Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / VE / Scalar / shl.ll
blobbe0484bef791704761d18329810d8dfdb7d0a401
1 ; RUN: llc < %s -mtriple=ve | FileCheck %s
3 ;;; Test ‘shl’ instruction
4 ;;;
5 ;;; Syntax:
6 ;;;   <result> = shl <ty> <op1>, <op2>           ; yields ty:result
7 ;;;   <result> = shl nuw <ty> <op1>, <op2>       ; yields ty:result
8 ;;;   <result> = shl nsw <ty> <op1>, <op2>       ; yields ty:result
9 ;;;   <result> = shl nuw nsw <ty> <op1>, <op2>   ; yields ty:result
10 ;;;
11 ;;; Overview:
12 ;;;   The ‘shl’ instruction returns the first operand shifted to the left
13 ;;;   a specified number of bits.
14 ;;;
15 ;;; Arguments:
16 ;;;   Both arguments to the ‘shl’ instruction must be the same integer or
17 ;;;   vector of integer type. ‘op2’ is treated as an unsigned value.
18 ;;;
19 ;;; Semantics:
20 ;;;   The value produced is op1 * 2op2 mod 2n, where n is the width of the
21 ;;;   result. If op2 is (statically or dynamically) equal to or larger than
22 ;;;   the number of bits in op1, this instruction returns a poison value.
23 ;;;   If the arguments are vectors, each vector element of op1 is shifted by
24 ;;;   the corresponding shift amount in op2.
25 ;;;
26 ;;;   If the nuw keyword is present, then the shift produces a poison value
27 ;;;   if it shifts out any non-zero bits. If the nsw keyword is present,
28 ;;;   then the shift produces a poison value if it shifts out any bits that
29 ;;;   disagree with the resultant sign bit.
30 ;;;
31 ;;; Example:
32 ;;;   <result> = shl i32 4, %var   ; yields i32: 4 << %var
33 ;;;   <result> = shl i32 4, 2      ; yields i32: 16
34 ;;;   <result> = shl i32 1, 10     ; yields i32: 1024
35 ;;;   <result> = shl i32 1, 32     ; undefined
36 ;;;   <result> = shl <2 x i32> < i32 1, i32 1>, < i32 1, i32 2>
37 ;;;                                ; yields: result=<2 x i32> < i32 2, i32 4>
38 ;;;
39 ;;; Note:
40 ;;;   We test only i8/i16/i32/i64/i128 and unsigned of them.
42 ; Function Attrs: norecurse nounwind readnone
43 define signext i8 @shl_i8_var(i8 signext %0, i8 signext %1) {
44 ; CHECK-LABEL: shl_i8_var:
45 ; CHECK:       # %bb.0:
46 ; CHECK-NEXT:    and %s1, %s1, (56)0
47 ; CHECK-NEXT:    sla.w.sx %s0, %s0, %s1
48 ; CHECK-NEXT:    sll %s0, %s0, 56
49 ; CHECK-NEXT:    sra.l %s0, %s0, 56
50 ; CHECK-NEXT:    b.l.t (, %s10)
51   %3 = sext i8 %0 to i32
52   %4 = zext i8 %1 to i32
53   %5 = shl i32 %3, %4
54   %6 = trunc i32 %5 to i8
55   ret i8 %6
58 ; Function Attrs: norecurse nounwind readnone
59 define zeroext i8 @shl_u8_var(i8 zeroext %0, i8 zeroext %1) {
60 ; CHECK-LABEL: shl_u8_var:
61 ; CHECK:       # %bb.0:
62 ; CHECK-NEXT:    sla.w.sx %s0, %s0, %s1
63 ; CHECK-NEXT:    and %s0, %s0, (56)0
64 ; CHECK-NEXT:    b.l.t (, %s10)
65   %3 = zext i8 %0 to i32
66   %4 = zext i8 %1 to i32
67   %5 = shl i32 %3, %4
68   %6 = trunc i32 %5 to i8
69   ret i8 %6
72 ; Function Attrs: norecurse nounwind readnone
73 define signext i16 @shl_i16_var(i16 signext %0, i16 signext %1) {
74 ; CHECK-LABEL: shl_i16_var:
75 ; CHECK:       # %bb.0:
76 ; CHECK-NEXT:    and %s1, %s1, (48)0
77 ; CHECK-NEXT:    sla.w.sx %s0, %s0, %s1
78 ; CHECK-NEXT:    sll %s0, %s0, 48
79 ; CHECK-NEXT:    sra.l %s0, %s0, 48
80 ; CHECK-NEXT:    b.l.t (, %s10)
81   %3 = sext i16 %0 to i32
82   %4 = zext i16 %1 to i32
83   %5 = shl i32 %3, %4
84   %6 = trunc i32 %5 to i16
85   ret i16 %6
88 ; Function Attrs: norecurse nounwind readnone
89 define zeroext i16 @shl_u16_var(i16 zeroext %0, i16 zeroext %1) {
90 ; CHECK-LABEL: shl_u16_var:
91 ; CHECK:       # %bb.0:
92 ; CHECK-NEXT:    sla.w.sx %s0, %s0, %s1
93 ; CHECK-NEXT:    and %s0, %s0, (48)0
94 ; CHECK-NEXT:    b.l.t (, %s10)
95   %3 = zext i16 %0 to i32
96   %4 = zext i16 %1 to i32
97   %5 = shl i32 %3, %4
98   %6 = trunc i32 %5 to i16
99   ret i16 %6
102 ; Function Attrs: norecurse nounwind readnone
103 define signext i32 @shl_i32_var(i32 signext %0, i32 signext %1) {
104 ; CHECK-LABEL: shl_i32_var:
105 ; CHECK:       # %bb.0:
106 ; CHECK-NEXT:    sla.w.sx %s0, %s0, %s1
107 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
108 ; CHECK-NEXT:    b.l.t (, %s10)
109   %3 = shl i32 %0, %1
110   ret i32 %3
113 ; Function Attrs: norecurse nounwind readnone
114 define zeroext i32 @shl_u32_var(i32 zeroext %0, i32 zeroext %1) {
115 ; CHECK-LABEL: shl_u32_var:
116 ; CHECK:       # %bb.0:
117 ; CHECK-NEXT:    sla.w.sx %s0, %s0, %s1
118 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
119 ; CHECK-NEXT:    b.l.t (, %s10)
120   %3 = shl i32 %0, %1
121   ret i32 %3
124 ; Function Attrs: norecurse nounwind readnone
125 define i64 @shl_i64_var(i64 %0, i64 %1) {
126 ; CHECK-LABEL: shl_i64_var:
127 ; CHECK:       # %bb.0:
128 ; CHECK-NEXT:    sll %s0, %s0, %s1
129 ; CHECK-NEXT:    b.l.t (, %s10)
130   %3 = shl i64 %0, %1
131   ret i64 %3
134 ; Function Attrs: norecurse nounwind readnone
135 define i64 @shl_u64_var(i64 %0, i64 %1) {
136 ; CHECK-LABEL: shl_u64_var:
137 ; CHECK:       # %bb.0:
138 ; CHECK-NEXT:    sll %s0, %s0, %s1
139 ; CHECK-NEXT:    b.l.t (, %s10)
140   %3 = shl i64 %0, %1
141   ret i64 %3
144 ; Function Attrs: norecurse nounwind readnone
145 define i128 @shl_i128_var(i128 %0, i128 %1) {
146 ; CHECK-LABEL: shl_i128_var:
147 ; CHECK:       .LBB{{[0-9]+}}_2:
148 ; CHECK-NEXT:    and %s2, %s2, (32)0
149 ; CHECK-NEXT:    lea %s3, __ashlti3@lo
150 ; CHECK-NEXT:    and %s3, %s3, (32)0
151 ; CHECK-NEXT:    lea.sl %s12, __ashlti3@hi(, %s3)
152 ; CHECK-NEXT:    bsic %s10, (, %s12)
153 ; CHECK-NEXT:    or %s11, 0, %s9
154   %3 = shl i128 %0, %1
155   ret i128 %3
158 ; Function Attrs: norecurse nounwind readnone
159 define i128 @shl_u128_var(i128 %0, i128 %1) {
160 ; CHECK-LABEL: shl_u128_var:
161 ; CHECK:       .LBB{{[0-9]+}}_2:
162 ; CHECK-NEXT:    and %s2, %s2, (32)0
163 ; CHECK-NEXT:    lea %s3, __ashlti3@lo
164 ; CHECK-NEXT:    and %s3, %s3, (32)0
165 ; CHECK-NEXT:    lea.sl %s12, __ashlti3@hi(, %s3)
166 ; CHECK-NEXT:    bsic %s10, (, %s12)
167 ; CHECK-NEXT:    or %s11, 0, %s9
168   %3 = shl i128 %0, %1
169   ret i128 %3
172 ; Function Attrs: norecurse nounwind readnone
173 define signext i8 @shl_const_i8(i8 signext %0) {
174 ; CHECK-LABEL: shl_const_i8:
175 ; CHECK:       # %bb.0:
176 ; CHECK-NEXT:    and %s0, %s0, (56)0
177 ; CHECK-NEXT:    sla.w.sx %s0, (62)1, %s0
178 ; CHECK-NEXT:    sll %s0, %s0, 56
179 ; CHECK-NEXT:    sra.l %s0, %s0, 56
180 ; CHECK-NEXT:    b.l.t (, %s10)
181   %2 = zext i8 %0 to i32
182   %3 = shl i32 -4, %2
183   %4 = trunc i32 %3 to i8
184   ret i8 %4
187 ; Function Attrs: norecurse nounwind readnone
188 define zeroext i8 @shl_const_u8(i8 zeroext %0) {
189 ; CHECK-LABEL: shl_const_u8:
190 ; CHECK:       # %bb.0:
191 ; CHECK-NEXT:    sla.w.sx %s0, (62)1, %s0
192 ; CHECK-NEXT:    lea %s1, 252
193 ; CHECK-NEXT:    and %s0, %s0, %s1
194 ; CHECK-NEXT:    b.l.t (, %s10)
195   %2 = zext i8 %0 to i32
196   %3 = shl i32 -4, %2
197   %4 = trunc i32 %3 to i8
198   ret i8 %4
201 ; Function Attrs: norecurse nounwind readnone
202 define signext i16 @shl_const_i16(i16 signext %0) {
203 ; CHECK-LABEL: shl_const_i16:
204 ; CHECK:       # %bb.0:
205 ; CHECK-NEXT:    and %s0, %s0, (48)0
206 ; CHECK-NEXT:    sla.w.sx %s0, (62)1, %s0
207 ; CHECK-NEXT:    sll %s0, %s0, 48
208 ; CHECK-NEXT:    sra.l %s0, %s0, 48
209 ; CHECK-NEXT:    b.l.t (, %s10)
210   %2 = zext i16 %0 to i32
211   %3 = shl i32 -4, %2
212   %4 = trunc i32 %3 to i16
213   ret i16 %4
216 ; Function Attrs: norecurse nounwind readnone
217 define zeroext i16 @shl_const_u16(i16 zeroext %0) {
218 ; CHECK-LABEL: shl_const_u16:
219 ; CHECK:       # %bb.0:
220 ; CHECK-NEXT:    sla.w.sx %s0, (62)1, %s0
221 ; CHECK-NEXT:    lea %s1, 65532
222 ; CHECK-NEXT:    and %s0, %s0, %s1
223 ; CHECK-NEXT:    b.l.t (, %s10)
224   %2 = zext i16 %0 to i32
225   %3 = shl i32 -4, %2
226   %4 = trunc i32 %3 to i16
227   ret i16 %4
230 ; Function Attrs: norecurse nounwind readnone
231 define signext i32 @shl_const_i32(i32 signext %0) {
232 ; CHECK-LABEL: shl_const_i32:
233 ; CHECK:       # %bb.0:
234 ; CHECK-NEXT:    sla.w.sx %s0, (62)1, %s0
235 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
236 ; CHECK-NEXT:    b.l.t (, %s10)
237   %2 = shl i32 -4, %0
238   ret i32 %2
241 ; Function Attrs: norecurse nounwind readnone
242 define zeroext i32 @shl_const_u32(i32 zeroext %0) {
243 ; CHECK-LABEL: shl_const_u32:
244 ; CHECK:       # %bb.0:
245 ; CHECK-NEXT:    sla.w.sx %s0, (62)1, %s0
246 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
247 ; CHECK-NEXT:    b.l.t (, %s10)
248   %2 = shl i32 -4, %0
249   ret i32 %2
252 ; Function Attrs: norecurse nounwind readnone
253 define i64 @shl_const_i64(i64 %0) {
254 ; CHECK-LABEL: shl_const_i64:
255 ; CHECK:       # %bb.0:
256 ; CHECK-NEXT:    sll %s0, (62)1, %s0
257 ; CHECK-NEXT:    b.l.t (, %s10)
258   %2 = shl i64 -4, %0
259   ret i64 %2
262 ; Function Attrs: norecurse nounwind readnone
263 define i64 @shl_const_u64(i64 %0) {
264 ; CHECK-LABEL: shl_const_u64:
265 ; CHECK:       # %bb.0:
266 ; CHECK-NEXT:    sll %s0, (62)1, %s0
267 ; CHECK-NEXT:    b.l.t (, %s10)
268   %2 = shl i64 -4, %0
269   ret i64 %2
272 ; Function Attrs: norecurse nounwind readnone
273 define i128 @shl_const_i128(i128 %0) {
274 ; CHECK-LABEL: shl_const_i128:
275 ; CHECK:       .LBB{{[0-9]+}}_2:
276 ; CHECK-NEXT:    and %s2, %s0, (32)0
277 ; CHECK-NEXT:    lea %s0, __ashlti3@lo
278 ; CHECK-NEXT:    and %s0, %s0, (32)0
279 ; CHECK-NEXT:    lea.sl %s12, __ashlti3@hi(, %s0)
280 ; CHECK-NEXT:    or %s0, -4, (0)1
281 ; CHECK-NEXT:    or %s1, -1, (0)1
282 ; CHECK-NEXT:    bsic %s10, (, %s12)
283 ; CHECK-NEXT:    or %s11, 0, %s9
284   %2 = shl i128 -4, %0
285   ret i128 %2
288 ; Function Attrs: norecurse nounwind readnone
289 define i128 @shl_const_u128(i128 %0) {
290 ; CHECK-LABEL: shl_const_u128:
291 ; CHECK:       .LBB{{[0-9]+}}_2:
292 ; CHECK-NEXT:    and %s2, %s0, (32)0
293 ; CHECK-NEXT:    lea %s0, __ashlti3@lo
294 ; CHECK-NEXT:    and %s0, %s0, (32)0
295 ; CHECK-NEXT:    lea.sl %s12, __ashlti3@hi(, %s0)
296 ; CHECK-NEXT:    or %s0, -4, (0)1
297 ; CHECK-NEXT:    or %s1, -1, (0)1
298 ; CHECK-NEXT:    bsic %s10, (, %s12)
299 ; CHECK-NEXT:    or %s11, 0, %s9
300   %2 = shl i128 -4, %0
301   ret i128 %2
304 ; Function Attrs: norecurse nounwind readnone
305 define signext i8 @shl_i8_const(i8 signext %0) {
306 ; CHECK-LABEL: shl_i8_const:
307 ; CHECK:       # %bb.0:
308 ; CHECK-NEXT:    sla.w.sx %s0, %s0, 3
309 ; CHECK-NEXT:    sll %s0, %s0, 56
310 ; CHECK-NEXT:    sra.l %s0, %s0, 56
311 ; CHECK-NEXT:    b.l.t (, %s10)
312   %2 = shl i8 %0, 3
313   ret i8 %2
316 ; Function Attrs: norecurse nounwind readnone
317 define zeroext i8 @shl_u8_const(i8 zeroext %0) {
318 ; CHECK-LABEL: shl_u8_const:
319 ; CHECK:       # %bb.0:
320 ; CHECK-NEXT:    sla.w.sx %s0, %s0, 3
321 ; CHECK-NEXT:    lea %s1, 248
322 ; CHECK-NEXT:    and %s0, %s0, %s1
323 ; CHECK-NEXT:    b.l.t (, %s10)
324   %2 = shl i8 %0, 3
325   ret i8 %2
328 ; Function Attrs: norecurse nounwind readnone
329 define signext i16 @shl_i16_const(i16 signext %0) {
330 ; CHECK-LABEL: shl_i16_const:
331 ; CHECK:       # %bb.0:
332 ; CHECK-NEXT:    sla.w.sx %s0, %s0, 7
333 ; CHECK-NEXT:    sll %s0, %s0, 48
334 ; CHECK-NEXT:    sra.l %s0, %s0, 48
335 ; CHECK-NEXT:    b.l.t (, %s10)
336   %2 = shl i16 %0, 7
337   ret i16 %2
340 ; Function Attrs: norecurse nounwind readnone
341 define zeroext i16 @shl_u16_const(i16 zeroext %0) {
342 ; CHECK-LABEL: shl_u16_const:
343 ; CHECK:       # %bb.0:
344 ; CHECK-NEXT:    sla.w.sx %s0, %s0, 7
345 ; CHECK-NEXT:    lea %s1, 65408
346 ; CHECK-NEXT:    and %s0, %s0, %s1
347 ; CHECK-NEXT:    b.l.t (, %s10)
348   %2 = shl i16 %0, 7
349   ret i16 %2
352 ; Function Attrs: norecurse nounwind readnone
353 define signext i32 @shl_i32_const(i32 signext %0) {
354 ; CHECK-LABEL: shl_i32_const:
355 ; CHECK:       # %bb.0:
356 ; CHECK-NEXT:    sla.w.sx %s0, %s0, 15
357 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
358 ; CHECK-NEXT:    b.l.t (, %s10)
359   %2 = shl i32 %0, 15
360   ret i32 %2
363 ; Function Attrs: norecurse nounwind readnone
364 define zeroext i32 @shl_u32_const(i32 zeroext %0) {
365 ; CHECK-LABEL: shl_u32_const:
366 ; CHECK:       # %bb.0:
367 ; CHECK-NEXT:    sla.w.sx %s0, %s0, 15
368 ; CHECK-NEXT:    adds.w.zx %s0, %s0, (0)1
369 ; CHECK-NEXT:    b.l.t (, %s10)
370   %2 = shl i32 %0, 15
371   ret i32 %2
374 ; Function Attrs: norecurse nounwind readnone
375 define i64 @shl_i64_const(i64 %0) {
376 ; CHECK-LABEL: shl_i64_const:
377 ; CHECK:       # %bb.0:
378 ; CHECK-NEXT:    sll %s0, %s0, 63
379 ; CHECK-NEXT:    b.l.t (, %s10)
380   %2 = shl i64 %0, 63
381   ret i64 %2
384 ; Function Attrs: norecurse nounwind readnone
385 define i64 @shl_u64_const(i64 %0) {
386 ; CHECK-LABEL: shl_u64_const:
387 ; CHECK:       # %bb.0:
388 ; CHECK-NEXT:    sll %s0, %s0, 63
389 ; CHECK-NEXT:    b.l.t (, %s10)
390   %2 = shl i64 %0, 63
391   ret i64 %2
394 ; Function Attrs: norecurse nounwind readnone
395 define i128 @shl_i128_const(i128 %0) {
396 ; CHECK-LABEL: shl_i128_const:
397 ; CHECK:       # %bb.0:
398 ; CHECK-NEXT:    sll %s1, %s0, 63
399 ; CHECK-NEXT:    or %s0, 0, (0)1
400 ; CHECK-NEXT:    b.l.t (, %s10)
401   %2 = shl i128 %0, 127
402   ret i128 %2
405 ; Function Attrs: norecurse nounwind readnone
406 define i128 @shl_u128_const(i128 %0) {
407 ; CHECK-LABEL: shl_u128_const:
408 ; CHECK:       # %bb.0:
409 ; CHECK-NEXT:    sll %s1, %s0, 63
410 ; CHECK-NEXT:    or %s0, 0, (0)1
411 ; CHECK-NEXT:    b.l.t (, %s10)
412   %2 = shl i128 %0, 127
413   ret i128 %2