[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / shift-eflags.ll
blob6eddf50ce5c9d5af22f8fc06db6020d57acc7748
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s
4 ; PR33879 - use shift eflags result when it won't cause stalls
6 ; ashr by constant - use sarl eflags result
7 define i32 @ashr_const(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
8 ; CHECK-LABEL: ashr_const:
9 ; CHECK:       # %bb.0:
10 ; CHECK-NEXT:    movl %edx, %eax
11 ; CHECK-NEXT:    sarl $14, %edi
12 ; CHECK-NEXT:    cmovnel %ecx, %eax
13 ; CHECK-NEXT:    retq
14   %s = ashr i32 %a0, 14
15   %c = icmp eq i32 %s, 0
16   %r = select i1 %c, i32 %a2, i32 %a3
17   ret i32 %r
20 ; lshr by constant - simplify to test
21 define i32 @lshr_const(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
22 ; CHECK-LABEL: lshr_const:
23 ; CHECK:       # %bb.0:
24 ; CHECK-NEXT:    movl %edx, %eax
25 ; CHECK-NEXT:    testl $-16384, %edi # imm = 0xC000
26 ; CHECK-NEXT:    cmovnel %ecx, %eax
27 ; CHECK-NEXT:    retq
28   %s = lshr i32 %a0, 14
29   %c = icmp eq i32 %s, 0
30   %r = select i1 %c, i32 %a2, i32 %a3
31   ret i32 %r
34 ; shl by constant - simplify to test
35 define i32 @shl_const(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
36 ; CHECK-LABEL: shl_const:
37 ; CHECK:       # %bb.0:
38 ; CHECK-NEXT:    movl %edx, %eax
39 ; CHECK-NEXT:    testl $262143, %edi # imm = 0x3FFFF
40 ; CHECK-NEXT:    cmovnel %ecx, %eax
41 ; CHECK-NEXT:    retq
42   %s = shl i32 %a0, 14
43   %c = icmp eq i32 %s, 0
44   %r = select i1 %c, i32 %a2, i32 %a3
45   ret i32 %r
48 ; ashr by constant and using shift result - use sarl eflags result
49 define i32 @ashr_const_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
50 ; CHECK-LABEL: ashr_const_self_select:
51 ; CHECK:       # %bb.0:
52 ; CHECK-NEXT:    movl %edi, %eax
53 ; CHECK-NEXT:    sarl $14, %eax
54 ; CHECK-NEXT:    cmovnel %edx, %eax
55 ; CHECK-NEXT:    retq
56   %s = ashr i32 %a0, 14
57   %c = icmp eq i32 %s, 0
58   %r = select i1 %c, i32 %s, i32 %a2
59   ret i32 %r
62 ; lshr by constant and using shift result - use shrl eflags result
63 define i32 @lshr_const_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
64 ; CHECK-LABEL: lshr_const_self_select:
65 ; CHECK:       # %bb.0:
66 ; CHECK-NEXT:    movl %edi, %eax
67 ; CHECK-NEXT:    shrl $14, %eax
68 ; CHECK-NEXT:    cmovnel %edx, %eax
69 ; CHECK-NEXT:    retq
70   %s = lshr i32 %a0, 14
71   %c = icmp eq i32 %s, 0
72   %r = select i1 %c, i32 %s, i32 %a2
73   ret i32 %r
76 ; lshr by constant and using result - use shll eflags result
77 define i32 @shl_const_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
78 ; CHECK-LABEL: shl_const_self_select:
79 ; CHECK:       # %bb.0:
80 ; CHECK-NEXT:    movl %edi, %eax
81 ; CHECK-NEXT:    shll $14, %eax
82 ; CHECK-NEXT:    cmovnel %edx, %eax
83 ; CHECK-NEXT:    retq
84   %s = shl i32 %a0, 14
85   %c = icmp eq i32 %s, 0
86   %r = select i1 %c, i32 %s, i32 %a2
87   ret i32 %r
90 ; ashr by 1 - use sarl eflags result
91 define i32 @ashr_const1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
92 ; CHECK-LABEL: ashr_const1:
93 ; CHECK:       # %bb.0:
94 ; CHECK-NEXT:    movl %edx, %eax
95 ; CHECK-NEXT:    sarl %edi
96 ; CHECK-NEXT:    cmovnel %ecx, %eax
97 ; CHECK-NEXT:    retq
98   %s = ashr i32 %a0, 1
99   %c = icmp eq i32 %s, 0
100   %r = select i1 %c, i32 %a2, i32 %a3
101   ret i32 %r
104 ; lshr by 1 - simplify to test
105 define i32 @lshr_const1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
106 ; CHECK-LABEL: lshr_const1:
107 ; CHECK:       # %bb.0:
108 ; CHECK-NEXT:    movl %edx, %eax
109 ; CHECK-NEXT:    testl $-2, %edi
110 ; CHECK-NEXT:    cmovnel %ecx, %eax
111 ; CHECK-NEXT:    retq
112   %s = lshr i32 %a0, 1
113   %c = icmp eq i32 %s, 0
114   %r = select i1 %c, i32 %a2, i32 %a3
115   ret i32 %r
118 ; shl by 1 - simplify to test
119 define i32 @shl_const1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
120 ; CHECK-LABEL: shl_const1:
121 ; CHECK:       # %bb.0:
122 ; CHECK-NEXT:    movl %edx, %eax
123 ; CHECK-NEXT:    testl $2147483647, %edi # imm = 0x7FFFFFFF
124 ; CHECK-NEXT:    cmovnel %ecx, %eax
125 ; CHECK-NEXT:    retq
126   %s = shl i32 %a0, 1
127   %c = icmp eq i32 %s, 0
128   %r = select i1 %c, i32 %a2, i32 %a3
129   ret i32 %r
132 ; ashr by 1 and using shift result - use sarl eflags result
133 define i32 @ashr_const1_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
134 ; CHECK-LABEL: ashr_const1_self_select:
135 ; CHECK:       # %bb.0:
136 ; CHECK-NEXT:    movl %edi, %eax
137 ; CHECK-NEXT:    sarl %eax
138 ; CHECK-NEXT:    cmovnel %edx, %eax
139 ; CHECK-NEXT:    retq
140   %s = ashr i32 %a0, 1
141   %c = icmp eq i32 %s, 0
142   %r = select i1 %c, i32 %s, i32 %a2
143   ret i32 %r
146 ; lshr by 1 and using shift result - use shrl eflags result
147 define i32 @lshr_const1_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
148 ; CHECK-LABEL: lshr_const1_self_select:
149 ; CHECK:       # %bb.0:
150 ; CHECK-NEXT:    movl %edi, %eax
151 ; CHECK-NEXT:    shrl %eax
152 ; CHECK-NEXT:    cmovnel %edx, %eax
153 ; CHECK-NEXT:    retq
154   %s = lshr i32 %a0, 1
155   %c = icmp eq i32 %s, 0
156   %r = select i1 %c, i32 %s, i32 %a2
157   ret i32 %r
160 ; lshr by 1 and using result - use addl eflags result
161 define i32 @shl_const1_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
162 ; CHECK-LABEL: shl_const1_self_select:
163 ; CHECK:       # %bb.0:
164 ; CHECK-NEXT:    movl %edi, %eax
165 ; CHECK-NEXT:    addl %edi, %eax
166 ; CHECK-NEXT:    cmovnel %edx, %eax
167 ; CHECK-NEXT:    retq
168   %s = shl i32 %a0, 1
169   %c = icmp eq i32 %s, 0
170   %r = select i1 %c, i32 %s, i32 %a2
171   ret i32 %r
174 ; ashr by variable - use separate test
175 define i32 @ashr_var(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
176 ; CHECK-LABEL: ashr_var:
177 ; CHECK:       # %bb.0:
178 ; CHECK-NEXT:    movl %ecx, %eax
179 ; CHECK-NEXT:    movl %esi, %ecx
180 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
181 ; CHECK-NEXT:    sarl %cl, %edi
182 ; CHECK-NEXT:    testl %edi, %edi
183 ; CHECK-NEXT:    cmovel %edx, %eax
184 ; CHECK-NEXT:    retq
185   %s = ashr i32 %a0, %a1
186   %c = icmp eq i32 %s, 0
187   %r = select i1 %c, i32 %a2, i32 %a3
188   ret i32 %r
191 ; lshr by variable - use separate test
192 define i32 @lshr_var(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
193 ; CHECK-LABEL: lshr_var:
194 ; CHECK:       # %bb.0:
195 ; CHECK-NEXT:    movl %ecx, %eax
196 ; CHECK-NEXT:    movl %esi, %ecx
197 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
198 ; CHECK-NEXT:    shrl %cl, %edi
199 ; CHECK-NEXT:    testl %edi, %edi
200 ; CHECK-NEXT:    cmovel %edx, %eax
201 ; CHECK-NEXT:    retq
202   %s = lshr i32 %a0, %a1
203   %c = icmp eq i32 %s, 0
204   %r = select i1 %c, i32 %a2, i32 %a3
205   ret i32 %r
208 ; shl by variable - use separate test
209 define i32 @shl_var(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
210 ; CHECK-LABEL: shl_var:
211 ; CHECK:       # %bb.0:
212 ; CHECK-NEXT:    movl %ecx, %eax
213 ; CHECK-NEXT:    movl %esi, %ecx
214 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
215 ; CHECK-NEXT:    shll %cl, %edi
216 ; CHECK-NEXT:    testl %edi, %edi
217 ; CHECK-NEXT:    cmovel %edx, %eax
218 ; CHECK-NEXT:    retq
219   %s = shl i32 %a0, %a1
220   %c = icmp eq i32 %s, 0
221   %r = select i1 %c, i32 %a2, i32 %a3
222   ret i32 %r
225 ; ashr by variable and using result - use separate test
226 define i32 @ashr_var_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
227 ; CHECK-LABEL: ashr_var_self_select:
228 ; CHECK:       # %bb.0:
229 ; CHECK-NEXT:    movl %esi, %ecx
230 ; CHECK-NEXT:    movl %edi, %eax
231 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
232 ; CHECK-NEXT:    sarl %cl, %eax
233 ; CHECK-NEXT:    testl %eax, %eax
234 ; CHECK-NEXT:    cmovnel %edx, %eax
235 ; CHECK-NEXT:    retq
236   %s = ashr i32 %a0, %a1
237   %c = icmp eq i32 %s, 0
238   %r = select i1 %c, i32 %s, i32 %a2
239   ret i32 %r
242 ; lshr by variable and using result - use separate test
243 define i32 @lshr_var_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
244 ; CHECK-LABEL: lshr_var_self_select:
245 ; CHECK:       # %bb.0:
246 ; CHECK-NEXT:    movl %esi, %ecx
247 ; CHECK-NEXT:    movl %edi, %eax
248 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
249 ; CHECK-NEXT:    shrl %cl, %eax
250 ; CHECK-NEXT:    testl %eax, %eax
251 ; CHECK-NEXT:    cmovnel %edx, %eax
252 ; CHECK-NEXT:    retq
253   %s = lshr i32 %a0, %a1
254   %c = icmp eq i32 %s, 0
255   %r = select i1 %c, i32 %s, i32 %a2
256   ret i32 %r
259 ; shl by variable and using result - use separate test
260 define i32 @shl_var_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
261 ; CHECK-LABEL: shl_var_self_select:
262 ; CHECK:       # %bb.0:
263 ; CHECK-NEXT:    movl %esi, %ecx
264 ; CHECK-NEXT:    movl %edi, %eax
265 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
266 ; CHECK-NEXT:    shll %cl, %eax
267 ; CHECK-NEXT:    testl %eax, %eax
268 ; CHECK-NEXT:    cmovnel %edx, %eax
269 ; CHECK-NEXT:    retq
270   %s = shl i32 %a0, %a1
271   %c = icmp eq i32 %s, 0
272   %r = select i1 %c, i32 %s, i32 %a2
273   ret i32 %r
276 ; ashr by non-zero variable - use separate test
277 define i32 @ashr_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
278 ; CHECK-LABEL: ashr_var_amt_never_zero:
279 ; CHECK:       # %bb.0:
280 ; CHECK-NEXT:    movl %ecx, %eax
281 ; CHECK-NEXT:    movl %esi, %ecx
282 ; CHECK-NEXT:    orb $1, %cl
283 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
284 ; CHECK-NEXT:    sarl %cl, %edi
285 ; CHECK-NEXT:    testl %edi, %edi
286 ; CHECK-NEXT:    cmovel %edx, %eax
287 ; CHECK-NEXT:    retq
288   %a = or i32 %a1, 1
289   %s = ashr i32 %a0, %a
290   %c = icmp eq i32 %s, 0
291   %r = select i1 %c, i32 %a2, i32 %a3
292   ret i32 %r
295 ; lshr by non-zero variable - use separate test
296 define i32 @lshr_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
297 ; CHECK-LABEL: lshr_var_amt_never_zero:
298 ; CHECK:       # %bb.0:
299 ; CHECK-NEXT:    movl %ecx, %eax
300 ; CHECK-NEXT:    movl %esi, %ecx
301 ; CHECK-NEXT:    orb $1, %cl
302 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
303 ; CHECK-NEXT:    shrl %cl, %edi
304 ; CHECK-NEXT:    testl %edi, %edi
305 ; CHECK-NEXT:    cmovel %edx, %eax
306 ; CHECK-NEXT:    retq
307   %a = or i32 %a1, 1
308   %s = lshr i32 %a0, %a
309   %c = icmp eq i32 %s, 0
310   %r = select i1 %c, i32 %a2, i32 %a3
311   ret i32 %r
314 ; shl by non-zero variable - use separate test
315 define i32 @shl_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
316 ; CHECK-LABEL: shl_var_amt_never_zero:
317 ; CHECK:       # %bb.0:
318 ; CHECK-NEXT:    movl %ecx, %eax
319 ; CHECK-NEXT:    movl %esi, %ecx
320 ; CHECK-NEXT:    orb $1, %cl
321 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
322 ; CHECK-NEXT:    shll %cl, %edi
323 ; CHECK-NEXT:    testl %edi, %edi
324 ; CHECK-NEXT:    cmovel %edx, %eax
325 ; CHECK-NEXT:    retq
326   %a = or i32 %a1, 1
327   %s = shl i32 %a0, %a
328   %c = icmp eq i32 %s, 0
329   %r = select i1 %c, i32 %a2, i32 %a3
330   ret i32 %r
333 ; ashr by non-zero variable and using result - use separate test
334 define i32 @ashr_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
335 ; CHECK-LABEL: ashr_var_self_select_amt_never_zero:
336 ; CHECK:       # %bb.0:
337 ; CHECK-NEXT:    movl %esi, %ecx
338 ; CHECK-NEXT:    movl %edi, %eax
339 ; CHECK-NEXT:    orb $1, %cl
340 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
341 ; CHECK-NEXT:    shrl %cl, %eax
342 ; CHECK-NEXT:    testl %eax, %eax
343 ; CHECK-NEXT:    cmovnel %edx, %eax
344 ; CHECK-NEXT:    retq
345   %a = or i32 %a1, 1
346   %s = lshr i32 %a0, %a
347   %c = icmp eq i32 %s, 0
348   %r = select i1 %c, i32 %s, i32 %a2
349   ret i32 %r
352 ; lshr by non-zero variable and using result - use separate test
353 define i32 @lshr_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
354 ; CHECK-LABEL: lshr_var_self_select_amt_never_zero:
355 ; CHECK:       # %bb.0:
356 ; CHECK-NEXT:    movl %esi, %ecx
357 ; CHECK-NEXT:    movl %edi, %eax
358 ; CHECK-NEXT:    orb $1, %cl
359 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
360 ; CHECK-NEXT:    shrl %cl, %eax
361 ; CHECK-NEXT:    testl %eax, %eax
362 ; CHECK-NEXT:    cmovnel %edx, %eax
363 ; CHECK-NEXT:    retq
364   %a = or i32 %a1, 1
365   %s = lshr i32 %a0, %a
366   %c = icmp eq i32 %s, 0
367   %r = select i1 %c, i32 %s, i32 %a2
368   ret i32 %r
371 ; shl by non-zero variable and using result - use separate test
372 define i32 @shl_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
373 ; CHECK-LABEL: shl_var_self_select_amt_never_zero:
374 ; CHECK:       # %bb.0:
375 ; CHECK-NEXT:    movl %esi, %ecx
376 ; CHECK-NEXT:    movl %edi, %eax
377 ; CHECK-NEXT:    orb $1, %cl
378 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
379 ; CHECK-NEXT:    shrl %cl, %eax
380 ; CHECK-NEXT:    testl %eax, %eax
381 ; CHECK-NEXT:    cmovnel %edx, %eax
382 ; CHECK-NEXT:    retq
383   %a = or i32 %a1, 1
384   %s = lshr i32 %a0, %a
385   %c = icmp eq i32 %s, 0
386   %r = select i1 %c, i32 %s, i32 %a2
387   ret i32 %r