blob: 9062c86924dbd7b73ccf3811e47196510f1c3904 [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 Patel8aac22e2018-08-01 17:17:08 +000068; CHECK-NEXT: neg w9, w1
Sanjay Patelf94c4c82018-07-25 21:25:50 +000069; CHECK-NEXT: lsl x8, x0, x1
70; CHECK-NEXT: lsr x9, x0, x9
71; CHECK-NEXT: orr x0, x8, x9
72; CHECK-NEXT: ret
73 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %z)
74 ret i64 %f
75}
76
Sanjay Patelc71adc82018-07-16 22:59:31 +000077; Vector rotate.
78
79define <4 x i32> @rotl_v4i32(<4 x i32> %x, <4 x i32> %z) {
80; CHECK-LABEL: rotl_v4i32:
81; CHECK: // %bb.0:
82; CHECK-NEXT: movi v2.4s, #31
Sanjay Patel8aac22e2018-08-01 17:17:08 +000083; CHECK-NEXT: neg v3.4s, v1.4s
Sanjay Patelc71adc82018-07-16 22:59:31 +000084; CHECK-NEXT: and v1.16b, v1.16b, v2.16b
Sanjay Patel8aac22e2018-08-01 17:17:08 +000085; CHECK-NEXT: and v2.16b, v3.16b, v2.16b
86; CHECK-NEXT: neg v2.4s, v2.4s
87; CHECK-NEXT: ushl v1.4s, v0.4s, v1.4s
88; CHECK-NEXT: ushl v0.4s, v0.4s, v2.4s
89; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
Sanjay Patelc71adc82018-07-16 22:59:31 +000090; CHECK-NEXT: ret
91 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)
92 ret <4 x i32> %f
93}
94
95; Vector rotate by constant splat amount.
96
97define <4 x i32> @rotl_v4i32_rotl_const_shift(<4 x i32> %x) {
98; CHECK-LABEL: rotl_v4i32_rotl_const_shift:
99; CHECK: // %bb.0:
100; CHECK-NEXT: ushr v1.4s, v0.4s, #29
101; CHECK-NEXT: shl v0.4s, v0.4s, #3
102; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
103; CHECK-NEXT: ret
104 %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>)
105 ret <4 x i32> %f
106}
107
108; Repeat everything for funnel shift right.
109
110; When first 2 operands match, it's a rotate.
111
112define i8 @rotr_i8_const_shift(i8 %x) {
113; CHECK-LABEL: rotr_i8_const_shift:
114; CHECK: // %bb.0:
115; CHECK-NEXT: ubfx w8, w0, #3, #5
116; CHECK-NEXT: bfi w8, w0, #5, #27
117; CHECK-NEXT: mov w0, w8
118; CHECK-NEXT: ret
119 %f = call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 3)
120 ret i8 %f
121}
122
123define i32 @rotr_i32_const_shift(i32 %x) {
124; CHECK-LABEL: rotr_i32_const_shift:
125; CHECK: // %bb.0:
126; CHECK-NEXT: ror w0, w0, #3
127; CHECK-NEXT: ret
128 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 3)
129 ret i32 %f
130}
131
132; When first 2 operands match, it's a rotate (by variable amount).
133
134define i16 @rotr_i16(i16 %x, i16 %z) {
135; CHECK-LABEL: rotr_i16:
136; CHECK: // %bb.0:
137; CHECK-NEXT: and w8, w0, #0xffff
138; CHECK-NEXT: and w9, w1, #0xf
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000139; CHECK-NEXT: neg w10, w1
Sanjay Patelc71adc82018-07-16 22:59:31 +0000140; CHECK-NEXT: lsr w8, w8, w9
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000141; CHECK-NEXT: and w9, w10, #0xf
Sanjay Patelc71adc82018-07-16 22:59:31 +0000142; CHECK-NEXT: lsl w9, w0, w9
143; CHECK-NEXT: orr w0, w9, w8
144; CHECK-NEXT: ret
145 %f = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 %z)
146 ret i16 %f
147}
148
Sanjay Patelf94c4c82018-07-25 21:25:50 +0000149define i32 @rotr_i32(i32 %x, i32 %z) {
150; CHECK-LABEL: rotr_i32:
151; CHECK: // %bb.0:
152; CHECK-NEXT: ror w0, w0, w1
153; CHECK-NEXT: ret
154 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %z)
155 ret i32 %f
156}
157
Sanjay Patelc71adc82018-07-16 22:59:31 +0000158define i64 @rotr_i64(i64 %x, i64 %z) {
159; CHECK-LABEL: rotr_i64:
160; CHECK: // %bb.0:
Sanjay Patel215dcbf2018-07-25 21:38:30 +0000161; CHECK-NEXT: ror x0, x0, x1
Sanjay Patelc71adc82018-07-16 22:59:31 +0000162; CHECK-NEXT: ret
163 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %z)
164 ret i64 %f
165}
166
167; Vector rotate.
168
169define <4 x i32> @rotr_v4i32(<4 x i32> %x, <4 x i32> %z) {
170; CHECK-LABEL: rotr_v4i32:
171; CHECK: // %bb.0:
172; CHECK-NEXT: movi v2.4s, #31
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000173; CHECK-NEXT: neg v3.4s, v1.4s
Sanjay Patelc71adc82018-07-16 22:59:31 +0000174; CHECK-NEXT: and v1.16b, v1.16b, v2.16b
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000175; CHECK-NEXT: and v2.16b, v3.16b, v2.16b
176; CHECK-NEXT: neg v1.4s, v1.4s
177; CHECK-NEXT: ushl v1.4s, v0.4s, v1.4s
178; CHECK-NEXT: ushl v0.4s, v0.4s, v2.4s
179; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
Sanjay Patelc71adc82018-07-16 22:59:31 +0000180; CHECK-NEXT: ret
181 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)
182 ret <4 x i32> %f
183}
184
185; Vector rotate by constant splat amount.
186
187define <4 x i32> @rotr_v4i32_const_shift(<4 x i32> %x) {
188; CHECK-LABEL: rotr_v4i32_const_shift:
189; CHECK: // %bb.0:
190; CHECK-NEXT: ushr v1.4s, v0.4s, #3
191; CHECK-NEXT: shl v0.4s, v0.4s, #29
192; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
193; CHECK-NEXT: ret
194 %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>)
195 ret <4 x i32> %f
196}
197
198define i32 @rotl_i32_shift_by_bitwidth(i32 %x) {
199; CHECK-LABEL: rotl_i32_shift_by_bitwidth:
200; CHECK: // %bb.0:
201; CHECK-NEXT: ret
202 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 32)
203 ret i32 %f
204}
205
206define i32 @rotr_i32_shift_by_bitwidth(i32 %x) {
207; CHECK-LABEL: rotr_i32_shift_by_bitwidth:
208; CHECK: // %bb.0:
209; CHECK-NEXT: ret
210 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 32)
211 ret i32 %f
212}
213
214define <4 x i32> @rotl_v4i32_shift_by_bitwidth(<4 x i32> %x) {
215; CHECK-LABEL: rotl_v4i32_shift_by_bitwidth:
216; CHECK: // %bb.0:
217; CHECK-NEXT: ret
218 %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>)
219 ret <4 x i32> %f
220}
221
222define <4 x i32> @rotr_v4i32_shift_by_bitwidth(<4 x i32> %x) {
223; CHECK-LABEL: rotr_v4i32_shift_by_bitwidth:
224; CHECK: // %bb.0:
225; CHECK-NEXT: ret
226 %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>)
227 ret <4 x i32> %f
228}
229