1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
4 ; If we have a shift by sign-extended value, we can replace sign-extension
7 define i32 @t0_shl(i32 %x, i8 %shamt) nounwind {
10 ; CHECK-NEXT: sxtb w8, w1
11 ; CHECK-NEXT: lsl w0, w0, w8
13 %shamt_wide = sext i8 %shamt to i32
14 %r = shl i32 %x, %shamt_wide
17 define i32 @t1_lshr(i32 %x, i8 %shamt) nounwind {
18 ; CHECK-LABEL: t1_lshr:
20 ; CHECK-NEXT: sxtb w8, w1
21 ; CHECK-NEXT: lsr w0, w0, w8
23 %shamt_wide = sext i8 %shamt to i32
24 %r = lshr i32 %x, %shamt_wide
27 define i32 @t2_ashr(i32 %x, i8 %shamt) nounwind {
28 ; CHECK-LABEL: t2_ashr:
30 ; CHECK-NEXT: sxtb w8, w1
31 ; CHECK-NEXT: asr w0, w0, w8
33 %shamt_wide = sext i8 %shamt to i32
34 %r = ashr i32 %x, %shamt_wide
38 define <4 x i32> @t3_vec_shl(<4 x i32> %x, <4 x i8> %shamt) nounwind {
39 ; CHECK-LABEL: t3_vec_shl:
41 ; CHECK-NEXT: ushll v1.4s, v1.4h, #0
42 ; CHECK-NEXT: shl v1.4s, v1.4s, #24
43 ; CHECK-NEXT: sshr v1.4s, v1.4s, #24
44 ; CHECK-NEXT: ushl v0.4s, v0.4s, v1.4s
46 %shamt_wide = sext <4 x i8> %shamt to <4 x i32>
47 %r = shl <4 x i32> %x, %shamt_wide
50 define <4 x i32> @t4_vec_lshr(<4 x i32> %x, <4 x i8> %shamt) nounwind {
51 ; CHECK-LABEL: t4_vec_lshr:
53 ; CHECK-NEXT: ushll v1.4s, v1.4h, #0
54 ; CHECK-NEXT: shl v1.4s, v1.4s, #24
55 ; CHECK-NEXT: sshr v1.4s, v1.4s, #24
56 ; CHECK-NEXT: neg v1.4s, v1.4s
57 ; CHECK-NEXT: ushl v0.4s, v0.4s, v1.4s
59 %shamt_wide = sext <4 x i8> %shamt to <4 x i32>
60 %r = lshr <4 x i32> %x, %shamt_wide
63 define <4 x i32> @t5_vec_ashr(<4 x i32> %x, <4 x i8> %shamt) nounwind {
64 ; CHECK-LABEL: t5_vec_ashr:
66 ; CHECK-NEXT: ushll v1.4s, v1.4h, #0
67 ; CHECK-NEXT: shl v1.4s, v1.4s, #24
68 ; CHECK-NEXT: sshr v1.4s, v1.4s, #24
69 ; CHECK-NEXT: neg v1.4s, v1.4s
70 ; CHECK-NEXT: sshl v0.4s, v0.4s, v1.4s
72 %shamt_wide = sext <4 x i8> %shamt to <4 x i32>
73 %r = ashr <4 x i32> %x, %shamt_wide
77 ; This is not valid for funnel shifts
78 declare i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %c)
79 declare i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %c)
80 define i32 @n6_fshl(i32 %x, i32 %y, i8 %shamt) nounwind {
81 ; CHECK-LABEL: n6_fshl:
83 ; CHECK-NEXT: lsr w8, w1, #1
84 ; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2
85 ; CHECK-NEXT: mvn w9, w2
86 ; CHECK-NEXT: lsl w10, w0, w2
87 ; CHECK-NEXT: lsr w8, w8, w9
88 ; CHECK-NEXT: orr w0, w10, w8
90 %shamt_wide = sext i8 %shamt to i32
91 %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %shamt_wide)
94 define i32 @n7_fshr(i32 %x, i32 %y, i8 %shamt) nounwind {
95 ; CHECK-LABEL: n7_fshr:
97 ; CHECK-NEXT: lsl w8, w0, #1
98 ; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2
99 ; CHECK-NEXT: mvn w9, w2
100 ; CHECK-NEXT: lsr w10, w1, w2
101 ; CHECK-NEXT: lsl w8, w8, w9
102 ; CHECK-NEXT: orr w0, w8, w10
104 %shamt_wide = sext i8 %shamt to i32
105 %r = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt_wide)
109 define i32 @n8_extrause(i32 %x, i8 %shamt, ptr %shamt_wide_store) nounwind {
110 ; CHECK-LABEL: n8_extrause:
112 ; CHECK-NEXT: sxtb w8, w1
113 ; CHECK-NEXT: lsl w0, w0, w8
114 ; CHECK-NEXT: str w8, [x2]
116 %shamt_wide = sext i8 %shamt to i32
117 store i32 %shamt_wide, ptr %shamt_wide_store, align 4
118 %r = shl i32 %x, %shamt_wide