1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc --mtriple=loongarch32 -mattr=+d < %s | FileCheck %s --check-prefix=LA32
3 ; RUN: llc --mtriple=loongarch64 -mattr=+d < %s | FileCheck %s --check-prefix=LA64
5 ;; Exercise the 'and' LLVM IR: https://llvm.org/docs/LangRef.html#and-instruction
7 define i1 @and_i1(i1 %a, i1 %b) {
9 ; LA32: # %bb.0: # %entry
10 ; LA32-NEXT: and $a0, $a0, $a1
14 ; LA64: # %bb.0: # %entry
15 ; LA64-NEXT: and $a0, $a0, $a1
22 define i8 @and_i8(i8 %a, i8 %b) {
24 ; LA32: # %bb.0: # %entry
25 ; LA32-NEXT: and $a0, $a0, $a1
29 ; LA64: # %bb.0: # %entry
30 ; LA64-NEXT: and $a0, $a0, $a1
37 define i16 @and_i16(i16 %a, i16 %b) {
38 ; LA32-LABEL: and_i16:
39 ; LA32: # %bb.0: # %entry
40 ; LA32-NEXT: and $a0, $a0, $a1
43 ; LA64-LABEL: and_i16:
44 ; LA64: # %bb.0: # %entry
45 ; LA64-NEXT: and $a0, $a0, $a1
52 define i32 @and_i32(i32 %a, i32 %b) {
53 ; LA32-LABEL: and_i32:
54 ; LA32: # %bb.0: # %entry
55 ; LA32-NEXT: and $a0, $a0, $a1
58 ; LA64-LABEL: and_i32:
59 ; LA64: # %bb.0: # %entry
60 ; LA64-NEXT: and $a0, $a0, $a1
67 define i64 @and_i64(i64 %a, i64 %b) {
68 ; LA32-LABEL: and_i64:
69 ; LA32: # %bb.0: # %entry
70 ; LA32-NEXT: and $a0, $a0, $a2
71 ; LA32-NEXT: and $a1, $a1, $a3
74 ; LA64-LABEL: and_i64:
75 ; LA64: # %bb.0: # %entry
76 ; LA64-NEXT: and $a0, $a0, $a1
83 define i1 @and_i1_0(i1 %b) {
84 ; LA32-LABEL: and_i1_0:
85 ; LA32: # %bb.0: # %entry
86 ; LA32-NEXT: move $a0, $zero
89 ; LA64-LABEL: and_i1_0:
90 ; LA64: # %bb.0: # %entry
91 ; LA64-NEXT: move $a0, $zero
98 define i1 @and_i1_5(i1 %b) {
99 ; LA32-LABEL: and_i1_5:
100 ; LA32: # %bb.0: # %entry
103 ; LA64-LABEL: and_i1_5:
104 ; LA64: # %bb.0: # %entry
111 define i8 @and_i8_5(i8 %b) {
112 ; LA32-LABEL: and_i8_5:
113 ; LA32: # %bb.0: # %entry
114 ; LA32-NEXT: andi $a0, $a0, 5
117 ; LA64-LABEL: and_i8_5:
118 ; LA64: # %bb.0: # %entry
119 ; LA64-NEXT: andi $a0, $a0, 5
126 define i8 @and_i8_257(i8 %b) {
127 ; LA32-LABEL: and_i8_257:
128 ; LA32: # %bb.0: # %entry
129 ; LA32-NEXT: andi $a0, $a0, 1
132 ; LA64-LABEL: and_i8_257:
133 ; LA64: # %bb.0: # %entry
134 ; LA64-NEXT: andi $a0, $a0, 1
141 define i16 @and_i16_5(i16 %b) {
142 ; LA32-LABEL: and_i16_5:
143 ; LA32: # %bb.0: # %entry
144 ; LA32-NEXT: andi $a0, $a0, 5
147 ; LA64-LABEL: and_i16_5:
148 ; LA64: # %bb.0: # %entry
149 ; LA64-NEXT: andi $a0, $a0, 5
156 define i16 @and_i16_0x1000(i16 %b) {
157 ; LA32-LABEL: and_i16_0x1000:
158 ; LA32: # %bb.0: # %entry
159 ; LA32-NEXT: lu12i.w $a1, 1
160 ; LA32-NEXT: and $a0, $a0, $a1
163 ; LA64-LABEL: and_i16_0x1000:
164 ; LA64: # %bb.0: # %entry
165 ; LA64-NEXT: lu12i.w $a1, 1
166 ; LA64-NEXT: and $a0, $a0, $a1
169 %r = and i16 4096, %b
173 define i16 @and_i16_0x10001(i16 %b) {
174 ; LA32-LABEL: and_i16_0x10001:
175 ; LA32: # %bb.0: # %entry
176 ; LA32-NEXT: andi $a0, $a0, 1
179 ; LA64-LABEL: and_i16_0x10001:
180 ; LA64: # %bb.0: # %entry
181 ; LA64-NEXT: andi $a0, $a0, 1
184 %r = and i16 65537, %b
188 define i32 @and_i32_5(i32 %b) {
189 ; LA32-LABEL: and_i32_5:
190 ; LA32: # %bb.0: # %entry
191 ; LA32-NEXT: andi $a0, $a0, 5
194 ; LA64-LABEL: and_i32_5:
195 ; LA64: # %bb.0: # %entry
196 ; LA64-NEXT: andi $a0, $a0, 5
203 define i32 @and_i32_0x1000(i32 %b) {
204 ; LA32-LABEL: and_i32_0x1000:
205 ; LA32: # %bb.0: # %entry
206 ; LA32-NEXT: lu12i.w $a1, 1
207 ; LA32-NEXT: and $a0, $a0, $a1
210 ; LA64-LABEL: and_i32_0x1000:
211 ; LA64: # %bb.0: # %entry
212 ; LA64-NEXT: lu12i.w $a1, 1
213 ; LA64-NEXT: and $a0, $a0, $a1
216 %r = and i32 4096, %b
220 define i32 @and_i32_0x100000001(i32 %b) {
221 ; LA32-LABEL: and_i32_0x100000001:
222 ; LA32: # %bb.0: # %entry
223 ; LA32-NEXT: andi $a0, $a0, 1
226 ; LA64-LABEL: and_i32_0x100000001:
227 ; LA64: # %bb.0: # %entry
228 ; LA64-NEXT: andi $a0, $a0, 1
231 %r = and i32 4294967297, %b
235 define i64 @and_i64_5(i64 %b) {
236 ; LA32-LABEL: and_i64_5:
237 ; LA32: # %bb.0: # %entry
238 ; LA32-NEXT: andi $a0, $a0, 5
239 ; LA32-NEXT: move $a1, $zero
242 ; LA64-LABEL: and_i64_5:
243 ; LA64: # %bb.0: # %entry
244 ; LA64-NEXT: andi $a0, $a0, 5
251 define i64 @and_i64_0x1000(i64 %b) {
252 ; LA32-LABEL: and_i64_0x1000:
253 ; LA32: # %bb.0: # %entry
254 ; LA32-NEXT: lu12i.w $a1, 1
255 ; LA32-NEXT: and $a0, $a0, $a1
256 ; LA32-NEXT: move $a1, $zero
259 ; LA64-LABEL: and_i64_0x1000:
260 ; LA64: # %bb.0: # %entry
261 ; LA64-NEXT: lu12i.w $a1, 1
262 ; LA64-NEXT: and $a0, $a0, $a1
265 %r = and i64 4096, %b
269 define signext i32 @and_i32_0xfff0(i32 %a) {
270 ; LA32-LABEL: and_i32_0xfff0:
272 ; LA32-NEXT: bstrpick.w $a0, $a0, 15, 4
273 ; LA32-NEXT: slli.w $a0, $a0, 4
276 ; LA64-LABEL: and_i32_0xfff0:
278 ; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4
279 ; LA64-NEXT: slli.d $a0, $a0, 4
281 %b = and i32 %a, 65520
285 define signext i32 @and_i32_0xfff0_twice(i32 %a, i32 %b) {
286 ; LA32-LABEL: and_i32_0xfff0_twice:
288 ; LA32-NEXT: bstrpick.w $a0, $a0, 15, 4
289 ; LA32-NEXT: slli.w $a0, $a0, 4
290 ; LA32-NEXT: bstrpick.w $a1, $a1, 15, 4
291 ; LA32-NEXT: slli.w $a1, $a1, 4
292 ; LA32-NEXT: sub.w $a0, $a0, $a1
295 ; LA64-LABEL: and_i32_0xfff0_twice:
297 ; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4
298 ; LA64-NEXT: slli.d $a0, $a0, 4
299 ; LA64-NEXT: bstrpick.d $a1, $a1, 15, 4
300 ; LA64-NEXT: slli.d $a1, $a1, 4
301 ; LA64-NEXT: sub.d $a0, $a0, $a1
303 %c = and i32 %a, 65520
304 %d = and i32 %b, 65520
309 define i64 @and_i64_0xfff0(i64 %a) {
310 ; LA32-LABEL: and_i64_0xfff0:
312 ; LA32-NEXT: bstrpick.w $a0, $a0, 15, 4
313 ; LA32-NEXT: slli.w $a0, $a0, 4
314 ; LA32-NEXT: move $a1, $zero
317 ; LA64-LABEL: and_i64_0xfff0:
319 ; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4
320 ; LA64-NEXT: slli.d $a0, $a0, 4
322 %b = and i64 %a, 65520
326 define i64 @and_i64_0xfff0_twice(i64 %a, i64 %b) {
327 ; LA32-LABEL: and_i64_0xfff0_twice:
329 ; LA32-NEXT: bstrpick.w $a0, $a0, 15, 4
330 ; LA32-NEXT: slli.w $a1, $a0, 4
331 ; LA32-NEXT: bstrpick.w $a0, $a2, 15, 4
332 ; LA32-NEXT: slli.w $a2, $a0, 4
333 ; LA32-NEXT: sub.w $a0, $a1, $a2
334 ; LA32-NEXT: sltu $a1, $a1, $a2
335 ; LA32-NEXT: sub.w $a1, $zero, $a1
338 ; LA64-LABEL: and_i64_0xfff0_twice:
340 ; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4
341 ; LA64-NEXT: slli.d $a0, $a0, 4
342 ; LA64-NEXT: bstrpick.d $a1, $a1, 15, 4
343 ; LA64-NEXT: slli.d $a1, $a1, 4
344 ; LA64-NEXT: sub.d $a0, $a0, $a1
346 %c = and i64 %a, 65520
347 %d = and i64 %b, 65520
352 ;; This case is not optimized to `bstrpick + slli`,
353 ;; since the immediate 1044480 can be composed via
354 ;; a single `lu12i.w $rx, 255`.
355 define i64 @and_i64_0xff000(i64 %a) {
356 ; LA32-LABEL: and_i64_0xff000:
358 ; LA32-NEXT: lu12i.w $a1, 255
359 ; LA32-NEXT: and $a0, $a0, $a1
360 ; LA32-NEXT: move $a1, $zero
363 ; LA64-LABEL: and_i64_0xff000:
365 ; LA64-NEXT: lu12i.w $a1, 255
366 ; LA64-NEXT: and $a0, $a0, $a1
368 %b = and i64 %a, 1044480
372 define i64 @and_i64_minus_2048(i64 %a) {
373 ; LA32-LABEL: and_i64_minus_2048:
375 ; LA32-NEXT: bstrins.w $a0, $zero, 10, 0
378 ; LA64-LABEL: and_i64_minus_2048:
380 ; LA64-NEXT: bstrins.d $a0, $zero, 10, 0
382 %b = and i64 %a, -2048
386 ;; This case is not optimized to `bstrpick + slli`,
387 ;; since the immediate 0xfff0 has more than 2 uses.
388 define i64 @and_i64_0xfff0_multiple_times(i64 %a, i64 %b, i64 %c) {
389 ; LA32-LABEL: and_i64_0xfff0_multiple_times:
391 ; LA32-NEXT: lu12i.w $a1, 15
392 ; LA32-NEXT: ori $a1, $a1, 4080
393 ; LA32-NEXT: and $a0, $a0, $a1
394 ; LA32-NEXT: and $a2, $a2, $a1
395 ; LA32-NEXT: and $a3, $a4, $a1
396 ; LA32-NEXT: sltu $a1, $a0, $a2
397 ; LA32-NEXT: sub.w $a1, $zero, $a1
398 ; LA32-NEXT: sub.w $a0, $a0, $a2
399 ; LA32-NEXT: mul.w $a2, $a2, $a3
400 ; LA32-NEXT: xor $a0, $a0, $a2
403 ; LA64-LABEL: and_i64_0xfff0_multiple_times:
405 ; LA64-NEXT: lu12i.w $a3, 15
406 ; LA64-NEXT: ori $a3, $a3, 4080
407 ; LA64-NEXT: and $a0, $a0, $a3
408 ; LA64-NEXT: and $a1, $a1, $a3
409 ; LA64-NEXT: and $a2, $a2, $a3
410 ; LA64-NEXT: sub.d $a0, $a0, $a1
411 ; LA64-NEXT: mul.d $a1, $a1, $a2
412 ; LA64-NEXT: xor $a0, $a0, $a1
414 %d = and i64 %a, 65520
415 %e = and i64 %b, 65520
416 %f = and i64 %c, 65520
423 define i64 @and_i64_0xffffffffff00ffff(i64 %a) {
424 ; LA32-LABEL: and_i64_0xffffffffff00ffff:
426 ; LA32-NEXT: bstrins.w $a0, $zero, 23, 16
429 ; LA64-LABEL: and_i64_0xffffffffff00ffff:
431 ; LA64-NEXT: bstrins.d $a0, $zero, 23, 16
433 %b = and i64 %a, 18446744073692839935
437 define i32 @and_add_lsr(i32 %x, i32 %y) {
438 ; LA32-LABEL: and_add_lsr:
440 ; LA32-NEXT: addi.w $a0, $a0, -1
441 ; LA32-NEXT: srli.w $a1, $a1, 20
442 ; LA32-NEXT: and $a0, $a1, $a0
445 ; LA64-LABEL: and_add_lsr:
447 ; LA64-NEXT: addi.w $a0, $a0, -1
448 ; LA64-NEXT: bstrpick.d $a1, $a1, 31, 20
449 ; LA64-NEXT: and $a0, $a1, $a0
451 %1 = add i32 %x, 4095