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:
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
13 %sh1 = lshr i8 %x0, %y
14 %sh2 = lshr i8 %x1, %y
15 %logic = or i8 %sh1, %z
16 %r = or i8 %logic, %sh2
20 define i32 @or_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) {
21 ; CHECK-LABEL: or_lshr_commute1:
23 ; CHECK-NEXT: orr w8, w0, w1
24 ; CHECK-NEXT: lsr w8, w8, w2
25 ; CHECK-NEXT: orr w0, w8, w3
27 %sh1 = lshr i32 %x0, %y
28 %sh2 = lshr i32 %x1, %y
29 %logic = or i32 %z, %sh1
30 %r = or i32 %logic, %sh2
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:
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
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
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:
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
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
64 define i16 @or_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) {
65 ; CHECK-LABEL: or_ashr_commute0:
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
73 %sh1 = ashr i16 %x0, %y
74 %sh2 = ashr i16 %x1, %y
75 %logic = or i16 %sh1, %z
76 %r = or i16 %logic, %sh2
80 define i64 @or_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) {
81 ; CHECK-LABEL: or_ashr_commute1:
83 ; CHECK-NEXT: orr x8, x0, x1
84 ; CHECK-NEXT: asr x8, x8, x2
85 ; CHECK-NEXT: orr x0, x8, x3
87 %sh1 = ashr i64 %x0, %y
88 %sh2 = ashr i64 %x1, %y
89 %logic = or i64 %z, %sh1
90 %r = or i64 %logic, %sh2
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:
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
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
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:
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
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
124 define i32 @or_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) {
125 ; CHECK-LABEL: or_shl_commute0:
127 ; CHECK-NEXT: orr w8, w0, w1
128 ; CHECK-NEXT: lsl w8, w8, w2
129 ; CHECK-NEXT: orr w0, w8, w3
131 %sh1 = shl i32 %x0, %y
132 %sh2 = shl i32 %x1, %y
133 %logic = or i32 %sh1, %z
134 %r = or i32 %logic, %sh2
138 define i8 @or_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) {
139 ; CHECK-LABEL: or_shl_commute1:
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
146 %sh1 = shl i8 %x0, %y
147 %sh2 = shl i8 %x1, %y
148 %logic = or i8 %z, %sh1
149 %r = or i8 %logic, %sh2
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:
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
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
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:
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
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
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:
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
191 %sh1 = ashr i64 %x0, %y
192 %sh2 = lshr i64 %x1, %y
193 %logic = or i64 %sh1, %z
194 %r = or i64 %logic, %sh2
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:
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
208 %sh1 = lshr i64 %x0, %y
209 %sh2 = lshr i64 %x1, %w
210 %logic = or i64 %sh1, %z
211 %r = or i64 %logic, %sh2
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:
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
225 %sh1 = lshr i64 %x0, %y
226 %sh2 = lshr i64 %x1, %y
227 %logic = xor i64 %sh1, %z
228 %r = or i64 %logic, %sh2
232 define i8 @xor_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) {
233 ; CHECK-LABEL: xor_lshr_commute0:
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
241 %sh1 = lshr i8 %x0, %y
242 %sh2 = lshr i8 %x1, %y
243 %logic = xor i8 %sh1, %z
244 %r = xor i8 %logic, %sh2
248 define i32 @xor_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) {
249 ; CHECK-LABEL: xor_lshr_commute1:
251 ; CHECK-NEXT: eor w8, w0, w1
252 ; CHECK-NEXT: lsr w8, w8, w2
253 ; CHECK-NEXT: eor w0, w8, w3
255 %sh1 = lshr i32 %x0, %y
256 %sh2 = lshr i32 %x1, %y
257 %logic = xor i32 %z, %sh1
258 %r = xor i32 %logic, %sh2
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:
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
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
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:
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
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
292 define i16 @xor_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) {
293 ; CHECK-LABEL: xor_ashr_commute0:
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
301 %sh1 = ashr i16 %x0, %y
302 %sh2 = ashr i16 %x1, %y
303 %logic = xor i16 %sh1, %z
304 %r = xor i16 %logic, %sh2
308 define i64 @xor_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) {
309 ; CHECK-LABEL: xor_ashr_commute1:
311 ; CHECK-NEXT: eor x8, x0, x1
312 ; CHECK-NEXT: asr x8, x8, x2
313 ; CHECK-NEXT: eor x0, x8, x3
315 %sh1 = ashr i64 %x0, %y
316 %sh2 = ashr i64 %x1, %y
317 %logic = xor i64 %z, %sh1
318 %r = xor i64 %logic, %sh2
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:
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
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
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:
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
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
352 define i32 @xor_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) {
353 ; CHECK-LABEL: xor_shl_commute0:
355 ; CHECK-NEXT: eor w8, w0, w1
356 ; CHECK-NEXT: lsl w8, w8, w2
357 ; CHECK-NEXT: eor w0, w8, w3
359 %sh1 = shl i32 %x0, %y
360 %sh2 = shl i32 %x1, %y
361 %logic = xor i32 %sh1, %z
362 %r = xor i32 %logic, %sh2
366 define i8 @xor_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) {
367 ; CHECK-LABEL: xor_shl_commute1:
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
374 %sh1 = shl i8 %x0, %y
375 %sh2 = shl i8 %x1, %y
376 %logic = xor i8 %z, %sh1
377 %r = xor i8 %logic, %sh2
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:
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
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
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:
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
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
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:
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
419 %sh1 = ashr i64 %x0, %y
420 %sh2 = lshr i64 %x1, %y
421 %logic = xor i64 %sh1, %z
422 %r = xor i64 %logic, %sh2
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:
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
436 %sh1 = lshr i64 %x0, %y
437 %sh2 = lshr i64 %x1, %w
438 %logic = xor i64 %sh1, %z
439 %r = xor i64 %logic, %sh2
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:
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
453 %sh1 = ashr i64 %x0, %y
454 %sh2 = ashr i64 %x1, %y
455 %logic = or i64 %sh1, %z
456 %r = xor i64 %logic, %sh2
460 define i8 @and_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) {
461 ; CHECK-LABEL: and_lshr_commute0:
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
469 %sh1 = lshr i8 %x0, %y
470 %sh2 = lshr i8 %x1, %y
471 %logic = and i8 %sh1, %z
472 %r = and i8 %logic, %sh2
476 define i32 @and_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) {
477 ; CHECK-LABEL: and_lshr_commute1:
479 ; CHECK-NEXT: and w8, w0, w1
480 ; CHECK-NEXT: lsr w8, w8, w2
481 ; CHECK-NEXT: and w0, w8, w3
483 %sh1 = lshr i32 %x0, %y
484 %sh2 = lshr i32 %x1, %y
485 %logic = and i32 %z, %sh1
486 %r = and i32 %logic, %sh2
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:
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
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
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:
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
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
520 define i16 @and_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) {
521 ; CHECK-LABEL: and_ashr_commute0:
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
529 %sh1 = ashr i16 %x0, %y
530 %sh2 = ashr i16 %x1, %y
531 %logic = and i16 %sh1, %z
532 %r = and i16 %logic, %sh2
536 define i64 @and_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) {
537 ; CHECK-LABEL: and_ashr_commute1:
539 ; CHECK-NEXT: and x8, x0, x1
540 ; CHECK-NEXT: asr x8, x8, x2
541 ; CHECK-NEXT: and x0, x8, x3
543 %sh1 = ashr i64 %x0, %y
544 %sh2 = ashr i64 %x1, %y
545 %logic = and i64 %z, %sh1
546 %r = and i64 %logic, %sh2
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:
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
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
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:
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
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
580 define i32 @and_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) {
581 ; CHECK-LABEL: and_shl_commute0:
583 ; CHECK-NEXT: and w8, w0, w1
584 ; CHECK-NEXT: lsl w8, w8, w2
585 ; CHECK-NEXT: and w0, w8, w3
587 %sh1 = shl i32 %x0, %y
588 %sh2 = shl i32 %x1, %y
589 %logic = and i32 %sh1, %z
590 %r = and i32 %logic, %sh2
594 define i8 @and_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) {
595 ; CHECK-LABEL: and_shl_commute1:
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
602 %sh1 = shl i8 %x0, %y
603 %sh2 = shl i8 %x1, %y
604 %logic = and i8 %z, %sh1
605 %r = and i8 %logic, %sh2
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:
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
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
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:
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
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
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:
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
647 %sh1 = lshr i64 %x0, %y
648 %sh2 = ashr i64 %x1, %y
649 %logic = and i64 %sh1, %z
650 %r = and i64 %logic, %sh2
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:
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
664 %sh1 = lshr i64 %x0, %y
665 %sh2 = lshr i64 %x1, %w
666 %logic = and i64 %sh1, %z
667 %r = and i64 %logic, %sh2
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:
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
681 %sh1 = shl i64 %x0, %y
682 %sh2 = shl i64 %x1, %y
683 %logic = xor i64 %sh1, %z
684 %r = and i64 %logic, %sh2
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:
693 ; CHECK-NEXT: orr w8, w0, w1
694 ; CHECK-NEXT: extr w0, w8, w0, #27
697 %sh1 = shl i32 %or1, 5
698 %sh2 = lshr i32 %x, 27
699 %r = or i32 %sh1, %sh2
703 define i64 @or_fshl_commute1(i64 %x, i64 %y) {
704 ; CHECK-LABEL: or_fshl_commute1:
706 ; CHECK-NEXT: orr w8, w1, w0
707 ; CHECK-NEXT: extr x0, x8, x0, #29
710 %sh1 = shl i64 %or1, 35
711 %sh2 = lshr i64 %x, 29
712 %r = or i64 %sh1, %sh2
716 define i16 @or_fshl_commute2(i16 %x, i16 %y) {
717 ; CHECK-LABEL: or_fshl_commute2:
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
725 %sh1 = shl i16 %or1, 2
726 %sh2 = lshr i16 %x, 14
727 %r = or i16 %sh2, %sh1
731 define i8 @or_fshl_commute3(i8 %x, i8 %y) {
732 ; CHECK-LABEL: or_fshl_commute3:
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
740 %sh1 = shl i8 %or1, 5
742 %r = or i8 %sh2, %sh1
746 define i32 @or_fshl_wrong_shift(i32 %x, i32 %y) {
747 ; CHECK-LABEL: or_fshl_wrong_shift:
749 ; CHECK-NEXT: orr w8, w0, w1
750 ; CHECK-NEXT: lsl w8, w8, #20
751 ; CHECK-NEXT: orr w0, w8, w0, lsr #11
754 %sh1 = shl i32 %or1, 20
755 %sh2 = lshr i32 %x, 11
756 %r = or i32 %sh1, %sh2
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:
765 ; CHECK-NEXT: orr x8, x0, x1
766 ; CHECK-NEXT: extr x0, x0, x8, #24
769 %sh1 = shl i64 %x, 40
770 %sh2 = lshr i64 %or1, 24
771 %r = or i64 %sh1, %sh2
775 define i32 @or_fshr_commute1(i32 %x, i32 %y) {
776 ; CHECK-LABEL: or_fshr_commute1:
778 ; CHECK-NEXT: orr w8, w1, w0
779 ; CHECK-NEXT: extr w0, w0, w8, #29
783 %sh2 = lshr i32 %or1, 29
784 %r = or i32 %sh1, %sh2
788 define i16 @or_fshr_commute2(i16 %x, i16 %y) {
789 ; CHECK-LABEL: or_fshr_commute2:
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
798 %sh2 = lshr i16 %or1, 7
799 %r = or i16 %sh2, %sh1
803 define i8 @or_fshr_commute3(i8 %x, i8 %y) {
804 ; CHECK-LABEL: or_fshr_commute3:
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
813 %sh2 = lshr i8 %or1, 6
814 %r = or i8 %sh2, %sh1
818 define i32 @or_fshr_wrong_shift(i32 %x, i32 %y) {
819 ; CHECK-LABEL: or_fshr_wrong_shift:
821 ; CHECK-NEXT: orr w8, w0, w1
822 ; CHECK-NEXT: lsr w8, w8, #26
823 ; CHECK-NEXT: orr w0, w8, w0, lsl #7
827 %sh2 = lshr i32 %or1, 26
828 %r = or i32 %sh1, %sh2