1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
4 ;==============================================================================;
5 ; the shift amount is negated (shiftbitwidth - shiftamt)
6 ;==============================================================================;
9 ;------------------------------------------------------------------------------;
11 define i32 @reg32_shl_by_negated(i32 %val, i32 %shamt) nounwind {
12 ; CHECK-LABEL: reg32_shl_by_negated:
14 ; CHECK-NEXT: neg w8, w1
15 ; CHECK-NEXT: lsl w0, w0, w8
17 %negshamt = sub i32 32, %shamt
18 %shifted = shl i32 %val, %negshamt
21 define i32 @load32_shl_by_negated(i32* %valptr, i32 %shamt) nounwind {
22 ; CHECK-LABEL: load32_shl_by_negated:
24 ; CHECK-NEXT: ldr w8, [x0]
25 ; CHECK-NEXT: neg w9, w1
26 ; CHECK-NEXT: lsl w0, w8, w9
28 %val = load i32, i32* %valptr
29 %negshamt = sub i32 32, %shamt
30 %shifted = shl i32 %val, %negshamt
33 define void @store32_shl_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
34 ; CHECK-LABEL: store32_shl_by_negated:
36 ; CHECK-NEXT: neg w8, w2
37 ; CHECK-NEXT: lsl w8, w0, w8
38 ; CHECK-NEXT: str w8, [x1]
40 %negshamt = sub i32 32, %shamt
41 %shifted = shl i32 %val, %negshamt
42 store i32 %shifted, i32* %dstptr
45 define void @modify32_shl_by_negated(i32* %valptr, i32 %shamt) nounwind {
46 ; CHECK-LABEL: modify32_shl_by_negated:
48 ; CHECK-NEXT: ldr w8, [x0]
49 ; CHECK-NEXT: neg w9, w1
50 ; CHECK-NEXT: lsl w8, w8, w9
51 ; CHECK-NEXT: str w8, [x0]
53 %val = load i32, i32* %valptr
54 %negshamt = sub i32 32, %shamt
55 %shifted = shl i32 %val, %negshamt
56 store i32 %shifted, i32* %valptr
60 define i64 @reg64_shl_by_negated(i64 %val, i64 %shamt) nounwind {
61 ; CHECK-LABEL: reg64_shl_by_negated:
63 ; CHECK-NEXT: neg x8, x1
64 ; CHECK-NEXT: lsl x0, x0, x8
66 %negshamt = sub i64 64, %shamt
67 %shifted = shl i64 %val, %negshamt
70 define i64 @load64_shl_by_negated(i64* %valptr, i64 %shamt) nounwind {
71 ; CHECK-LABEL: load64_shl_by_negated:
73 ; CHECK-NEXT: ldr x8, [x0]
74 ; CHECK-NEXT: neg x9, x1
75 ; CHECK-NEXT: lsl x0, x8, x9
77 %val = load i64, i64* %valptr
78 %negshamt = sub i64 64, %shamt
79 %shifted = shl i64 %val, %negshamt
82 define void @store64_shl_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
83 ; CHECK-LABEL: store64_shl_by_negated:
85 ; CHECK-NEXT: neg x8, x2
86 ; CHECK-NEXT: lsl x8, x0, x8
87 ; CHECK-NEXT: str x8, [x1]
89 %negshamt = sub i64 64, %shamt
90 %shifted = shl i64 %val, %negshamt
91 store i64 %shifted, i64* %dstptr
94 define void @modify64_shl_by_negated(i64* %valptr, i64 %shamt) nounwind {
95 ; CHECK-LABEL: modify64_shl_by_negated:
97 ; CHECK-NEXT: ldr x8, [x0]
98 ; CHECK-NEXT: neg x9, x1
99 ; CHECK-NEXT: lsl x8, x8, x9
100 ; CHECK-NEXT: str x8, [x0]
102 %val = load i64, i64* %valptr
103 %negshamt = sub i64 64, %shamt
104 %shifted = shl i64 %val, %negshamt
105 store i64 %shifted, i64* %valptr
109 ; logical shift right
110 ;------------------------------------------------------------------------------;
112 define i32 @reg32_lshr_by_negated(i32 %val, i32 %shamt) nounwind {
113 ; CHECK-LABEL: reg32_lshr_by_negated:
115 ; CHECK-NEXT: neg w8, w1
116 ; CHECK-NEXT: lsr w0, w0, w8
118 %negshamt = sub i32 32, %shamt
119 %shifted = lshr i32 %val, %negshamt
122 define i32 @load32_lshr_by_negated(i32* %valptr, i32 %shamt) nounwind {
123 ; CHECK-LABEL: load32_lshr_by_negated:
125 ; CHECK-NEXT: ldr w8, [x0]
126 ; CHECK-NEXT: neg w9, w1
127 ; CHECK-NEXT: lsr w0, w8, w9
129 %val = load i32, i32* %valptr
130 %negshamt = sub i32 32, %shamt
131 %shifted = lshr i32 %val, %negshamt
134 define void @store32_lshr_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
135 ; CHECK-LABEL: store32_lshr_by_negated:
137 ; CHECK-NEXT: neg w8, w2
138 ; CHECK-NEXT: lsr w8, w0, w8
139 ; CHECK-NEXT: str w8, [x1]
141 %negshamt = sub i32 32, %shamt
142 %shifted = lshr i32 %val, %negshamt
143 store i32 %shifted, i32* %dstptr
146 define void @modify32_lshr_by_negated(i32* %valptr, i32 %shamt) nounwind {
147 ; CHECK-LABEL: modify32_lshr_by_negated:
149 ; CHECK-NEXT: ldr w8, [x0]
150 ; CHECK-NEXT: neg w9, w1
151 ; CHECK-NEXT: lsr w8, w8, w9
152 ; CHECK-NEXT: str w8, [x0]
154 %val = load i32, i32* %valptr
155 %negshamt = sub i32 32, %shamt
156 %shifted = lshr i32 %val, %negshamt
157 store i32 %shifted, i32* %valptr
161 define i64 @reg64_lshr_by_negated(i64 %val, i64 %shamt) nounwind {
162 ; CHECK-LABEL: reg64_lshr_by_negated:
164 ; CHECK-NEXT: neg x8, x1
165 ; CHECK-NEXT: lsr x0, x0, x8
167 %negshamt = sub i64 64, %shamt
168 %shifted = lshr i64 %val, %negshamt
171 define i64 @load64_lshr_by_negated(i64* %valptr, i64 %shamt) nounwind {
172 ; CHECK-LABEL: load64_lshr_by_negated:
174 ; CHECK-NEXT: ldr x8, [x0]
175 ; CHECK-NEXT: neg x9, x1
176 ; CHECK-NEXT: lsr x0, x8, x9
178 %val = load i64, i64* %valptr
179 %negshamt = sub i64 64, %shamt
180 %shifted = lshr i64 %val, %negshamt
183 define void @store64_lshr_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
184 ; CHECK-LABEL: store64_lshr_by_negated:
186 ; CHECK-NEXT: neg x8, x2
187 ; CHECK-NEXT: lsr x8, x0, x8
188 ; CHECK-NEXT: str x8, [x1]
190 %negshamt = sub i64 64, %shamt
191 %shifted = lshr i64 %val, %negshamt
192 store i64 %shifted, i64* %dstptr
195 define void @modify64_lshr_by_negated(i64* %valptr, i64 %shamt) nounwind {
196 ; CHECK-LABEL: modify64_lshr_by_negated:
198 ; CHECK-NEXT: ldr x8, [x0]
199 ; CHECK-NEXT: neg x9, x1
200 ; CHECK-NEXT: lsr x8, x8, x9
201 ; CHECK-NEXT: str x8, [x0]
203 %val = load i64, i64* %valptr
204 %negshamt = sub i64 64, %shamt
205 %shifted = lshr i64 %val, %negshamt
206 store i64 %shifted, i64* %valptr
210 ; arithmetic shift right
211 ;------------------------------------------------------------------------------;
213 define i32 @reg32_ashr_by_negated(i32 %val, i32 %shamt) nounwind {
214 ; CHECK-LABEL: reg32_ashr_by_negated:
216 ; CHECK-NEXT: neg w8, w1
217 ; CHECK-NEXT: asr w0, w0, w8
219 %negshamt = sub i32 32, %shamt
220 %shifted = ashr i32 %val, %negshamt
223 define i32 @load32_ashr_by_negated(i32* %valptr, i32 %shamt) nounwind {
224 ; CHECK-LABEL: load32_ashr_by_negated:
226 ; CHECK-NEXT: ldr w8, [x0]
227 ; CHECK-NEXT: neg w9, w1
228 ; CHECK-NEXT: asr w0, w8, w9
230 %val = load i32, i32* %valptr
231 %negshamt = sub i32 32, %shamt
232 %shifted = ashr i32 %val, %negshamt
235 define void @store32_ashr_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
236 ; CHECK-LABEL: store32_ashr_by_negated:
238 ; CHECK-NEXT: neg w8, w2
239 ; CHECK-NEXT: asr w8, w0, w8
240 ; CHECK-NEXT: str w8, [x1]
242 %negshamt = sub i32 32, %shamt
243 %shifted = ashr i32 %val, %negshamt
244 store i32 %shifted, i32* %dstptr
247 define void @modify32_ashr_by_negated(i32* %valptr, i32 %shamt) nounwind {
248 ; CHECK-LABEL: modify32_ashr_by_negated:
250 ; CHECK-NEXT: ldr w8, [x0]
251 ; CHECK-NEXT: neg w9, w1
252 ; CHECK-NEXT: asr w8, w8, w9
253 ; CHECK-NEXT: str w8, [x0]
255 %val = load i32, i32* %valptr
256 %negshamt = sub i32 32, %shamt
257 %shifted = ashr i32 %val, %negshamt
258 store i32 %shifted, i32* %valptr
262 define i64 @reg64_ashr_by_negated(i64 %val, i64 %shamt) nounwind {
263 ; CHECK-LABEL: reg64_ashr_by_negated:
265 ; CHECK-NEXT: neg x8, x1
266 ; CHECK-NEXT: asr x0, x0, x8
268 %negshamt = sub i64 64, %shamt
269 %shifted = ashr i64 %val, %negshamt
272 define i64 @load64_ashr_by_negated(i64* %valptr, i64 %shamt) nounwind {
273 ; CHECK-LABEL: load64_ashr_by_negated:
275 ; CHECK-NEXT: ldr x8, [x0]
276 ; CHECK-NEXT: neg x9, x1
277 ; CHECK-NEXT: asr x0, x8, x9
279 %val = load i64, i64* %valptr
280 %negshamt = sub i64 64, %shamt
281 %shifted = ashr i64 %val, %negshamt
284 define void @store64_ashr_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
285 ; CHECK-LABEL: store64_ashr_by_negated:
287 ; CHECK-NEXT: neg x8, x2
288 ; CHECK-NEXT: asr x8, x0, x8
289 ; CHECK-NEXT: str x8, [x1]
291 %negshamt = sub i64 64, %shamt
292 %shifted = ashr i64 %val, %negshamt
293 store i64 %shifted, i64* %dstptr
296 define void @modify64_ashr_by_negated(i64* %valptr, i64 %shamt) nounwind {
297 ; CHECK-LABEL: modify64_ashr_by_negated:
299 ; CHECK-NEXT: ldr x8, [x0]
300 ; CHECK-NEXT: neg x9, x1
301 ; CHECK-NEXT: asr x8, x8, x9
302 ; CHECK-NEXT: str x8, [x0]
304 %val = load i64, i64* %valptr
305 %negshamt = sub i64 64, %shamt
306 %shifted = ashr i64 %val, %negshamt
307 store i64 %shifted, i64* %valptr
311 ;==============================================================================;
312 ; the shift amount is complemented (shiftbitwidth - 1 - shiftamt)
313 ;==============================================================================;
316 ;------------------------------------------------------------------------------;
318 define i32 @reg32_shl_by_complemented(i32 %val, i32 %shamt) nounwind {
319 ; CHECK-LABEL: reg32_shl_by_complemented:
321 ; CHECK-NEXT: mov w8, #31
322 ; CHECK-NEXT: sub w8, w8, w1
323 ; CHECK-NEXT: lsl w0, w0, w8
325 %negshamt = sub i32 31, %shamt
326 %shifted = shl i32 %val, %negshamt
329 define i32 @load32_shl_by_complemented(i32* %valptr, i32 %shamt) nounwind {
330 ; CHECK-LABEL: load32_shl_by_complemented:
332 ; CHECK-NEXT: ldr w8, [x0]
333 ; CHECK-NEXT: mov w9, #31
334 ; CHECK-NEXT: sub w9, w9, w1
335 ; CHECK-NEXT: lsl w0, w8, w9
337 %val = load i32, i32* %valptr
338 %negshamt = sub i32 31, %shamt
339 %shifted = shl i32 %val, %negshamt
342 define void @store32_shl_by_complemented(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
343 ; CHECK-LABEL: store32_shl_by_complemented:
345 ; CHECK-NEXT: mov w8, #31
346 ; CHECK-NEXT: sub w8, w8, w2
347 ; CHECK-NEXT: lsl w8, w0, w8
348 ; CHECK-NEXT: str w8, [x1]
350 %negshamt = sub i32 31, %shamt
351 %shifted = shl i32 %val, %negshamt
352 store i32 %shifted, i32* %dstptr
355 define void @modify32_shl_by_complemented(i32* %valptr, i32 %shamt) nounwind {
356 ; CHECK-LABEL: modify32_shl_by_complemented:
358 ; CHECK-NEXT: ldr w8, [x0]
359 ; CHECK-NEXT: mov w9, #31
360 ; CHECK-NEXT: sub w9, w9, w1
361 ; CHECK-NEXT: lsl w8, w8, w9
362 ; CHECK-NEXT: str w8, [x0]
364 %val = load i32, i32* %valptr
365 %negshamt = sub i32 31, %shamt
366 %shifted = shl i32 %val, %negshamt
367 store i32 %shifted, i32* %valptr
371 define i64 @reg64_shl_by_complemented(i64 %val, i64 %shamt) nounwind {
372 ; CHECK-LABEL: reg64_shl_by_complemented:
374 ; CHECK-NEXT: mov w8, #63
375 ; CHECK-NEXT: sub x8, x8, x1
376 ; CHECK-NEXT: lsl x0, x0, x8
378 %negshamt = sub i64 63, %shamt
379 %shifted = shl i64 %val, %negshamt
382 define i64 @load64_shl_by_complemented(i64* %valptr, i64 %shamt) nounwind {
383 ; CHECK-LABEL: load64_shl_by_complemented:
385 ; CHECK-NEXT: ldr x8, [x0]
386 ; CHECK-NEXT: mov w9, #63
387 ; CHECK-NEXT: sub x9, x9, x1
388 ; CHECK-NEXT: lsl x0, x8, x9
390 %val = load i64, i64* %valptr
391 %negshamt = sub i64 63, %shamt
392 %shifted = shl i64 %val, %negshamt
395 define void @store64_shl_by_complemented(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
396 ; CHECK-LABEL: store64_shl_by_complemented:
398 ; CHECK-NEXT: mov w8, #63
399 ; CHECK-NEXT: sub x8, x8, x2
400 ; CHECK-NEXT: lsl x8, x0, x8
401 ; CHECK-NEXT: str x8, [x1]
403 %negshamt = sub i64 63, %shamt
404 %shifted = shl i64 %val, %negshamt
405 store i64 %shifted, i64* %dstptr
408 define void @modify64_shl_by_complemented(i64* %valptr, i64 %shamt) nounwind {
409 ; CHECK-LABEL: modify64_shl_by_complemented:
411 ; CHECK-NEXT: ldr x8, [x0]
412 ; CHECK-NEXT: mov w9, #63
413 ; CHECK-NEXT: sub x9, x9, x1
414 ; CHECK-NEXT: lsl x8, x8, x9
415 ; CHECK-NEXT: str x8, [x0]
417 %val = load i64, i64* %valptr
418 %negshamt = sub i64 63, %shamt
419 %shifted = shl i64 %val, %negshamt
420 store i64 %shifted, i64* %valptr
424 ; logical shift right
425 ;------------------------------------------------------------------------------;
427 define i32 @reg32_lshr_by_complemented(i32 %val, i32 %shamt) nounwind {
428 ; CHECK-LABEL: reg32_lshr_by_complemented:
430 ; CHECK-NEXT: mov w8, #31
431 ; CHECK-NEXT: sub w8, w8, w1
432 ; CHECK-NEXT: lsr w0, w0, w8
434 %negshamt = sub i32 31, %shamt
435 %shifted = lshr i32 %val, %negshamt
438 define i32 @load32_lshr_by_complemented(i32* %valptr, i32 %shamt) nounwind {
439 ; CHECK-LABEL: load32_lshr_by_complemented:
441 ; CHECK-NEXT: ldr w8, [x0]
442 ; CHECK-NEXT: mov w9, #31
443 ; CHECK-NEXT: sub w9, w9, w1
444 ; CHECK-NEXT: lsr w0, w8, w9
446 %val = load i32, i32* %valptr
447 %negshamt = sub i32 31, %shamt
448 %shifted = lshr i32 %val, %negshamt
451 define void @store32_lshr_by_complemented(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
452 ; CHECK-LABEL: store32_lshr_by_complemented:
454 ; CHECK-NEXT: mov w8, #31
455 ; CHECK-NEXT: sub w8, w8, w2
456 ; CHECK-NEXT: lsr w8, w0, w8
457 ; CHECK-NEXT: str w8, [x1]
459 %negshamt = sub i32 31, %shamt
460 %shifted = lshr i32 %val, %negshamt
461 store i32 %shifted, i32* %dstptr
464 define void @modify32_lshr_by_complemented(i32* %valptr, i32 %shamt) nounwind {
465 ; CHECK-LABEL: modify32_lshr_by_complemented:
467 ; CHECK-NEXT: ldr w8, [x0]
468 ; CHECK-NEXT: mov w9, #31
469 ; CHECK-NEXT: sub w9, w9, w1
470 ; CHECK-NEXT: lsr w8, w8, w9
471 ; CHECK-NEXT: str w8, [x0]
473 %val = load i32, i32* %valptr
474 %negshamt = sub i32 31, %shamt
475 %shifted = lshr i32 %val, %negshamt
476 store i32 %shifted, i32* %valptr
480 define i64 @reg64_lshr_by_complemented(i64 %val, i64 %shamt) nounwind {
481 ; CHECK-LABEL: reg64_lshr_by_complemented:
483 ; CHECK-NEXT: mov w8, #63
484 ; CHECK-NEXT: sub x8, x8, x1
485 ; CHECK-NEXT: lsr x0, x0, x8
487 %negshamt = sub i64 63, %shamt
488 %shifted = lshr i64 %val, %negshamt
491 define i64 @load64_lshr_by_complemented(i64* %valptr, i64 %shamt) nounwind {
492 ; CHECK-LABEL: load64_lshr_by_complemented:
494 ; CHECK-NEXT: ldr x8, [x0]
495 ; CHECK-NEXT: mov w9, #63
496 ; CHECK-NEXT: sub x9, x9, x1
497 ; CHECK-NEXT: lsr x0, x8, x9
499 %val = load i64, i64* %valptr
500 %negshamt = sub i64 63, %shamt
501 %shifted = lshr i64 %val, %negshamt
504 define void @store64_lshr_by_complemented(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
505 ; CHECK-LABEL: store64_lshr_by_complemented:
507 ; CHECK-NEXT: mov w8, #63
508 ; CHECK-NEXT: sub x8, x8, x2
509 ; CHECK-NEXT: lsr x8, x0, x8
510 ; CHECK-NEXT: str x8, [x1]
512 %negshamt = sub i64 63, %shamt
513 %shifted = lshr i64 %val, %negshamt
514 store i64 %shifted, i64* %dstptr
517 define void @modify64_lshr_by_complemented(i64* %valptr, i64 %shamt) nounwind {
518 ; CHECK-LABEL: modify64_lshr_by_complemented:
520 ; CHECK-NEXT: ldr x8, [x0]
521 ; CHECK-NEXT: mov w9, #63
522 ; CHECK-NEXT: sub x9, x9, x1
523 ; CHECK-NEXT: lsr x8, x8, x9
524 ; CHECK-NEXT: str x8, [x0]
526 %val = load i64, i64* %valptr
527 %negshamt = sub i64 63, %shamt
528 %shifted = lshr i64 %val, %negshamt
529 store i64 %shifted, i64* %valptr
533 ; arithmetic shift right
534 ;------------------------------------------------------------------------------;
536 define i32 @reg32_ashr_by_complemented(i32 %val, i32 %shamt) nounwind {
537 ; CHECK-LABEL: reg32_ashr_by_complemented:
539 ; CHECK-NEXT: mov w8, #31
540 ; CHECK-NEXT: sub w8, w8, w1
541 ; CHECK-NEXT: asr w0, w0, w8
543 %negshamt = sub i32 31, %shamt
544 %shifted = ashr i32 %val, %negshamt
547 define i32 @load32_ashr_by_complemented(i32* %valptr, i32 %shamt) nounwind {
548 ; CHECK-LABEL: load32_ashr_by_complemented:
550 ; CHECK-NEXT: ldr w8, [x0]
551 ; CHECK-NEXT: mov w9, #31
552 ; CHECK-NEXT: sub w9, w9, w1
553 ; CHECK-NEXT: asr w0, w8, w9
555 %val = load i32, i32* %valptr
556 %negshamt = sub i32 31, %shamt
557 %shifted = ashr i32 %val, %negshamt
560 define void @store32_ashr_by_complemented(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
561 ; CHECK-LABEL: store32_ashr_by_complemented:
563 ; CHECK-NEXT: mov w8, #31
564 ; CHECK-NEXT: sub w8, w8, w2
565 ; CHECK-NEXT: asr w8, w0, w8
566 ; CHECK-NEXT: str w8, [x1]
568 %negshamt = sub i32 31, %shamt
569 %shifted = ashr i32 %val, %negshamt
570 store i32 %shifted, i32* %dstptr
573 define void @modify32_ashr_by_complemented(i32* %valptr, i32 %shamt) nounwind {
574 ; CHECK-LABEL: modify32_ashr_by_complemented:
576 ; CHECK-NEXT: ldr w8, [x0]
577 ; CHECK-NEXT: mov w9, #31
578 ; CHECK-NEXT: sub w9, w9, w1
579 ; CHECK-NEXT: asr w8, w8, w9
580 ; CHECK-NEXT: str w8, [x0]
582 %val = load i32, i32* %valptr
583 %negshamt = sub i32 31, %shamt
584 %shifted = ashr i32 %val, %negshamt
585 store i32 %shifted, i32* %valptr
589 define i64 @reg64_ashr_by_complemented(i64 %val, i64 %shamt) nounwind {
590 ; CHECK-LABEL: reg64_ashr_by_complemented:
592 ; CHECK-NEXT: mov w8, #63
593 ; CHECK-NEXT: sub x8, x8, x1
594 ; CHECK-NEXT: asr x0, x0, x8
596 %negshamt = sub i64 63, %shamt
597 %shifted = ashr i64 %val, %negshamt
600 define i64 @load64_ashr_by_complemented(i64* %valptr, i64 %shamt) nounwind {
601 ; CHECK-LABEL: load64_ashr_by_complemented:
603 ; CHECK-NEXT: ldr x8, [x0]
604 ; CHECK-NEXT: mov w9, #63
605 ; CHECK-NEXT: sub x9, x9, x1
606 ; CHECK-NEXT: asr x0, x8, x9
608 %val = load i64, i64* %valptr
609 %negshamt = sub i64 63, %shamt
610 %shifted = ashr i64 %val, %negshamt
613 define void @store64_ashr_by_complemented(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
614 ; CHECK-LABEL: store64_ashr_by_complemented:
616 ; CHECK-NEXT: mov w8, #63
617 ; CHECK-NEXT: sub x8, x8, x2
618 ; CHECK-NEXT: asr x8, x0, x8
619 ; CHECK-NEXT: str x8, [x1]
621 %negshamt = sub i64 63, %shamt
622 %shifted = ashr i64 %val, %negshamt
623 store i64 %shifted, i64* %dstptr
626 define void @modify64_ashr_by_complemented(i64* %valptr, i64 %shamt) nounwind {
627 ; CHECK-LABEL: modify64_ashr_by_complemented:
629 ; CHECK-NEXT: ldr x8, [x0]
630 ; CHECK-NEXT: mov w9, #63
631 ; CHECK-NEXT: sub x9, x9, x1
632 ; CHECK-NEXT: asr x8, x8, x9
633 ; CHECK-NEXT: str x8, [x0]
635 %val = load i64, i64* %valptr
636 %negshamt = sub i64 63, %shamt
637 %shifted = ashr i64 %val, %negshamt
638 store i64 %shifted, i64* %valptr
642 ;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
643 ; next let's only test simple reg pattern, and only lshr.
644 ;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
646 ;==============================================================================;
647 ; subtraction from negated shift amount
649 define i32 @reg32_lshr_by_sub_from_negated(i32 %val, i32 %a, i32 %b) nounwind {
650 ; CHECK-LABEL: reg32_lshr_by_sub_from_negated:
652 ; CHECK-NEXT: add w8, w1, w2
653 ; CHECK-NEXT: neg w8, w8
654 ; CHECK-NEXT: lsr w0, w0, w8
656 %nega = sub i32 32, %a
657 %negasubb = sub i32 %nega, %b
658 %shifted = lshr i32 %val, %negasubb
661 define i64 @reg64_lshr_by_sub_from_negated(i64 %val, i64 %a, i64 %b) nounwind {
662 ; CHECK-LABEL: reg64_lshr_by_sub_from_negated:
664 ; CHECK-NEXT: add x8, x1, x2
665 ; CHECK-NEXT: neg x8, x8
666 ; CHECK-NEXT: lsr x0, x0, x8
668 %nega = sub i64 64, %a
669 %negasubb = sub i64 %nega, %b
670 %shifted = lshr i64 %val, %negasubb
674 ;==============================================================================;
675 ; subtraction of negated shift amount
677 define i32 @reg32_lshr_by_sub_of_negated(i32 %val, i32 %a, i32 %b) nounwind {
678 ; CHECK-LABEL: reg32_lshr_by_sub_of_negated:
680 ; CHECK-NEXT: add w8, w1, w2
681 ; CHECK-NEXT: lsr w0, w0, w8
683 %nega = sub i32 32, %a
684 %negasubb = sub i32 %b, %nega
685 %shifted = lshr i32 %val, %negasubb
688 define i64 @reg64_lshr_by_sub_of_negated(i64 %val, i64 %a, i64 %b) nounwind {
689 ; CHECK-LABEL: reg64_lshr_by_sub_of_negated:
691 ; CHECK-NEXT: add x8, x1, x2
692 ; CHECK-NEXT: lsr x0, x0, x8
694 %nega = sub i64 64, %a
695 %negasubb = sub i64 %b, %nega
696 %shifted = lshr i64 %val, %negasubb
700 ;==============================================================================;
701 ; add to negated shift amount
704 define i32 @reg32_lshr_by_add_to_negated(i32 %val, i32 %a, i32 %b) nounwind {
705 ; CHECK-LABEL: reg32_lshr_by_add_to_negated:
707 ; CHECK-NEXT: sub w8, w2, w1
708 ; CHECK-NEXT: lsr w0, w0, w8
710 %nega = sub i32 32, %a
711 %negasubb = add i32 %nega, %b
712 %shifted = lshr i32 %val, %negasubb
715 define i64 @reg64_lshr_by_add_to_negated(i64 %val, i64 %a, i64 %b) nounwind {
716 ; CHECK-LABEL: reg64_lshr_by_add_to_negated:
718 ; CHECK-NEXT: sub x8, x2, x1
719 ; CHECK-NEXT: lsr x0, x0, x8
721 %nega = sub i64 64, %a
722 %negasubb = add i64 %nega, %b
723 %shifted = lshr i64 %val, %negasubb
727 ;==============================================================================;
728 ; subtraction of negated shift amounts
730 define i32 @reg32_lshr_by_sub_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
731 ; CHECK-LABEL: reg32_lshr_by_sub_of_negated_amts:
733 ; CHECK-NEXT: sub w8, w2, w1
734 ; CHECK-NEXT: lsr w0, w0, w8
736 %nega = sub i32 32, %a
737 %negb = sub i32 32, %b
738 %negasubnegb = sub i32 %nega, %negb
739 %shifted = lshr i32 %val, %negasubnegb
742 define i64 @reg64_lshr_by_sub_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
743 ; CHECK-LABEL: reg64_lshr_by_sub_of_negated_amts:
745 ; CHECK-NEXT: sub x8, x2, x1
746 ; CHECK-NEXT: lsr x0, x0, x8
748 %nega = sub i64 64, %a
749 %negb = sub i64 64, %b
750 %negasubnegb = sub i64 %nega, %negb
751 %shifted = lshr i64 %val, %negasubnegb
755 ;==============================================================================;
756 ; addition of negated shift amounts
758 define i32 @reg32_lshr_by_add_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
759 ; CHECK-LABEL: reg32_lshr_by_add_of_negated_amts:
761 ; CHECK-NEXT: add w8, w1, w2
762 ; CHECK-NEXT: neg w8, w8
763 ; CHECK-NEXT: lsr w0, w0, w8
765 %nega = sub i32 32, %a
766 %negb = sub i32 32, %b
767 %negasubnegb = add i32 %nega, %negb
768 %shifted = lshr i32 %val, %negasubnegb
771 define i64 @reg64_lshr_by_add_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
772 ; CHECK-LABEL: reg64_lshr_by_add_of_negated_amts:
774 ; CHECK-NEXT: add x8, x1, x2
775 ; CHECK-NEXT: neg x8, x8
776 ; CHECK-NEXT: lsr x0, x0, x8
778 %nega = sub i64 64, %a
779 %negb = sub i64 64, %b
780 %negasubnegb = add i64 %nega, %negb
781 %shifted = lshr i64 %val, %negasubnegb
785 ;==============================================================================;
786 ; and patterns with an actual negation+addition
788 define i32 @reg32_lshr_by_negated_unfolded(i32 %val, i32 %shamt) nounwind {
789 ; CHECK-LABEL: reg32_lshr_by_negated_unfolded:
791 ; CHECK-NEXT: neg w8, w1
792 ; CHECK-NEXT: lsr w0, w0, w8
794 %negshamt = sub i32 0, %shamt
795 %negaaddbitwidth = add i32 %negshamt, 32
796 %shifted = lshr i32 %val, %negaaddbitwidth
799 define i64 @reg64_lshr_by_negated_unfolded(i64 %val, i64 %shamt) nounwind {
800 ; CHECK-LABEL: reg64_lshr_by_negated_unfolded:
802 ; CHECK-NEXT: neg x8, x1
803 ; CHECK-NEXT: lsr x0, x0, x8
805 %negshamt = sub i64 0, %shamt
806 %negaaddbitwidth = add i64 %negshamt, 64
807 %shifted = lshr i64 %val, %negaaddbitwidth
811 define i32 @reg32_lshr_by_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
812 ; CHECK-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
814 ; CHECK-NEXT: add w8, w1, w2
815 ; CHECK-NEXT: neg w8, w8
816 ; CHECK-NEXT: lsr w0, w0, w8
818 %nega = sub i32 0, %a
819 %negaaddbitwidth = add i32 %nega, 32
820 %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
821 %shifted = lshr i32 %val, %negaaddbitwidthsubb
824 define i64 @reg64_lshr_by_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
825 ; CHECK-LABEL: reg64_lshr_by_negated_unfolded_sub_b:
827 ; CHECK-NEXT: add x8, x1, x2
828 ; CHECK-NEXT: neg x8, x8
829 ; CHECK-NEXT: lsr x0, x0, x8
831 %nega = sub i64 0, %a
832 %negaaddbitwidth = add i64 %nega, 64
833 %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
834 %shifted = lshr i64 %val, %negaaddbitwidthsubb
838 define i32 @reg32_lshr_by_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
839 ; CHECK-LABEL: reg32_lshr_by_b_sub_negated_unfolded:
841 ; CHECK-NEXT: add w8, w2, w1
842 ; CHECK-NEXT: lsr w0, w0, w8
844 %nega = sub i32 0, %a
845 %negaaddbitwidth = add i32 %nega, 32
846 %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
847 %shifted = lshr i32 %val, %negaaddbitwidthsubb
850 define i64 @reg64_lshr_by_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
851 ; CHECK-LABEL: reg64_lshr_by_b_sub_negated_unfolded:
853 ; CHECK-NEXT: add x8, x2, x1
854 ; CHECK-NEXT: lsr x0, x0, x8
856 %nega = sub i64 0, %a
857 %negaaddbitwidth = add i64 %nega, 64
858 %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
859 %shifted = lshr i64 %val, %negaaddbitwidthsubb
863 define i32 @reg32_lshr_by_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
864 ; CHECK-LABEL: reg32_lshr_by_negated_unfolded_add_b:
866 ; CHECK-NEXT: sub w8, w2, w1
867 ; CHECK-NEXT: lsr w0, w0, w8
869 %nega = sub i32 0, %a
870 %negaaddbitwidth = add i32 %nega, 32
871 %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
872 %shifted = lshr i32 %val, %negaaddbitwidthaddb
875 define i64 @reg64_lshr_by_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
876 ; CHECK-LABEL: reg64_lshr_by_negated_unfolded_add_b:
878 ; CHECK-NEXT: sub x8, x2, x1
879 ; CHECK-NEXT: lsr x0, x0, x8
881 %nega = sub i64 0, %a
882 %negaaddbitwidth = add i64 %nega, 64
883 %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
884 %shifted = lshr i64 %val, %negaaddbitwidthaddb
888 ;==============================================================================;
889 ; and patterns with an actual negation+mask
891 define i32 @reg32_lshr_by_masked_negated_unfolded(i32 %val, i32 %shamt) nounwind {
892 ; CHECK-LABEL: reg32_lshr_by_masked_negated_unfolded:
894 ; CHECK-NEXT: neg w8, w1
895 ; CHECK-NEXT: lsr w0, w0, w8
897 %negshamt = sub i32 0, %shamt
898 %negaaddbitwidth = and i32 %negshamt, 31
899 %shifted = lshr i32 %val, %negaaddbitwidth
902 define i64 @reg64_lshr_by_masked_negated_unfolded(i64 %val, i64 %shamt) nounwind {
903 ; CHECK-LABEL: reg64_lshr_by_masked_negated_unfolded:
905 ; CHECK-NEXT: neg w8, w1
906 ; CHECK-NEXT: lsr x0, x0, x8
908 %negshamt = sub i64 0, %shamt
909 %negaaddbitwidth = and i64 %negshamt, 63
910 %shifted = lshr i64 %val, %negaaddbitwidth
914 define i32 @reg32_lshr_by_masked_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
915 ; CHECK-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b:
917 ; CHECK-NEXT: neg w8, w1
918 ; CHECK-NEXT: and w8, w8, #0x1f
919 ; CHECK-NEXT: sub w8, w8, w2
920 ; CHECK-NEXT: lsr w0, w0, w8
922 %nega = sub i32 0, %a
923 %negaaddbitwidth = and i32 %nega, 31
924 %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
925 %shifted = lshr i32 %val, %negaaddbitwidthsubb
928 define i64 @reg64_lshr_by_masked_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
929 ; CHECK-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b:
931 ; CHECK-NEXT: neg w8, w1
932 ; CHECK-NEXT: and x8, x8, #0x3f
933 ; CHECK-NEXT: sub x8, x8, x2
934 ; CHECK-NEXT: lsr x0, x0, x8
936 %nega = sub i64 0, %a
937 %negaaddbitwidth = and i64 %nega, 63
938 %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
939 %shifted = lshr i64 %val, %negaaddbitwidthsubb
943 define i32 @reg32_lshr_by_masked_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
944 ; CHECK-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded:
946 ; CHECK-NEXT: neg w8, w1
947 ; CHECK-NEXT: and w8, w8, #0x1f
948 ; CHECK-NEXT: sub w8, w2, w8
949 ; CHECK-NEXT: lsr w0, w0, w8
951 %nega = sub i32 0, %a
952 %negaaddbitwidth = and i32 %nega, 31
953 %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
954 %shifted = lshr i32 %val, %negaaddbitwidthsubb
957 define i64 @reg64_lshr_by_masked_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
958 ; CHECK-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded:
960 ; CHECK-NEXT: neg w8, w1
961 ; CHECK-NEXT: and x8, x8, #0x3f
962 ; CHECK-NEXT: sub x8, x2, x8
963 ; CHECK-NEXT: lsr x0, x0, x8
965 %nega = sub i64 0, %a
966 %negaaddbitwidth = and i64 %nega, 63
967 %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
968 %shifted = lshr i64 %val, %negaaddbitwidthsubb
972 define i32 @reg32_lshr_by_masked_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
973 ; CHECK-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b:
975 ; CHECK-NEXT: neg w8, w1
976 ; CHECK-NEXT: and w8, w8, #0x1f
977 ; CHECK-NEXT: add w8, w8, w2
978 ; CHECK-NEXT: lsr w0, w0, w8
980 %nega = sub i32 0, %a
981 %negaaddbitwidth = and i32 %nega, 31
982 %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
983 %shifted = lshr i32 %val, %negaaddbitwidthaddb
986 define i64 @reg64_lshr_by_masked_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
987 ; CHECK-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b:
989 ; CHECK-NEXT: neg w8, w1
990 ; CHECK-NEXT: and x8, x8, #0x3f
991 ; CHECK-NEXT: add x8, x8, x2
992 ; CHECK-NEXT: lsr x0, x0, x8
994 %nega = sub i64 0, %a
995 %negaaddbitwidth = and i64 %nega, 63
996 %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
997 %shifted = lshr i64 %val, %negaaddbitwidthaddb
1001 define i32 @t(i64 %x) {
1004 ; CHECK-NEXT: ubfx x0, x0, #17, #28
1005 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
1007 %s = lshr i64 %x, 13
1008 %t = trunc i64 %s to i32