[RISCV][VLOPT] Add vector narrowing integer right shift instructions to isSupportedIn...
[llvm-project.git] / llvm / test / CodeGen / AArch64 / logic-shift.ll
blob31047954401cf5e8a9d2ad26f1f41b5f1844f076
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
4 define i8 @or_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) {
5 ; CHECK-LABEL: or_lshr_commute0:
6 ; CHECK:       // %bb.0:
7 ; CHECK-NEXT:    orr w8, w0, w1
8 ; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
9 ; CHECK-NEXT:    and w8, w8, #0xff
10 ; CHECK-NEXT:    lsr w8, w8, w2
11 ; CHECK-NEXT:    orr w0, w8, w3
12 ; CHECK-NEXT:    ret
13   %sh1 = lshr i8 %x0, %y
14   %sh2 = lshr i8 %x1, %y
15   %logic = or i8 %sh1, %z
16   %r = or i8 %logic, %sh2
17   ret i8 %r
20 define i32 @or_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) {
21 ; CHECK-LABEL: or_lshr_commute1:
22 ; CHECK:       // %bb.0:
23 ; CHECK-NEXT:    orr w8, w0, w1
24 ; CHECK-NEXT:    lsr w8, w8, w2
25 ; CHECK-NEXT:    orr w0, w8, w3
26 ; CHECK-NEXT:    ret
27   %sh1 = lshr i32 %x0, %y
28   %sh2 = lshr i32 %x1, %y
29   %logic = or i32 %z, %sh1
30   %r = or i32 %logic, %sh2
31   ret i32 %r
34 define <8 x i16> @or_lshr_commute2(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {
35 ; CHECK-LABEL: or_lshr_commute2:
36 ; CHECK:       // %bb.0:
37 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
38 ; CHECK-NEXT:    neg v1.8h, v2.8h
39 ; CHECK-NEXT:    ushl v0.8h, v0.8h, v1.8h
40 ; CHECK-NEXT:    orr v0.16b, v0.16b, v3.16b
41 ; CHECK-NEXT:    ret
42   %sh1 = lshr <8 x i16> %x0, %y
43   %sh2 = lshr <8 x i16> %x1, %y
44   %logic = or <8 x i16> %sh1, %z
45   %r = or <8 x i16> %sh2, %logic
46   ret <8 x i16> %r
49 define <2 x i64> @or_lshr_commute3(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {
50 ; CHECK-LABEL: or_lshr_commute3:
51 ; CHECK:       // %bb.0:
52 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
53 ; CHECK-NEXT:    neg v1.2d, v2.2d
54 ; CHECK-NEXT:    ushl v0.2d, v0.2d, v1.2d
55 ; CHECK-NEXT:    orr v0.16b, v0.16b, v3.16b
56 ; CHECK-NEXT:    ret
57   %sh1 = lshr <2 x i64> %x0, %y
58   %sh2 = lshr <2 x i64> %x1, %y
59   %logic = or <2 x i64> %z, %sh1
60   %r = or <2 x i64> %sh2, %logic
61   ret <2 x i64> %r
64 define i16 @or_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) {
65 ; CHECK-LABEL: or_ashr_commute0:
66 ; CHECK:       // %bb.0:
67 ; CHECK-NEXT:    orr w8, w0, w1
68 ; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
69 ; CHECK-NEXT:    sxth w8, w8
70 ; CHECK-NEXT:    asr w8, w8, w2
71 ; CHECK-NEXT:    orr w0, w8, w3
72 ; CHECK-NEXT:    ret
73   %sh1 = ashr i16 %x0, %y
74   %sh2 = ashr i16 %x1, %y
75   %logic = or i16 %sh1, %z
76   %r = or i16 %logic, %sh2
77   ret i16 %r
80 define i64 @or_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) {
81 ; CHECK-LABEL: or_ashr_commute1:
82 ; CHECK:       // %bb.0:
83 ; CHECK-NEXT:    orr x8, x0, x1
84 ; CHECK-NEXT:    asr x8, x8, x2
85 ; CHECK-NEXT:    orr x0, x8, x3
86 ; CHECK-NEXT:    ret
87   %sh1 = ashr i64 %x0, %y
88   %sh2 = ashr i64 %x1, %y
89   %logic = or i64 %z, %sh1
90   %r = or i64 %logic, %sh2
91   ret i64 %r
94 define <4 x i32> @or_ashr_commute2(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y, <4 x i32> %z) {
95 ; CHECK-LABEL: or_ashr_commute2:
96 ; CHECK:       // %bb.0:
97 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
98 ; CHECK-NEXT:    neg v1.4s, v2.4s
99 ; CHECK-NEXT:    sshl v0.4s, v0.4s, v1.4s
100 ; CHECK-NEXT:    orr v0.16b, v0.16b, v3.16b
101 ; CHECK-NEXT:    ret
102   %sh1 = ashr <4 x i32> %x0, %y
103   %sh2 = ashr <4 x i32> %x1, %y
104   %logic = or <4 x i32> %sh1, %z
105   %r = or <4 x i32> %sh2, %logic
106   ret <4 x i32> %r
109 define <16 x i8> @or_ashr_commute3(<16 x i8> %x0, <16 x i8> %x1, <16 x i8> %y, <16 x i8> %z) {
110 ; CHECK-LABEL: or_ashr_commute3:
111 ; CHECK:       // %bb.0:
112 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
113 ; CHECK-NEXT:    neg v1.16b, v2.16b
114 ; CHECK-NEXT:    sshl v0.16b, v0.16b, v1.16b
115 ; CHECK-NEXT:    orr v0.16b, v0.16b, v3.16b
116 ; CHECK-NEXT:    ret
117   %sh1 = ashr <16 x i8> %x0, %y
118   %sh2 = ashr <16 x i8> %x1, %y
119   %logic = or <16 x i8> %z, %sh1
120   %r = or <16 x i8> %sh2, %logic
121   ret <16 x i8> %r
124 define i32 @or_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) {
125 ; CHECK-LABEL: or_shl_commute0:
126 ; CHECK:       // %bb.0:
127 ; CHECK-NEXT:    orr w8, w0, w1
128 ; CHECK-NEXT:    lsl w8, w8, w2
129 ; CHECK-NEXT:    orr w0, w8, w3
130 ; CHECK-NEXT:    ret
131   %sh1 = shl i32 %x0, %y
132   %sh2 = shl i32 %x1, %y
133   %logic = or i32 %sh1, %z
134   %r = or i32 %logic, %sh2
135   ret i32 %r
138 define i8 @or_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) {
139 ; CHECK-LABEL: or_shl_commute1:
140 ; CHECK:       // %bb.0:
141 ; CHECK-NEXT:    orr w8, w0, w1
142 ; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
143 ; CHECK-NEXT:    lsl w8, w8, w2
144 ; CHECK-NEXT:    orr w0, w8, w3
145 ; CHECK-NEXT:    ret
146   %sh1 = shl i8 %x0, %y
147   %sh2 = shl i8 %x1, %y
148   %logic = or i8 %z, %sh1
149   %r = or i8 %logic, %sh2
150   ret i8 %r
153 define <2 x i64> @or_shl_commute2(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {
154 ; CHECK-LABEL: or_shl_commute2:
155 ; CHECK:       // %bb.0:
156 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
157 ; CHECK-NEXT:    ushl v0.2d, v0.2d, v2.2d
158 ; CHECK-NEXT:    orr v0.16b, v0.16b, v3.16b
159 ; CHECK-NEXT:    ret
160   %sh1 = shl <2 x i64> %x0, %y
161   %sh2 = shl <2 x i64> %x1, %y
162   %logic = or <2 x i64> %sh1, %z
163   %r = or <2 x i64> %sh2, %logic
164   ret <2 x i64> %r
167 define <8 x i16> @or_shl_commute3(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {
168 ; CHECK-LABEL: or_shl_commute3:
169 ; CHECK:       // %bb.0:
170 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
171 ; CHECK-NEXT:    ushl v0.8h, v0.8h, v2.8h
172 ; CHECK-NEXT:    orr v0.16b, v0.16b, v3.16b
173 ; CHECK-NEXT:    ret
174   %sh1 = shl <8 x i16> %x0, %y
175   %sh2 = shl <8 x i16> %x1, %y
176   %logic = or <8 x i16> %z, %sh1
177   %r = or <8 x i16> %sh2, %logic
178   ret <8 x i16> %r
181 ; negative test - mismatched shift opcodes
183 define i64 @or_mix_shr(i64 %x0, i64 %x1, i64 %y, i64 %z) {
184 ; CHECK-LABEL: or_mix_shr:
185 ; CHECK:       // %bb.0:
186 ; CHECK-NEXT:    asr x8, x0, x2
187 ; CHECK-NEXT:    lsr x9, x1, x2
188 ; CHECK-NEXT:    orr x8, x8, x3
189 ; CHECK-NEXT:    orr x0, x8, x9
190 ; CHECK-NEXT:    ret
191   %sh1 = ashr i64 %x0, %y
192   %sh2 = lshr i64 %x1, %y
193   %logic = or i64 %sh1, %z
194   %r = or i64 %logic, %sh2
195   ret i64 %r
198 ; negative test - mixed shift amounts
200 define i64 @or_lshr_mix_shift_amount(i64 %x0, i64 %x1, i64 %y, i64 %z, i64 %w) {
201 ; CHECK-LABEL: or_lshr_mix_shift_amount:
202 ; CHECK:       // %bb.0:
203 ; CHECK-NEXT:    lsr x8, x0, x2
204 ; CHECK-NEXT:    lsr x9, x1, x4
205 ; CHECK-NEXT:    orr x8, x8, x3
206 ; CHECK-NEXT:    orr x0, x8, x9
207 ; CHECK-NEXT:    ret
208   %sh1 = lshr i64 %x0, %y
209   %sh2 = lshr i64 %x1, %w
210   %logic = or i64 %sh1, %z
211   %r = or i64 %logic, %sh2
212   ret i64 %r
215 ; negative test - mismatched logic opcodes
217 define i64 @mix_logic_lshr(i64 %x0, i64 %x1, i64 %y, i64 %z) {
218 ; CHECK-LABEL: mix_logic_lshr:
219 ; CHECK:       // %bb.0:
220 ; CHECK-NEXT:    lsr x8, x0, x2
221 ; CHECK-NEXT:    lsr x9, x1, x2
222 ; CHECK-NEXT:    eor x8, x8, x3
223 ; CHECK-NEXT:    orr x0, x8, x9
224 ; CHECK-NEXT:    ret
225   %sh1 = lshr i64 %x0, %y
226   %sh2 = lshr i64 %x1, %y
227   %logic = xor i64 %sh1, %z
228   %r = or i64 %logic, %sh2
229   ret i64 %r
232 define i8 @xor_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) {
233 ; CHECK-LABEL: xor_lshr_commute0:
234 ; CHECK:       // %bb.0:
235 ; CHECK-NEXT:    eor w8, w0, w1
236 ; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
237 ; CHECK-NEXT:    and w8, w8, #0xff
238 ; CHECK-NEXT:    lsr w8, w8, w2
239 ; CHECK-NEXT:    eor w0, w8, w3
240 ; CHECK-NEXT:    ret
241   %sh1 = lshr i8 %x0, %y
242   %sh2 = lshr i8 %x1, %y
243   %logic = xor i8 %sh1, %z
244   %r = xor i8 %logic, %sh2
245   ret i8 %r
248 define i32 @xor_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) {
249 ; CHECK-LABEL: xor_lshr_commute1:
250 ; CHECK:       // %bb.0:
251 ; CHECK-NEXT:    eor w8, w0, w1
252 ; CHECK-NEXT:    lsr w8, w8, w2
253 ; CHECK-NEXT:    eor w0, w8, w3
254 ; CHECK-NEXT:    ret
255   %sh1 = lshr i32 %x0, %y
256   %sh2 = lshr i32 %x1, %y
257   %logic = xor i32 %z, %sh1
258   %r = xor i32 %logic, %sh2
259   ret i32 %r
262 define <8 x i16> @xor_lshr_commute2(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {
263 ; CHECK-LABEL: xor_lshr_commute2:
264 ; CHECK:       // %bb.0:
265 ; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b
266 ; CHECK-NEXT:    neg v1.8h, v2.8h
267 ; CHECK-NEXT:    ushl v0.8h, v0.8h, v1.8h
268 ; CHECK-NEXT:    eor v0.16b, v0.16b, v3.16b
269 ; CHECK-NEXT:    ret
270   %sh1 = lshr <8 x i16> %x0, %y
271   %sh2 = lshr <8 x i16> %x1, %y
272   %logic = xor <8 x i16> %sh1, %z
273   %r = xor <8 x i16> %sh2, %logic
274   ret <8 x i16> %r
277 define <2 x i64> @xor_lshr_commute3(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {
278 ; CHECK-LABEL: xor_lshr_commute3:
279 ; CHECK:       // %bb.0:
280 ; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b
281 ; CHECK-NEXT:    neg v1.2d, v2.2d
282 ; CHECK-NEXT:    ushl v0.2d, v0.2d, v1.2d
283 ; CHECK-NEXT:    eor v0.16b, v0.16b, v3.16b
284 ; CHECK-NEXT:    ret
285   %sh1 = lshr <2 x i64> %x0, %y
286   %sh2 = lshr <2 x i64> %x1, %y
287   %logic = xor <2 x i64> %z, %sh1
288   %r = xor <2 x i64> %sh2, %logic
289   ret <2 x i64> %r
292 define i16 @xor_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) {
293 ; CHECK-LABEL: xor_ashr_commute0:
294 ; CHECK:       // %bb.0:
295 ; CHECK-NEXT:    eor w8, w0, w1
296 ; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
297 ; CHECK-NEXT:    sxth w8, w8
298 ; CHECK-NEXT:    asr w8, w8, w2
299 ; CHECK-NEXT:    eor w0, w8, w3
300 ; CHECK-NEXT:    ret
301   %sh1 = ashr i16 %x0, %y
302   %sh2 = ashr i16 %x1, %y
303   %logic = xor i16 %sh1, %z
304   %r = xor i16 %logic, %sh2
305   ret i16 %r
308 define i64 @xor_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) {
309 ; CHECK-LABEL: xor_ashr_commute1:
310 ; CHECK:       // %bb.0:
311 ; CHECK-NEXT:    eor x8, x0, x1
312 ; CHECK-NEXT:    asr x8, x8, x2
313 ; CHECK-NEXT:    eor x0, x8, x3
314 ; CHECK-NEXT:    ret
315   %sh1 = ashr i64 %x0, %y
316   %sh2 = ashr i64 %x1, %y
317   %logic = xor i64 %z, %sh1
318   %r = xor i64 %logic, %sh2
319   ret i64 %r
322 define <4 x i32> @xor_ashr_commute2(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y, <4 x i32> %z) {
323 ; CHECK-LABEL: xor_ashr_commute2:
324 ; CHECK:       // %bb.0:
325 ; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b
326 ; CHECK-NEXT:    neg v1.4s, v2.4s
327 ; CHECK-NEXT:    sshl v0.4s, v0.4s, v1.4s
328 ; CHECK-NEXT:    eor v0.16b, v0.16b, v3.16b
329 ; CHECK-NEXT:    ret
330   %sh1 = ashr <4 x i32> %x0, %y
331   %sh2 = ashr <4 x i32> %x1, %y
332   %logic = xor <4 x i32> %sh1, %z
333   %r = xor <4 x i32> %sh2, %logic
334   ret <4 x i32> %r
337 define <16 x i8> @xor_ashr_commute3(<16 x i8> %x0, <16 x i8> %x1, <16 x i8> %y, <16 x i8> %z) {
338 ; CHECK-LABEL: xor_ashr_commute3:
339 ; CHECK:       // %bb.0:
340 ; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b
341 ; CHECK-NEXT:    neg v1.16b, v2.16b
342 ; CHECK-NEXT:    sshl v0.16b, v0.16b, v1.16b
343 ; CHECK-NEXT:    eor v0.16b, v0.16b, v3.16b
344 ; CHECK-NEXT:    ret
345   %sh1 = ashr <16 x i8> %x0, %y
346   %sh2 = ashr <16 x i8> %x1, %y
347   %logic = xor <16 x i8> %z, %sh1
348   %r = xor <16 x i8> %sh2, %logic
349   ret <16 x i8> %r
352 define i32 @xor_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) {
353 ; CHECK-LABEL: xor_shl_commute0:
354 ; CHECK:       // %bb.0:
355 ; CHECK-NEXT:    eor w8, w0, w1
356 ; CHECK-NEXT:    lsl w8, w8, w2
357 ; CHECK-NEXT:    eor w0, w8, w3
358 ; CHECK-NEXT:    ret
359   %sh1 = shl i32 %x0, %y
360   %sh2 = shl i32 %x1, %y
361   %logic = xor i32 %sh1, %z
362   %r = xor i32 %logic, %sh2
363   ret i32 %r
366 define i8 @xor_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) {
367 ; CHECK-LABEL: xor_shl_commute1:
368 ; CHECK:       // %bb.0:
369 ; CHECK-NEXT:    eor w8, w0, w1
370 ; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
371 ; CHECK-NEXT:    lsl w8, w8, w2
372 ; CHECK-NEXT:    eor w0, w8, w3
373 ; CHECK-NEXT:    ret
374   %sh1 = shl i8 %x0, %y
375   %sh2 = shl i8 %x1, %y
376   %logic = xor i8 %z, %sh1
377   %r = xor i8 %logic, %sh2
378   ret i8 %r
381 define <2 x i64> @xor_shl_commute2(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {
382 ; CHECK-LABEL: xor_shl_commute2:
383 ; CHECK:       // %bb.0:
384 ; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b
385 ; CHECK-NEXT:    ushl v0.2d, v0.2d, v2.2d
386 ; CHECK-NEXT:    eor v0.16b, v0.16b, v3.16b
387 ; CHECK-NEXT:    ret
388   %sh1 = shl <2 x i64> %x0, %y
389   %sh2 = shl <2 x i64> %x1, %y
390   %logic = xor <2 x i64> %sh1, %z
391   %r = xor <2 x i64> %sh2, %logic
392   ret <2 x i64> %r
395 define <8 x i16> @xor_shl_commute3(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {
396 ; CHECK-LABEL: xor_shl_commute3:
397 ; CHECK:       // %bb.0:
398 ; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b
399 ; CHECK-NEXT:    ushl v0.8h, v0.8h, v2.8h
400 ; CHECK-NEXT:    eor v0.16b, v0.16b, v3.16b
401 ; CHECK-NEXT:    ret
402   %sh1 = shl <8 x i16> %x0, %y
403   %sh2 = shl <8 x i16> %x1, %y
404   %logic = xor <8 x i16> %z, %sh1
405   %r = xor <8 x i16> %sh2, %logic
406   ret <8 x i16> %r
409 ; negative test - mismatched shift opcodes
411 define i64 @xor_mix_shr(i64 %x0, i64 %x1, i64 %y, i64 %z) {
412 ; CHECK-LABEL: xor_mix_shr:
413 ; CHECK:       // %bb.0:
414 ; CHECK-NEXT:    asr x8, x0, x2
415 ; CHECK-NEXT:    lsr x9, x1, x2
416 ; CHECK-NEXT:    eor x8, x8, x3
417 ; CHECK-NEXT:    eor x0, x8, x9
418 ; CHECK-NEXT:    ret
419   %sh1 = ashr i64 %x0, %y
420   %sh2 = lshr i64 %x1, %y
421   %logic = xor i64 %sh1, %z
422   %r = xor i64 %logic, %sh2
423   ret i64 %r
426 ; negative test - mismatched shift amounts
428 define i64 @xor_lshr_mix_shift_amount(i64 %x0, i64 %x1, i64 %y, i64 %z, i64 %w) {
429 ; CHECK-LABEL: xor_lshr_mix_shift_amount:
430 ; CHECK:       // %bb.0:
431 ; CHECK-NEXT:    lsr x8, x0, x2
432 ; CHECK-NEXT:    lsr x9, x1, x4
433 ; CHECK-NEXT:    eor x8, x8, x3
434 ; CHECK-NEXT:    eor x0, x8, x9
435 ; CHECK-NEXT:    ret
436   %sh1 = lshr i64 %x0, %y
437   %sh2 = lshr i64 %x1, %w
438   %logic = xor i64 %sh1, %z
439   %r = xor i64 %logic, %sh2
440   ret i64 %r
443 ; negative test - mismatched logic opcodes
445 define i64 @mix_logic_ashr(i64 %x0, i64 %x1, i64 %y, i64 %z) {
446 ; CHECK-LABEL: mix_logic_ashr:
447 ; CHECK:       // %bb.0:
448 ; CHECK-NEXT:    asr x8, x0, x2
449 ; CHECK-NEXT:    asr x9, x1, x2
450 ; CHECK-NEXT:    orr x8, x8, x3
451 ; CHECK-NEXT:    eor x0, x8, x9
452 ; CHECK-NEXT:    ret
453   %sh1 = ashr i64 %x0, %y
454   %sh2 = ashr i64 %x1, %y
455   %logic = or i64 %sh1, %z
456   %r = xor i64 %logic, %sh2
457   ret i64 %r
460 define i8 @and_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) {
461 ; CHECK-LABEL: and_lshr_commute0:
462 ; CHECK:       // %bb.0:
463 ; CHECK-NEXT:    and w8, w0, w1
464 ; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
465 ; CHECK-NEXT:    and w8, w8, #0xff
466 ; CHECK-NEXT:    lsr w8, w8, w2
467 ; CHECK-NEXT:    and w0, w8, w3
468 ; CHECK-NEXT:    ret
469   %sh1 = lshr i8 %x0, %y
470   %sh2 = lshr i8 %x1, %y
471   %logic = and i8 %sh1, %z
472   %r = and i8 %logic, %sh2
473   ret i8 %r
476 define i32 @and_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) {
477 ; CHECK-LABEL: and_lshr_commute1:
478 ; CHECK:       // %bb.0:
479 ; CHECK-NEXT:    and w8, w0, w1
480 ; CHECK-NEXT:    lsr w8, w8, w2
481 ; CHECK-NEXT:    and w0, w8, w3
482 ; CHECK-NEXT:    ret
483   %sh1 = lshr i32 %x0, %y
484   %sh2 = lshr i32 %x1, %y
485   %logic = and i32 %z, %sh1
486   %r = and i32 %logic, %sh2
487   ret i32 %r
490 define <8 x i16> @and_lshr_commute2(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {
491 ; CHECK-LABEL: and_lshr_commute2:
492 ; CHECK:       // %bb.0:
493 ; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
494 ; CHECK-NEXT:    neg v1.8h, v2.8h
495 ; CHECK-NEXT:    ushl v0.8h, v0.8h, v1.8h
496 ; CHECK-NEXT:    and v0.16b, v0.16b, v3.16b
497 ; CHECK-NEXT:    ret
498   %sh1 = lshr <8 x i16> %x0, %y
499   %sh2 = lshr <8 x i16> %x1, %y
500   %logic = and <8 x i16> %sh1, %z
501   %r = and <8 x i16> %sh2, %logic
502   ret <8 x i16> %r
505 define <2 x i64> @and_lshr_commute3(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {
506 ; CHECK-LABEL: and_lshr_commute3:
507 ; CHECK:       // %bb.0:
508 ; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
509 ; CHECK-NEXT:    neg v1.2d, v2.2d
510 ; CHECK-NEXT:    ushl v0.2d, v0.2d, v1.2d
511 ; CHECK-NEXT:    and v0.16b, v0.16b, v3.16b
512 ; CHECK-NEXT:    ret
513   %sh1 = lshr <2 x i64> %x0, %y
514   %sh2 = lshr <2 x i64> %x1, %y
515   %logic = and <2 x i64> %z, %sh1
516   %r = and <2 x i64> %sh2, %logic
517   ret <2 x i64> %r
520 define i16 @and_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) {
521 ; CHECK-LABEL: and_ashr_commute0:
522 ; CHECK:       // %bb.0:
523 ; CHECK-NEXT:    and w8, w0, w1
524 ; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
525 ; CHECK-NEXT:    sxth w8, w8
526 ; CHECK-NEXT:    asr w8, w8, w2
527 ; CHECK-NEXT:    and w0, w8, w3
528 ; CHECK-NEXT:    ret
529   %sh1 = ashr i16 %x0, %y
530   %sh2 = ashr i16 %x1, %y
531   %logic = and i16 %sh1, %z
532   %r = and i16 %logic, %sh2
533   ret i16 %r
536 define i64 @and_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) {
537 ; CHECK-LABEL: and_ashr_commute1:
538 ; CHECK:       // %bb.0:
539 ; CHECK-NEXT:    and x8, x0, x1
540 ; CHECK-NEXT:    asr x8, x8, x2
541 ; CHECK-NEXT:    and x0, x8, x3
542 ; CHECK-NEXT:    ret
543   %sh1 = ashr i64 %x0, %y
544   %sh2 = ashr i64 %x1, %y
545   %logic = and i64 %z, %sh1
546   %r = and i64 %logic, %sh2
547   ret i64 %r
550 define <4 x i32> @and_ashr_commute2(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y, <4 x i32> %z) {
551 ; CHECK-LABEL: and_ashr_commute2:
552 ; CHECK:       // %bb.0:
553 ; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
554 ; CHECK-NEXT:    neg v1.4s, v2.4s
555 ; CHECK-NEXT:    sshl v0.4s, v0.4s, v1.4s
556 ; CHECK-NEXT:    and v0.16b, v0.16b, v3.16b
557 ; CHECK-NEXT:    ret
558   %sh1 = ashr <4 x i32> %x0, %y
559   %sh2 = ashr <4 x i32> %x1, %y
560   %logic = and <4 x i32> %sh1, %z
561   %r = and <4 x i32> %sh2, %logic
562   ret <4 x i32> %r
565 define <16 x i8> @and_ashr_commute3(<16 x i8> %x0, <16 x i8> %x1, <16 x i8> %y, <16 x i8> %z) {
566 ; CHECK-LABEL: and_ashr_commute3:
567 ; CHECK:       // %bb.0:
568 ; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
569 ; CHECK-NEXT:    neg v1.16b, v2.16b
570 ; CHECK-NEXT:    sshl v0.16b, v0.16b, v1.16b
571 ; CHECK-NEXT:    and v0.16b, v0.16b, v3.16b
572 ; CHECK-NEXT:    ret
573   %sh1 = ashr <16 x i8> %x0, %y
574   %sh2 = ashr <16 x i8> %x1, %y
575   %logic = and <16 x i8> %z, %sh1
576   %r = and <16 x i8> %sh2, %logic
577   ret <16 x i8> %r
580 define i32 @and_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) {
581 ; CHECK-LABEL: and_shl_commute0:
582 ; CHECK:       // %bb.0:
583 ; CHECK-NEXT:    and w8, w0, w1
584 ; CHECK-NEXT:    lsl w8, w8, w2
585 ; CHECK-NEXT:    and w0, w8, w3
586 ; CHECK-NEXT:    ret
587   %sh1 = shl i32 %x0, %y
588   %sh2 = shl i32 %x1, %y
589   %logic = and i32 %sh1, %z
590   %r = and i32 %logic, %sh2
591   ret i32 %r
594 define i8 @and_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) {
595 ; CHECK-LABEL: and_shl_commute1:
596 ; CHECK:       // %bb.0:
597 ; CHECK-NEXT:    and w8, w0, w1
598 ; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
599 ; CHECK-NEXT:    lsl w8, w8, w2
600 ; CHECK-NEXT:    and w0, w8, w3
601 ; CHECK-NEXT:    ret
602   %sh1 = shl i8 %x0, %y
603   %sh2 = shl i8 %x1, %y
604   %logic = and i8 %z, %sh1
605   %r = and i8 %logic, %sh2
606   ret i8 %r
609 define <2 x i64> @and_shl_commute2(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {
610 ; CHECK-LABEL: and_shl_commute2:
611 ; CHECK:       // %bb.0:
612 ; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
613 ; CHECK-NEXT:    ushl v0.2d, v0.2d, v2.2d
614 ; CHECK-NEXT:    and v0.16b, v0.16b, v3.16b
615 ; CHECK-NEXT:    ret
616   %sh1 = shl <2 x i64> %x0, %y
617   %sh2 = shl <2 x i64> %x1, %y
618   %logic = and <2 x i64> %sh1, %z
619   %r = and <2 x i64> %sh2, %logic
620   ret <2 x i64> %r
623 define <8 x i16> @and_shl_commute3(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {
624 ; CHECK-LABEL: and_shl_commute3:
625 ; CHECK:       // %bb.0:
626 ; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
627 ; CHECK-NEXT:    ushl v0.8h, v0.8h, v2.8h
628 ; CHECK-NEXT:    and v0.16b, v0.16b, v3.16b
629 ; CHECK-NEXT:    ret
630   %sh1 = shl <8 x i16> %x0, %y
631   %sh2 = shl <8 x i16> %x1, %y
632   %logic = and <8 x i16> %z, %sh1
633   %r = and <8 x i16> %sh2, %logic
634   ret <8 x i16> %r
637 ; negative test - mismatched shift opcodes
639 define i64 @and_mix_shr(i64 %x0, i64 %x1, i64 %y, i64 %z) {
640 ; CHECK-LABEL: and_mix_shr:
641 ; CHECK:       // %bb.0:
642 ; CHECK-NEXT:    lsr x8, x0, x2
643 ; CHECK-NEXT:    asr x9, x1, x2
644 ; CHECK-NEXT:    and x8, x8, x3
645 ; CHECK-NEXT:    and x0, x8, x9
646 ; CHECK-NEXT:    ret
647   %sh1 = lshr i64 %x0, %y
648   %sh2 = ashr i64 %x1, %y
649   %logic = and i64 %sh1, %z
650   %r = and i64 %logic, %sh2
651   ret i64 %r
654 ; negative test - mismatched shift amounts
656 define i64 @and_lshr_mix_shift_amount(i64 %x0, i64 %x1, i64 %y, i64 %z, i64 %w) {
657 ; CHECK-LABEL: and_lshr_mix_shift_amount:
658 ; CHECK:       // %bb.0:
659 ; CHECK-NEXT:    lsr x8, x0, x2
660 ; CHECK-NEXT:    lsr x9, x1, x4
661 ; CHECK-NEXT:    and x8, x8, x3
662 ; CHECK-NEXT:    and x0, x8, x9
663 ; CHECK-NEXT:    ret
664   %sh1 = lshr i64 %x0, %y
665   %sh2 = lshr i64 %x1, %w
666   %logic = and i64 %sh1, %z
667   %r = and i64 %logic, %sh2
668   ret i64 %r
671 ; negative test - mismatched logic opcodes
673 define i64 @mix_logic_shl(i64 %x0, i64 %x1, i64 %y, i64 %z) {
674 ; CHECK-LABEL: mix_logic_shl:
675 ; CHECK:       // %bb.0:
676 ; CHECK-NEXT:    lsl x8, x0, x2
677 ; CHECK-NEXT:    lsl x9, x1, x2
678 ; CHECK-NEXT:    eor x8, x8, x3
679 ; CHECK-NEXT:    and x0, x8, x9
680 ; CHECK-NEXT:    ret
681   %sh1 = shl i64 %x0, %y
682   %sh2 = shl i64 %x1, %y
683   %logic = xor i64 %sh1, %z
684   %r = and i64 %logic, %sh2
685   ret i64 %r
688 ; (shl (X | Y), C1) | (srl X, C2) --> (rotl X, C1) | (shl Y, C1)
690 define i32 @or_fshl_commute0(i32 %x, i32 %y) {
691 ; CHECK-LABEL: or_fshl_commute0:
692 ; CHECK:       // %bb.0:
693 ; CHECK-NEXT:    orr w8, w0, w1
694 ; CHECK-NEXT:    extr w0, w8, w0, #27
695 ; CHECK-NEXT:    ret
696   %or1 = or i32 %x, %y
697   %sh1 = shl i32 %or1, 5
698   %sh2 = lshr i32 %x, 27
699   %r = or i32 %sh1, %sh2
700   ret i32 %r
703 define i64 @or_fshl_commute1(i64 %x, i64 %y) {
704 ; CHECK-LABEL: or_fshl_commute1:
705 ; CHECK:       // %bb.0:
706 ; CHECK-NEXT:    orr w8, w1, w0
707 ; CHECK-NEXT:    extr x0, x8, x0, #29
708 ; CHECK-NEXT:    ret
709   %or1 = or i64 %y, %x
710   %sh1 = shl i64 %or1, 35
711   %sh2 = lshr i64 %x, 29
712   %r = or i64 %sh1, %sh2
713   ret i64 %r
716 define i16 @or_fshl_commute2(i16 %x, i16 %y) {
717 ; CHECK-LABEL: or_fshl_commute2:
718 ; CHECK:       // %bb.0:
719 ; CHECK-NEXT:    orr w8, w0, w1
720 ; CHECK-NEXT:    lsl w8, w8, #2
721 ; CHECK-NEXT:    bfxil w8, w0, #14, #2
722 ; CHECK-NEXT:    mov w0, w8
723 ; CHECK-NEXT:    ret
724   %or1 = or i16 %x, %y
725   %sh1 = shl i16 %or1, 2
726   %sh2 = lshr i16 %x, 14
727   %r = or i16 %sh2, %sh1
728   ret i16 %r
731 define i8 @or_fshl_commute3(i8 %x, i8 %y) {
732 ; CHECK-LABEL: or_fshl_commute3:
733 ; CHECK:       // %bb.0:
734 ; CHECK-NEXT:    orr w8, w1, w0
735 ; CHECK-NEXT:    lsl w8, w8, #5
736 ; CHECK-NEXT:    bfxil w8, w0, #3, #5
737 ; CHECK-NEXT:    mov w0, w8
738 ; CHECK-NEXT:    ret
739   %or1 = or i8 %y, %x
740   %sh1 = shl i8 %or1, 5
741   %sh2 = lshr i8 %x, 3
742   %r = or i8 %sh2, %sh1
743   ret i8 %r
746 define i32 @or_fshl_wrong_shift(i32 %x, i32 %y) {
747 ; CHECK-LABEL: or_fshl_wrong_shift:
748 ; CHECK:       // %bb.0:
749 ; CHECK-NEXT:    orr w8, w0, w1
750 ; CHECK-NEXT:    lsl w8, w8, #20
751 ; CHECK-NEXT:    orr w0, w8, w0, lsr #11
752 ; CHECK-NEXT:    ret
753   %or1 = or i32 %x, %y
754   %sh1 = shl i32 %or1, 20
755   %sh2 = lshr i32 %x, 11
756   %r = or i32 %sh1, %sh2
757   ret i32 %r
760 ; (shl X, C1) | (srl (X | Y), C2) --> (rotl X, C1) | (srl Y, C2)
762 define i64 @or_fshr_commute0(i64 %x, i64 %y) {
763 ; CHECK-LABEL: or_fshr_commute0:
764 ; CHECK:       // %bb.0:
765 ; CHECK-NEXT:    orr x8, x0, x1
766 ; CHECK-NEXT:    extr x0, x0, x8, #24
767 ; CHECK-NEXT:    ret
768   %or1 = or i64 %x, %y
769   %sh1 = shl i64 %x, 40
770   %sh2 = lshr i64 %or1, 24
771   %r = or i64 %sh1, %sh2
772   ret i64 %r
775 define i32 @or_fshr_commute1(i32 %x, i32 %y) {
776 ; CHECK-LABEL: or_fshr_commute1:
777 ; CHECK:       // %bb.0:
778 ; CHECK-NEXT:    orr w8, w1, w0
779 ; CHECK-NEXT:    extr w0, w0, w8, #29
780 ; CHECK-NEXT:    ret
781   %or1 = or i32 %y, %x
782   %sh1 = shl i32 %x, 3
783   %sh2 = lshr i32 %or1, 29
784   %r = or i32 %sh1, %sh2
785   ret i32 %r
788 define i16 @or_fshr_commute2(i16 %x, i16 %y) {
789 ; CHECK-LABEL: or_fshr_commute2:
790 ; CHECK:       // %bb.0:
791 ; CHECK-NEXT:    lsl w8, w0, #9
792 ; CHECK-NEXT:    orr w9, w0, w1
793 ; CHECK-NEXT:    bfxil w8, w9, #7, #9
794 ; CHECK-NEXT:    mov w0, w8
795 ; CHECK-NEXT:    ret
796   %or1 = or i16 %x, %y
797   %sh1 = shl i16 %x, 9
798   %sh2 = lshr i16 %or1, 7
799   %r = or i16 %sh2, %sh1
800   ret i16 %r
803 define i8 @or_fshr_commute3(i8 %x, i8 %y) {
804 ; CHECK-LABEL: or_fshr_commute3:
805 ; CHECK:       // %bb.0:
806 ; CHECK-NEXT:    lsl w8, w0, #2
807 ; CHECK-NEXT:    orr w9, w1, w0
808 ; CHECK-NEXT:    bfxil w8, w9, #6, #2
809 ; CHECK-NEXT:    mov w0, w8
810 ; CHECK-NEXT:    ret
811   %or1 = or i8 %y, %x
812   %sh1 = shl i8 %x, 2
813   %sh2 = lshr i8 %or1, 6
814   %r = or i8 %sh2, %sh1
815   ret i8 %r
818 define i32 @or_fshr_wrong_shift(i32 %x, i32 %y) {
819 ; CHECK-LABEL: or_fshr_wrong_shift:
820 ; CHECK:       // %bb.0:
821 ; CHECK-NEXT:    orr w8, w0, w1
822 ; CHECK-NEXT:    lsr w8, w8, #26
823 ; CHECK-NEXT:    orr w0, w8, w0, lsl #7
824 ; CHECK-NEXT:    ret
825   %or1 = or i32 %x, %y
826   %sh1 = shl i32 %x, 7
827   %sh2 = lshr i32 %or1, 26
828   %r = or i32 %sh1, %sh2
829   ret i32 %r