Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / VE / Scalar / shr.ll
blob22445280b850556ae89b5c44fdc4a6327778d3bc
1 ; RUN: llc < %s -mtriple=ve | FileCheck %s
3 ;;; Test both ‘lshr’ and `ashr` instructions
4 ;;;
5 ;;; ‘lshr’ Instruction
6 ;;;
7 ;;; Syntax:
8 ;;;   <result> = lshr <ty> <op1>, <op2>         ; yields ty:result
9 ;;;   <result> = lshr exact <ty> <op1>, <op2>   ; yields ty:result
10 ;;;
11 ;;; Overview:
12 ;;;   The ‘lshr’ instruction (logical shift right) returns the first operand
13 ;;;   shifted to the right a specified number of bits with zero fill.
14 ;;;
15 ;;; Arguments:
16 ;;;   Both arguments to the ‘lshr’ instruction must be the same integer or
17 ;;;   vector of integer type. ‘op2’ is treated as an unsigned value.
18 ;;;
19 ;;; Semantics:
20 ;;;   This instruction always performs a logical shift right operation. The
21 ;;;   most significant bits of the result will be filled with zero bits after
22 ;;;   the shift. If op2 is (statically or dynamically) equal to or larger than
23 ;;;   the number of bits in op1, this instruction returns a poison value. If
24 ;;;   the arguments are vectors, each vector element of op1 is shifted by the
25 ;;;   corresponding shift amount in op2.
26 ;;;
27 ;;;   If the exact keyword is present, the result value of the lshr is a
28 ;;;   poison value if any of the bits shifted out are non-zero.
29 ;;;
30 ;;; Example:
31 ;;;   <result> = lshr i32 4, 1   ; yields i32:result = 2
32 ;;;   <result> = lshr i32 4, 2   ; yields i32:result = 1
33 ;;;   <result> = lshr i8  4, 3   ; yields i8:result = 0
34 ;;;   <result> = lshr i8 -2, 1   ; yields i8:result = 0x7F
35 ;;;   <result> = lshr i32 1, 32  ; undefined
36 ;;;   <result> = lshr <2 x i32> < i32 -2, i32 4>, < i32 1, i32 2>
37 ;;;                          ; yields: result=<2 x i32> < i32 0x7FFFFFFF, i32 1>
38 ;;;
39 ;;; ‘ashr’ Instruction
40 ;;;
41 ;;; Syntax:
42 ;;;   <result> = ashr <ty> <op1>, <op2>         ; yields ty:result
43 ;;;   <result> = ashr exact <ty> <op1>, <op2>   ; yields ty:result
44 ;;;
45 ;;; Overview:
46 ;;;   The ‘ashr’ instruction (arithmetic shift right) returns the first operand
47 ;;;   shifted to the right a specified number of bits with sign extension.
48 ;;;
49 ;;; Arguments:
50 ;;;   Both arguments to the ‘ashr’ instruction must be the same integer or
51 ;;;   vector of integer type. ‘op2’ is treated as an unsigned value.
52 ;;;
53 ;;; Semantics:
54 ;;;   This instruction always performs an arithmetic shift right operation, The
55 ;;;   most significant bits of the result will be filled with the sign bit of
56 ;;;   op1. If op2 is (statically or dynamically) equal to or larger than the
57 ;;;   number of bits in op1, this instruction returns a poison value. If the
58 ;;;   arguments are vectors, each vector element of op1 is shifted by the
59 ;;;   corresponding shift amount in op2.
60 ;;;
61 ;;;   If the exact keyword is present, the result value of the ashr is a poison
62 ;;;   value if any of the bits shifted out are non-zero.
63 ;;;
64 ;;; Example:
65 ;;;   <result> = ashr i32 4, 1   ; yields i32:result = 2
66 ;;;   <result> = ashr i32 4, 2   ; yields i32:result = 1
67 ;;;   <result> = ashr i8  4, 3   ; yields i8:result = 0
68 ;;;   <result> = ashr i8 -2, 1   ; yields i8:result = -1
69 ;;;   <result> = ashr i32 1, 32  ; undefined
70 ;;;   <result> = ashr <2 x i32> < i32 -2, i32 4>, < i32 1, i32 3>
71 ;;;                                  ; yields: result=<2 x i32> < i32 -1, i32 0>
72 ;;;
73 ;;; Note:
74 ;;;   We test only i8/i16/i32/i64/i128 and unsigned of them.
76 ; Function Attrs: norecurse nounwind readnone
77 define signext i8 @shl_i8_var(i8 signext %0, i8 signext %1) {
78 ; CHECK-LABEL: shl_i8_var:
79 ; CHECK:       # %bb.0:
80 ; CHECK-NEXT:    and %s1, %s1, (56)0
81 ; CHECK-NEXT:    sra.w.sx %s0, %s0, %s1
82 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
83 ; CHECK-NEXT:    b.l.t (, %s10)
84   %3 = sext i8 %0 to i32
85   %4 = zext i8 %1 to i32
86   %5 = ashr i32 %3, %4
87   %6 = trunc i32 %5 to i8
88   ret i8 %6
91 ; Function Attrs: norecurse nounwind readnone
92 define zeroext i8 @shl_u8_var(i8 zeroext %0, i8 zeroext %1) {
93 ; CHECK-LABEL: shl_u8_var:
94 ; CHECK:       # %bb.0:
95 ; CHECK-NEXT:    and %s0, %s0, (32)0
96 ; CHECK-NEXT:    srl %s0, %s0, %s1
97 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
98 ; CHECK-NEXT:    b.l.t (, %s10)
99   %3 = zext i8 %0 to i32
100   %4 = zext i8 %1 to i32
101   %5 = lshr i32 %3, %4
102   %6 = trunc i32 %5 to i8
103   ret i8 %6
106 ; Function Attrs: norecurse nounwind readnone
107 define signext i16 @shl_i16_var(i16 signext %0, i16 signext %1) {
108 ; CHECK-LABEL: shl_i16_var:
109 ; CHECK:       # %bb.0:
110 ; CHECK-NEXT:    and %s1, %s1, (48)0
111 ; CHECK-NEXT:    sra.w.sx %s0, %s0, %s1
112 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
113 ; CHECK-NEXT:    b.l.t (, %s10)
114   %3 = sext i16 %0 to i32
115   %4 = zext i16 %1 to i32
116   %5 = ashr i32 %3, %4
117   %6 = trunc i32 %5 to i16
118   ret i16 %6
121 ; Function Attrs: norecurse nounwind readnone
122 define zeroext i16 @shl_u16_var(i16 zeroext %0, i16 zeroext %1) {
123 ; CHECK-LABEL: shl_u16_var:
124 ; CHECK:       # %bb.0:
125 ; CHECK-NEXT:    and %s0, %s0, (32)0
126 ; CHECK-NEXT:    srl %s0, %s0, %s1
127 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
128 ; CHECK-NEXT:    b.l.t (, %s10)
129   %3 = zext i16 %0 to i32
130   %4 = zext i16 %1 to i32
131   %5 = lshr i32 %3, %4
132   %6 = trunc i32 %5 to i16
133   ret i16 %6
136 ; Function Attrs: norecurse nounwind readnone
137 define signext i32 @shl_i32_var(i32 signext %0, i32 signext %1) {
138 ; CHECK-LABEL: shl_i32_var:
139 ; CHECK:       # %bb.0:
140 ; CHECK-NEXT:    sra.w.sx %s0, %s0, %s1
141 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
142 ; CHECK-NEXT:    b.l.t (, %s10)
143   %3 = ashr i32 %0, %1
144   ret i32 %3
147 ; Function Attrs: norecurse nounwind readnone
148 define zeroext i32 @shl_u32_var(i32 zeroext %0, i32 zeroext %1) {
149 ; CHECK-LABEL: shl_u32_var:
150 ; CHECK:       # %bb.0:
151 ; CHECK-NEXT:    and %s0, %s0, (32)0
152 ; CHECK-NEXT:    srl %s0, %s0, %s1
153 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
154 ; CHECK-NEXT:    b.l.t (, %s10)
155   %3 = lshr i32 %0, %1
156   ret i32 %3
159 ; Function Attrs: norecurse nounwind readnone
160 define i64 @shl_i64_var(i64 %0, i64 %1) {
161 ; CHECK-LABEL: shl_i64_var:
162 ; CHECK:       # %bb.0:
163 ; CHECK-NEXT:    sra.l %s0, %s0, %s1
164 ; CHECK-NEXT:    b.l.t (, %s10)
165   %3 = ashr i64 %0, %1
166   ret i64 %3
169 ; Function Attrs: norecurse nounwind readnone
170 define i64 @shl_u64_var(i64 %0, i64 %1) {
171 ; CHECK-LABEL: shl_u64_var:
172 ; CHECK:       # %bb.0:
173 ; CHECK-NEXT:    srl %s0, %s0, %s1
174 ; CHECK-NEXT:    b.l.t (, %s10)
175   %3 = lshr i64 %0, %1
176   ret i64 %3
179 ; Function Attrs: norecurse nounwind readnone
180 define i128 @shl_i128_var(i128 %0, i128 %1) {
181 ; CHECK-LABEL: shl_i128_var:
182 ; CHECK:       .LBB{{[0-9]+}}_2:
183 ; CHECK-NEXT:    adds.w.sx %s2, %s2, (0)1
184 ; CHECK-NEXT:    lea %s3, __ashrti3@lo
185 ; CHECK-NEXT:    and %s3, %s3, (32)0
186 ; CHECK-NEXT:    lea.sl %s12, __ashrti3@hi(, %s3)
187 ; CHECK-NEXT:    bsic %s10, (, %s12)
188 ; CHECK-NEXT:    or %s11, 0, %s9
189   %3 = ashr i128 %0, %1
190   ret i128 %3
193 ; Function Attrs: norecurse nounwind readnone
194 define i128 @shl_u128_var(i128 %0, i128 %1) {
195 ; CHECK-LABEL: shl_u128_var:
196 ; CHECK:       .LBB{{[0-9]+}}_2:
197 ; CHECK-NEXT:    and %s2, %s2, (32)0
198 ; CHECK-NEXT:    lea %s3, __lshrti3@lo
199 ; CHECK-NEXT:    and %s3, %s3, (32)0
200 ; CHECK-NEXT:    lea.sl %s12, __lshrti3@hi(, %s3)
201 ; CHECK-NEXT:    bsic %s10, (, %s12)
202 ; CHECK-NEXT:    or %s11, 0, %s9
203   %3 = lshr i128 %0, %1
204   ret i128 %3
207 ; Function Attrs: norecurse nounwind readnone
208 define signext i8 @shl_const_i8(i8 signext %0) {
209 ; CHECK-LABEL: shl_const_i8:
210 ; CHECK:       # %bb.0:
211 ; CHECK-NEXT:    and %s0, %s0, (56)0
212 ; CHECK-NEXT:    sra.w.sx %s0, (62)1, %s0
213 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
214 ; CHECK-NEXT:    b.l.t (, %s10)
215   %2 = zext i8 %0 to i32
216   %3 = ashr i32 -4, %2
217   %4 = trunc i32 %3 to i8
218   ret i8 %4
221 ; Function Attrs: norecurse nounwind readnone
222 define zeroext i8 @shl_const_u8(i8 zeroext %0) {
223 ; CHECK-LABEL: shl_const_u8:
224 ; CHECK:       # %bb.0:
225 ; CHECK-NEXT:    sra.w.sx %s0, (62)1, %s0
226 ; CHECK-NEXT:    and %s0, %s0, (56)0
227 ; CHECK-NEXT:    b.l.t (, %s10)
228   %2 = zext i8 %0 to i32
229   %3 = ashr i32 -4, %2
230   %4 = trunc i32 %3 to i8
231   ret i8 %4
234 ; Function Attrs: norecurse nounwind readnone
235 define signext i16 @shl_const_i16(i16 signext %0) {
236 ; CHECK-LABEL: shl_const_i16:
237 ; CHECK:       # %bb.0:
238 ; CHECK-NEXT:    and %s0, %s0, (48)0
239 ; CHECK-NEXT:    sra.w.sx %s0, (62)1, %s0
240 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
241 ; CHECK-NEXT:    b.l.t (, %s10)
242   %2 = zext i16 %0 to i32
243   %3 = ashr i32 -4, %2
244   %4 = trunc i32 %3 to i16
245   ret i16 %4
248 ; Function Attrs: norecurse nounwind readnone
249 define zeroext i16 @shl_const_u16(i16 zeroext %0) {
250 ; CHECK-LABEL: shl_const_u16:
251 ; CHECK:       # %bb.0:
252 ; CHECK-NEXT:    sra.w.sx %s0, (62)1, %s0
253 ; CHECK-NEXT:    and %s0, %s0, (48)0
254 ; CHECK-NEXT:    b.l.t (, %s10)
255   %2 = zext i16 %0 to i32
256   %3 = ashr i32 -4, %2
257   %4 = trunc i32 %3 to i16
258   ret i16 %4
261 ; Function Attrs: norecurse nounwind readnone
262 define signext i32 @shl_const_i32(i32 signext %0) {
263 ; CHECK-LABEL: shl_const_i32:
264 ; CHECK:       # %bb.0:
265 ; CHECK-NEXT:    sra.w.sx %s0, (62)1, %s0
266 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
267 ; CHECK-NEXT:    b.l.t (, %s10)
268   %2 = ashr i32 -4, %0
269   ret i32 %2
272 ; Function Attrs: norecurse nounwind readnone
273 define zeroext i32 @shl_const_u32(i32 zeroext %0) {
274 ; CHECK-LABEL: shl_const_u32:
275 ; CHECK:       # %bb.0:
276 ; CHECK-NEXT:    sra.w.sx %s0, (62)1, %s0
277 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
278 ; CHECK-NEXT:    b.l.t (, %s10)
279   %2 = ashr i32 -4, %0
280   ret i32 %2
283 ; Function Attrs: norecurse nounwind readnone
284 define i64 @shl_const_i64(i64 %0) {
285 ; CHECK-LABEL: shl_const_i64:
286 ; CHECK:       # %bb.0:
287 ; CHECK-NEXT:    sra.l %s0, (62)1, %s0
288 ; CHECK-NEXT:    b.l.t (, %s10)
289   %2 = ashr i64 -4, %0
290   ret i64 %2
293 ; Function Attrs: norecurse nounwind readnone
294 define i64 @shl_const_u64(i64 %0) {
295 ; CHECK-LABEL: shl_const_u64:
296 ; CHECK:       # %bb.0:
297 ; CHECK-NEXT:    sra.l %s0, (62)1, %s0
298 ; CHECK-NEXT:    b.l.t (, %s10)
299   %2 = ashr i64 -4, %0
300   ret i64 %2
303 ; Function Attrs: norecurse nounwind readnone
304 define i128 @shl_const_i128(i128 %0) {
305 ; CHECK-LABEL: shl_const_i128:
306 ; CHECK:       .LBB{{[0-9]+}}_2:
307 ; CHECK-NEXT:    adds.w.sx %s2, %s0, (0)1
308 ; CHECK-NEXT:    lea %s0, __ashrti3@lo
309 ; CHECK-NEXT:    and %s0, %s0, (32)0
310 ; CHECK-NEXT:    lea.sl %s12, __ashrti3@hi(, %s0)
311 ; CHECK-NEXT:    or %s0, -4, (0)1
312 ; CHECK-NEXT:    or %s1, -1, (0)1
313 ; CHECK-NEXT:    bsic %s10, (, %s12)
314 ; CHECK-NEXT:    or %s11, 0, %s9
315   %2 = ashr i128 -4, %0
316   ret i128 %2
319 ; Function Attrs: norecurse nounwind readnone
320 define i128 @shl_const_u128(i128 %0) {
321 ; CHECK-LABEL: shl_const_u128:
322 ; CHECK:       .LBB{{[0-9]+}}_2:
323 ; CHECK-NEXT:    adds.w.sx %s2, %s0, (0)1
324 ; CHECK-NEXT:    lea %s0, __ashrti3@lo
325 ; CHECK-NEXT:    and %s0, %s0, (32)0
326 ; CHECK-NEXT:    lea.sl %s12, __ashrti3@hi(, %s0)
327 ; CHECK-NEXT:    or %s0, -4, (0)1
328 ; CHECK-NEXT:    or %s1, -1, (0)1
329 ; CHECK-NEXT:    bsic %s10, (, %s12)
330 ; CHECK-NEXT:    or %s11, 0, %s9
331   %2 = ashr i128 -4, %0
332   ret i128 %2
335 ; Function Attrs: norecurse nounwind readnone
336 define signext i8 @shl_i8_const(i8 signext %0) {
337 ; CHECK-LABEL: shl_i8_const:
338 ; CHECK:       # %bb.0:
339 ; CHECK-NEXT:    sra.w.sx %s0, %s0, 3
340 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
341 ; CHECK-NEXT:    b.l.t (, %s10)
342   %2 = ashr i8 %0, 3
343   ret i8 %2
346 ; Function Attrs: norecurse nounwind readnone
347 define zeroext i8 @shl_u8_const(i8 zeroext %0) {
348 ; CHECK-LABEL: shl_u8_const:
349 ; CHECK:       # %bb.0:
350 ; CHECK-NEXT:    and %s0, %s0, (32)0
351 ; CHECK-NEXT:    srl %s0, %s0, 3
352 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
353 ; CHECK-NEXT:    b.l.t (, %s10)
354   %2 = lshr i8 %0, 3
355   ret i8 %2
358 ; Function Attrs: norecurse nounwind readnone
359 define signext i16 @shl_i16_const(i16 signext %0) {
360 ; CHECK-LABEL: shl_i16_const:
361 ; CHECK:       # %bb.0:
362 ; CHECK-NEXT:    sra.w.sx %s0, %s0, 7
363 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
364 ; CHECK-NEXT:    b.l.t (, %s10)
365   %2 = ashr i16 %0, 7
366   ret i16 %2
369 ; Function Attrs: norecurse nounwind readnone
370 define zeroext i16 @shl_u16_const(i16 zeroext %0) {
371 ; CHECK-LABEL: shl_u16_const:
372 ; CHECK:       # %bb.0:
373 ; CHECK-NEXT:    and %s0, %s0, (32)0
374 ; CHECK-NEXT:    srl %s0, %s0, 7
375 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
376 ; CHECK-NEXT:    b.l.t (, %s10)
377   %2 = lshr i16 %0, 7
378   ret i16 %2
381 ; Function Attrs: norecurse nounwind readnone
382 define signext i32 @shl_i32_const(i32 signext %0) {
383 ; CHECK-LABEL: shl_i32_const:
384 ; CHECK:       # %bb.0:
385 ; CHECK-NEXT:    sra.w.sx %s0, %s0, 15
386 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
387 ; CHECK-NEXT:    b.l.t (, %s10)
388   %2 = ashr i32 %0, 15
389   ret i32 %2
392 ; Function Attrs: norecurse nounwind readnone
393 define zeroext i32 @shl_u32_const(i32 zeroext %0) {
394 ; CHECK-LABEL: shl_u32_const:
395 ; CHECK:       # %bb.0:
396 ; CHECK-NEXT:    and %s0, %s0, (32)0
397 ; CHECK-NEXT:    srl %s0, %s0, 15
398 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
399 ; CHECK-NEXT:    b.l.t (, %s10)
400   %2 = lshr i32 %0, 15
401   ret i32 %2
404 ; Function Attrs: norecurse nounwind readnone
405 define i64 @shl_i64_const(i64 %0) {
406 ; CHECK-LABEL: shl_i64_const:
407 ; CHECK:       # %bb.0:
408 ; CHECK-NEXT:    sra.l %s0, %s0, 63
409 ; CHECK-NEXT:    b.l.t (, %s10)
410   %2 = ashr i64 %0, 63
411   ret i64 %2
414 ; Function Attrs: norecurse nounwind readnone
415 define i64 @shl_u64_const(i64 %0) {
416 ; CHECK-LABEL: shl_u64_const:
417 ; CHECK:       # %bb.0:
418 ; CHECK-NEXT:    srl %s0, %s0, 63
419 ; CHECK-NEXT:    b.l.t (, %s10)
420   %2 = lshr i64 %0, 63
421   ret i64 %2
424 ; Function Attrs: norecurse nounwind readnone
425 define i128 @shl_i128_const(i128 %0) {
426 ; CHECK-LABEL: shl_i128_const:
427 ; CHECK:       # %bb.0:
428 ; CHECK-NEXT:    sra.l %s0, %s1, 63
429 ; CHECK-NEXT:    or %s1, 0, %s0
430 ; CHECK-NEXT:    b.l.t (, %s10)
431   %2 = ashr i128 %0, 127
432   ret i128 %2
435 ; Function Attrs: norecurse nounwind readnone
436 define i128 @shl_u128_const(i128 %0) {
437 ; CHECK-LABEL: shl_u128_const:
438 ; CHECK:       # %bb.0:
439 ; CHECK-NEXT:    srl %s0, %s1, 63
440 ; CHECK-NEXT:    or %s1, 0, (0)1
441 ; CHECK-NEXT:    b.l.t (, %s10)
442   %2 = lshr i128 %0, 127
443   ret i128 %2