blob: 4d238282a6722be83d011239d924a65be0f70fcb [file] [log] [blame]
Sanjay Patelc71adc82018-07-16 22:59:31 +00001; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
3
4declare i8 @llvm.fshl.i8(i8, i8, i8)
5declare i16 @llvm.fshl.i16(i16, i16, i16)
6declare i32 @llvm.fshl.i32(i32, i32, i32)
7declare i64 @llvm.fshl.i64(i64, i64, i64)
8declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
9
10declare i8 @llvm.fshr.i8(i8, i8, i8)
11declare i16 @llvm.fshr.i16(i16, i16, i16)
12declare i32 @llvm.fshr.i32(i32, i32, i32)
13declare i64 @llvm.fshr.i64(i64, i64, i64)
14declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
15
16; When first 2 operands match, it's a rotate.
17
18define i8 @rotl_i8_const_shift(i8 %x) {
19; CHECK-LABEL: rotl_i8_const_shift:
20; CHECK: // %bb.0:
21; CHECK-NEXT: ubfx w8, w0, #5, #3
22; CHECK-NEXT: bfi w8, w0, #3, #29
23; CHECK-NEXT: mov w0, w8
24; CHECK-NEXT: ret
25 %f = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
26 ret i8 %f
27}
28
29define i64 @rotl_i64_const_shift(i64 %x) {
30; CHECK-LABEL: rotl_i64_const_shift:
31; CHECK: // %bb.0:
32; CHECK-NEXT: ror x0, x0, #61
33; CHECK-NEXT: ret
34 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 3)
35 ret i64 %f
36}
37
38; When first 2 operands match, it's a rotate (by variable amount).
39
40define i16 @rotl_i16(i16 %x, i16 %z) {
41; CHECK-LABEL: rotl_i16:
42; CHECK: // %bb.0:
Sanjay Patel8aac22e2018-08-01 17:17:08 +000043; CHECK-NEXT: neg w10, w1
Sanjay Patelc71adc82018-07-16 22:59:31 +000044; CHECK-NEXT: and w8, w0, #0xffff
45; CHECK-NEXT: and w9, w1, #0xf
46; CHECK-NEXT: and w10, w10, #0xf
47; CHECK-NEXT: lsl w9, w0, w9
48; CHECK-NEXT: lsr w8, w8, w10
49; CHECK-NEXT: orr w0, w9, w8
50; CHECK-NEXT: ret
51 %f = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 %z)
52 ret i16 %f
53}
54
55define i32 @rotl_i32(i32 %x, i32 %z) {
56; CHECK-LABEL: rotl_i32:
57; CHECK: // %bb.0:
Sanjay Patel8aac22e2018-08-01 17:17:08 +000058; CHECK-NEXT: neg w8, w1
Sanjay Patelc71adc82018-07-16 22:59:31 +000059; CHECK-NEXT: ror w0, w0, w8
60; CHECK-NEXT: ret
61 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %z)
62 ret i32 %f
63}
64
Sanjay Patelf94c4c82018-07-25 21:25:50 +000065define i64 @rotl_i64(i64 %x, i64 %z) {
66; CHECK-LABEL: rotl_i64:
67; CHECK: // %bb.0:
Sanjay Patel15d15012018-08-09 17:26:22 +000068; CHECK-NEXT: neg x8, x1
69; CHECK-NEXT: ror x0, x0, x8
Sanjay Patelf94c4c82018-07-25 21:25:50 +000070; CHECK-NEXT: ret
71 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %z)
72 ret i64 %f
73}
74
Sanjay Patelc71adc82018-07-16 22:59:31 +000075; Vector rotate.
76
77define <4 x i32> @rotl_v4i32(<4 x i32> %x, <4 x i32> %z) {
78; CHECK-LABEL: rotl_v4i32:
79; CHECK: // %bb.0:
80; CHECK-NEXT: movi v2.4s, #31
Sanjay Patel8aac22e2018-08-01 17:17:08 +000081; CHECK-NEXT: neg v3.4s, v1.4s
Sanjay Patelc71adc82018-07-16 22:59:31 +000082; CHECK-NEXT: and v1.16b, v1.16b, v2.16b
Sanjay Patel8aac22e2018-08-01 17:17:08 +000083; CHECK-NEXT: and v2.16b, v3.16b, v2.16b
84; CHECK-NEXT: neg v2.4s, v2.4s
85; CHECK-NEXT: ushl v1.4s, v0.4s, v1.4s
86; CHECK-NEXT: ushl v0.4s, v0.4s, v2.4s
87; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
Sanjay Patelc71adc82018-07-16 22:59:31 +000088; CHECK-NEXT: ret
89 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)
90 ret <4 x i32> %f
91}
92
93; Vector rotate by constant splat amount.
94
95define <4 x i32> @rotl_v4i32_rotl_const_shift(<4 x i32> %x) {
96; CHECK-LABEL: rotl_v4i32_rotl_const_shift:
97; CHECK: // %bb.0:
98; CHECK-NEXT: ushr v1.4s, v0.4s, #29
99; CHECK-NEXT: shl v0.4s, v0.4s, #3
100; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
101; CHECK-NEXT: ret
102 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 3, i32 3, i32 3, i32 3>)
103 ret <4 x i32> %f
104}
105
106; Repeat everything for funnel shift right.
107
108; When first 2 operands match, it's a rotate.
109
110define i8 @rotr_i8_const_shift(i8 %x) {
111; CHECK-LABEL: rotr_i8_const_shift:
112; CHECK: // %bb.0:
113; CHECK-NEXT: ubfx w8, w0, #3, #5
114; CHECK-NEXT: bfi w8, w0, #5, #27
115; CHECK-NEXT: mov w0, w8
116; CHECK-NEXT: ret
117 %f = call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 3)
118 ret i8 %f
119}
120
121define i32 @rotr_i32_const_shift(i32 %x) {
122; CHECK-LABEL: rotr_i32_const_shift:
123; CHECK: // %bb.0:
124; CHECK-NEXT: ror w0, w0, #3
125; CHECK-NEXT: ret
126 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 3)
127 ret i32 %f
128}
129
130; When first 2 operands match, it's a rotate (by variable amount).
131
132define i16 @rotr_i16(i16 %x, i16 %z) {
133; CHECK-LABEL: rotr_i16:
134; CHECK: // %bb.0:
135; CHECK-NEXT: and w8, w0, #0xffff
136; CHECK-NEXT: and w9, w1, #0xf
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000137; CHECK-NEXT: neg w10, w1
Sanjay Patelc71adc82018-07-16 22:59:31 +0000138; CHECK-NEXT: lsr w8, w8, w9
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000139; CHECK-NEXT: and w9, w10, #0xf
Sanjay Patelc71adc82018-07-16 22:59:31 +0000140; CHECK-NEXT: lsl w9, w0, w9
141; CHECK-NEXT: orr w0, w9, w8
142; CHECK-NEXT: ret
143 %f = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 %z)
144 ret i16 %f
145}
146
Sanjay Patelf94c4c82018-07-25 21:25:50 +0000147define i32 @rotr_i32(i32 %x, i32 %z) {
148; CHECK-LABEL: rotr_i32:
149; CHECK: // %bb.0:
150; CHECK-NEXT: ror w0, w0, w1
151; CHECK-NEXT: ret
152 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %z)
153 ret i32 %f
154}
155
Sanjay Patelc71adc82018-07-16 22:59:31 +0000156define i64 @rotr_i64(i64 %x, i64 %z) {
157; CHECK-LABEL: rotr_i64:
158; CHECK: // %bb.0:
Sanjay Patel215dcbf2018-07-25 21:38:30 +0000159; CHECK-NEXT: ror x0, x0, x1
Sanjay Patelc71adc82018-07-16 22:59:31 +0000160; CHECK-NEXT: ret
161 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %z)
162 ret i64 %f
163}
164
165; Vector rotate.
166
167define <4 x i32> @rotr_v4i32(<4 x i32> %x, <4 x i32> %z) {
168; CHECK-LABEL: rotr_v4i32:
169; CHECK: // %bb.0:
170; CHECK-NEXT: movi v2.4s, #31
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000171; CHECK-NEXT: neg v3.4s, v1.4s
Sanjay Patelc71adc82018-07-16 22:59:31 +0000172; CHECK-NEXT: and v1.16b, v1.16b, v2.16b
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000173; CHECK-NEXT: and v2.16b, v3.16b, v2.16b
174; CHECK-NEXT: neg v1.4s, v1.4s
175; CHECK-NEXT: ushl v1.4s, v0.4s, v1.4s
176; CHECK-NEXT: ushl v0.4s, v0.4s, v2.4s
177; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
Sanjay Patelc71adc82018-07-16 22:59:31 +0000178; CHECK-NEXT: ret
179 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)
180 ret <4 x i32> %f
181}
182
183; Vector rotate by constant splat amount.
184
185define <4 x i32> @rotr_v4i32_const_shift(<4 x i32> %x) {
186; CHECK-LABEL: rotr_v4i32_const_shift:
187; CHECK: // %bb.0:
188; CHECK-NEXT: ushr v1.4s, v0.4s, #3
189; CHECK-NEXT: shl v0.4s, v0.4s, #29
190; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
191; CHECK-NEXT: ret
192 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 3, i32 3, i32 3, i32 3>)
193 ret <4 x i32> %f
194}
195
196define i32 @rotl_i32_shift_by_bitwidth(i32 %x) {
197; CHECK-LABEL: rotl_i32_shift_by_bitwidth:
198; CHECK: // %bb.0:
199; CHECK-NEXT: ret
200 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 32)
201 ret i32 %f
202}
203
204define i32 @rotr_i32_shift_by_bitwidth(i32 %x) {
205; CHECK-LABEL: rotr_i32_shift_by_bitwidth:
206; CHECK: // %bb.0:
207; CHECK-NEXT: ret
208 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 32)
209 ret i32 %f
210}
211
212define <4 x i32> @rotl_v4i32_shift_by_bitwidth(<4 x i32> %x) {
213; CHECK-LABEL: rotl_v4i32_shift_by_bitwidth:
214; CHECK: // %bb.0:
215; CHECK-NEXT: ret
216 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
217 ret <4 x i32> %f
218}
219
220define <4 x i32> @rotr_v4i32_shift_by_bitwidth(<4 x i32> %x) {
221; CHECK-LABEL: rotr_v4i32_shift_by_bitwidth:
222; CHECK: // %bb.0:
223; CHECK-NEXT: ret
224 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
225 ret <4 x i32> %f
226}
227