xref: /llvm-project/llvm/test/CodeGen/RISCV/rv32zbkb.ll (revision cad72632eb0d612fe18c38ac4526d80a6b800f96)
1182aa0cbSCraig Topper; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2182aa0cbSCraig Topper; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3182aa0cbSCraig Topper; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32I
4182aa0cbSCraig Topper; RUN: llc -mtriple=riscv32 -mattr=+zbkb -verify-machineinstrs < %s \
5182aa0cbSCraig Topper; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBKB
6182aa0cbSCraig Topper
7182aa0cbSCraig Topperdefine i32 @pack_i32(i32 %a, i32 %b) nounwind {
8182aa0cbSCraig Topper; RV32I-LABEL: pack_i32:
9182aa0cbSCraig Topper; RV32I:       # %bb.0:
10182aa0cbSCraig Topper; RV32I-NEXT:    slli a0, a0, 16
11182aa0cbSCraig Topper; RV32I-NEXT:    srli a0, a0, 16
12182aa0cbSCraig Topper; RV32I-NEXT:    slli a1, a1, 16
13182aa0cbSCraig Topper; RV32I-NEXT:    or a0, a1, a0
14182aa0cbSCraig Topper; RV32I-NEXT:    ret
15182aa0cbSCraig Topper;
16182aa0cbSCraig Topper; RV32ZBKB-LABEL: pack_i32:
17182aa0cbSCraig Topper; RV32ZBKB:       # %bb.0:
18182aa0cbSCraig Topper; RV32ZBKB-NEXT:    pack a0, a0, a1
19182aa0cbSCraig Topper; RV32ZBKB-NEXT:    ret
20182aa0cbSCraig Topper  %shl = and i32 %a, 65535
21182aa0cbSCraig Topper  %shl1 = shl i32 %b, 16
22182aa0cbSCraig Topper  %or = or i32 %shl1, %shl
23182aa0cbSCraig Topper  ret i32 %or
24182aa0cbSCraig Topper}
25182aa0cbSCraig Topper
2695388f73SCraig Topperdefine i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind {
2795388f73SCraig Topper; RV32I-LABEL: pack_i32_2:
2895388f73SCraig Topper; RV32I:       # %bb.0:
2995388f73SCraig Topper; RV32I-NEXT:    slli a1, a1, 16
3095388f73SCraig Topper; RV32I-NEXT:    or a0, a1, a0
3195388f73SCraig Topper; RV32I-NEXT:    ret
3295388f73SCraig Topper;
3395388f73SCraig Topper; RV32ZBKB-LABEL: pack_i32_2:
3495388f73SCraig Topper; RV32ZBKB:       # %bb.0:
3595388f73SCraig Topper; RV32ZBKB-NEXT:    pack a0, a0, a1
3695388f73SCraig Topper; RV32ZBKB-NEXT:    ret
3795388f73SCraig Topper  %zexta = zext i16 %a to i32
3895388f73SCraig Topper  %zextb = zext i16 %b to i32
3995388f73SCraig Topper  %shl1 = shl i32 %zextb, 16
4095388f73SCraig Topper  %or = or i32 %shl1, %zexta
4195388f73SCraig Topper  ret i32 %or
4295388f73SCraig Topper}
4395388f73SCraig Topper
441a8ba9e1SCraig Topperdefine i32 @pack_i32_3(i16 zeroext %0, i16 zeroext %1, i32 %2) {
451a8ba9e1SCraig Topper; RV32I-LABEL: pack_i32_3:
461a8ba9e1SCraig Topper; RV32I:       # %bb.0:
471a8ba9e1SCraig Topper; RV32I-NEXT:    slli a0, a0, 16
481a8ba9e1SCraig Topper; RV32I-NEXT:    or a0, a0, a1
491a8ba9e1SCraig Topper; RV32I-NEXT:    add a0, a0, a2
501a8ba9e1SCraig Topper; RV32I-NEXT:    ret
511a8ba9e1SCraig Topper;
521a8ba9e1SCraig Topper; RV32ZBKB-LABEL: pack_i32_3:
531a8ba9e1SCraig Topper; RV32ZBKB:       # %bb.0:
541a8ba9e1SCraig Topper; RV32ZBKB-NEXT:    pack a0, a1, a0
551a8ba9e1SCraig Topper; RV32ZBKB-NEXT:    add a0, a0, a2
561a8ba9e1SCraig Topper; RV32ZBKB-NEXT:    ret
571a8ba9e1SCraig Topper  %4 = zext i16 %0 to i32
581a8ba9e1SCraig Topper  %5 = shl nuw i32 %4, 16
591a8ba9e1SCraig Topper  %6 = zext i16 %1 to i32
601a8ba9e1SCraig Topper  %7 = or i32 %5, %6
611a8ba9e1SCraig Topper  %8 = add i32 %7, %2
621a8ba9e1SCraig Topper  ret i32 %8
631a8ba9e1SCraig Topper}
641a8ba9e1SCraig Topper
65182aa0cbSCraig Topper; As we are not matching directly i64 code patterns on RV32 some i64 patterns
66182aa0cbSCraig Topper; don't have yet any matching bit manipulation instructions on RV32.
67182aa0cbSCraig Topper; This test is presented here in case future expansions of the Bitmanip
68182aa0cbSCraig Topper; extensions introduce instructions suitable for this pattern.
69182aa0cbSCraig Topper
70182aa0cbSCraig Topperdefine i64 @pack_i64(i64 %a, i64 %b) nounwind {
71182aa0cbSCraig Topper; CHECK-LABEL: pack_i64:
72182aa0cbSCraig Topper; CHECK:       # %bb.0:
73182aa0cbSCraig Topper; CHECK-NEXT:    mv a1, a2
74182aa0cbSCraig Topper; CHECK-NEXT:    ret
75182aa0cbSCraig Topper  %shl = and i64 %a, 4294967295
76182aa0cbSCraig Topper  %shl1 = shl i64 %b, 32
77182aa0cbSCraig Topper  %or = or i64 %shl1, %shl
78182aa0cbSCraig Topper  ret i64 %or
79182aa0cbSCraig Topper}
80182aa0cbSCraig Topper
8195388f73SCraig Topperdefine i64 @pack_i64_2(i32 %a, i32 %b) nounwind {
8295388f73SCraig Topper; CHECK-LABEL: pack_i64_2:
8395388f73SCraig Topper; CHECK:       # %bb.0:
8495388f73SCraig Topper; CHECK-NEXT:    ret
8595388f73SCraig Topper  %zexta = zext i32 %a to i64
8695388f73SCraig Topper  %zextb = zext i32 %b to i64
8795388f73SCraig Topper  %shl1 = shl i64 %zextb, 32
8895388f73SCraig Topper  %or = or i64 %shl1, %zexta
8995388f73SCraig Topper  ret i64 %or
9095388f73SCraig Topper}
9195388f73SCraig Topper
9213e32a8aSCraig Topperdefine i64 @pack_i64_3(ptr %0, ptr %1) {
9313e32a8aSCraig Topper; CHECK-LABEL: pack_i64_3:
9413e32a8aSCraig Topper; CHECK:       # %bb.0:
9513e32a8aSCraig Topper; CHECK-NEXT:    lw a2, 0(a0)
9613e32a8aSCraig Topper; CHECK-NEXT:    lw a0, 0(a1)
9713e32a8aSCraig Topper; CHECK-NEXT:    mv a1, a2
9813e32a8aSCraig Topper; CHECK-NEXT:    ret
9913e32a8aSCraig Topper  %3 = load i32, ptr %0, align 4
10013e32a8aSCraig Topper  %4 = zext i32 %3 to i64
10113e32a8aSCraig Topper  %5 = shl i64 %4, 32
10213e32a8aSCraig Topper  %6 = load i32, ptr %1, align 4
10313e32a8aSCraig Topper  %7 = zext i32 %6 to i64
10413e32a8aSCraig Topper  %8 = or i64 %5, %7
10513e32a8aSCraig Topper  ret i64 %8
10613e32a8aSCraig Topper}
10713e32a8aSCraig Topper
108182aa0cbSCraig Topperdefine i32 @packh_i32(i32 %a, i32 %b) nounwind {
109182aa0cbSCraig Topper; RV32I-LABEL: packh_i32:
110182aa0cbSCraig Topper; RV32I:       # %bb.0:
111182aa0cbSCraig Topper; RV32I-NEXT:    andi a0, a0, 255
112182aa0cbSCraig Topper; RV32I-NEXT:    slli a1, a1, 24
113182aa0cbSCraig Topper; RV32I-NEXT:    srli a1, a1, 16
114182aa0cbSCraig Topper; RV32I-NEXT:    or a0, a1, a0
115182aa0cbSCraig Topper; RV32I-NEXT:    ret
116182aa0cbSCraig Topper;
117182aa0cbSCraig Topper; RV32ZBKB-LABEL: packh_i32:
118182aa0cbSCraig Topper; RV32ZBKB:       # %bb.0:
119182aa0cbSCraig Topper; RV32ZBKB-NEXT:    packh a0, a0, a1
120182aa0cbSCraig Topper; RV32ZBKB-NEXT:    ret
121182aa0cbSCraig Topper  %and = and i32 %a, 255
122182aa0cbSCraig Topper  %and1 = shl i32 %b, 8
123182aa0cbSCraig Topper  %shl = and i32 %and1, 65280
124182aa0cbSCraig Topper  %or = or i32 %shl, %and
125182aa0cbSCraig Topper  ret i32 %or
126182aa0cbSCraig Topper}
127182aa0cbSCraig Topper
128182aa0cbSCraig Topperdefine i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
129182aa0cbSCraig Topper; RV32I-LABEL: packh_i32_2:
130182aa0cbSCraig Topper; RV32I:       # %bb.0:
131182aa0cbSCraig Topper; RV32I-NEXT:    andi a0, a0, 255
132182aa0cbSCraig Topper; RV32I-NEXT:    andi a1, a1, 255
133182aa0cbSCraig Topper; RV32I-NEXT:    slli a1, a1, 8
134182aa0cbSCraig Topper; RV32I-NEXT:    or a0, a1, a0
135182aa0cbSCraig Topper; RV32I-NEXT:    ret
136182aa0cbSCraig Topper;
137182aa0cbSCraig Topper; RV32ZBKB-LABEL: packh_i32_2:
138182aa0cbSCraig Topper; RV32ZBKB:       # %bb.0:
139182aa0cbSCraig Topper; RV32ZBKB-NEXT:    packh a0, a0, a1
140182aa0cbSCraig Topper; RV32ZBKB-NEXT:    ret
141182aa0cbSCraig Topper  %and = and i32 %a, 255
142182aa0cbSCraig Topper  %and1 = and i32 %b, 255
143182aa0cbSCraig Topper  %shl = shl i32 %and1, 8
144182aa0cbSCraig Topper  %or = or i32 %shl, %and
145182aa0cbSCraig Topper  ret i32 %or
146182aa0cbSCraig Topper}
147182aa0cbSCraig Topper
148182aa0cbSCraig Topperdefine i64 @packh_i64(i64 %a, i64 %b) nounwind {
149182aa0cbSCraig Topper; RV32I-LABEL: packh_i64:
150182aa0cbSCraig Topper; RV32I:       # %bb.0:
151182aa0cbSCraig Topper; RV32I-NEXT:    andi a0, a0, 255
152a2b5b584SCraig Topper; RV32I-NEXT:    slli a2, a2, 24
153a8c79121SCraig Topper; RV32I-NEXT:    srli a2, a2, 16
154a8c79121SCraig Topper; RV32I-NEXT:    or a0, a2, a0
155182aa0cbSCraig Topper; RV32I-NEXT:    li a1, 0
156182aa0cbSCraig Topper; RV32I-NEXT:    ret
157182aa0cbSCraig Topper;
158182aa0cbSCraig Topper; RV32ZBKB-LABEL: packh_i64:
159182aa0cbSCraig Topper; RV32ZBKB:       # %bb.0:
160182aa0cbSCraig Topper; RV32ZBKB-NEXT:    packh a0, a0, a2
161182aa0cbSCraig Topper; RV32ZBKB-NEXT:    li a1, 0
162182aa0cbSCraig Topper; RV32ZBKB-NEXT:    ret
163182aa0cbSCraig Topper  %and = and i64 %a, 255
164182aa0cbSCraig Topper  %and1 = shl i64 %b, 8
165182aa0cbSCraig Topper  %shl = and i64 %and1, 65280
166182aa0cbSCraig Topper  %or = or i64 %shl, %and
167182aa0cbSCraig Topper  ret i64 %or
168182aa0cbSCraig Topper}
169182aa0cbSCraig Topper
170182aa0cbSCraig Topperdefine i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
171182aa0cbSCraig Topper; RV32I-LABEL: packh_i64_2:
172182aa0cbSCraig Topper; RV32I:       # %bb.0:
173182aa0cbSCraig Topper; RV32I-NEXT:    andi a0, a0, 255
174182aa0cbSCraig Topper; RV32I-NEXT:    andi a1, a2, 255
175182aa0cbSCraig Topper; RV32I-NEXT:    slli a1, a1, 8
176182aa0cbSCraig Topper; RV32I-NEXT:    or a0, a1, a0
177182aa0cbSCraig Topper; RV32I-NEXT:    li a1, 0
178182aa0cbSCraig Topper; RV32I-NEXT:    ret
179182aa0cbSCraig Topper;
180182aa0cbSCraig Topper; RV32ZBKB-LABEL: packh_i64_2:
181182aa0cbSCraig Topper; RV32ZBKB:       # %bb.0:
182182aa0cbSCraig Topper; RV32ZBKB-NEXT:    packh a0, a0, a2
183182aa0cbSCraig Topper; RV32ZBKB-NEXT:    li a1, 0
184182aa0cbSCraig Topper; RV32ZBKB-NEXT:    ret
185182aa0cbSCraig Topper  %and = and i64 %a, 255
186182aa0cbSCraig Topper  %and1 = and i64 %b, 255
187182aa0cbSCraig Topper  %shl = shl i64 %and1, 8
188182aa0cbSCraig Topper  %or = or i64 %shl, %and
189182aa0cbSCraig Topper  ret i64 %or
190182aa0cbSCraig Topper}
19140ae4b89SCraig Topper
19240ae4b89SCraig Topper
19340ae4b89SCraig Topperdefine zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind {
19440ae4b89SCraig Topper; RV32I-LABEL: packh_i16:
19540ae4b89SCraig Topper; RV32I:       # %bb.0:
19640ae4b89SCraig Topper; RV32I-NEXT:    slli a1, a1, 8
19740ae4b89SCraig Topper; RV32I-NEXT:    or a0, a1, a0
19840ae4b89SCraig Topper; RV32I-NEXT:    ret
19940ae4b89SCraig Topper;
20040ae4b89SCraig Topper; RV32ZBKB-LABEL: packh_i16:
20140ae4b89SCraig Topper; RV32ZBKB:       # %bb.0:
20240ae4b89SCraig Topper; RV32ZBKB-NEXT:    packh a0, a0, a1
20340ae4b89SCraig Topper; RV32ZBKB-NEXT:    ret
20440ae4b89SCraig Topper  %zext = zext i8 %a to i16
20540ae4b89SCraig Topper  %zext1 = zext i8 %b to i16
20640ae4b89SCraig Topper  %shl = shl i16 %zext1, 8
20740ae4b89SCraig Topper  %or = or i16 %shl, %zext
20840ae4b89SCraig Topper  ret i16 %or
20940ae4b89SCraig Topper}
2103ac93d1fSCraig Topper
2113ac93d1fSCraig Topper
2123ac93d1fSCraig Topperdefine zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
2133ac93d1fSCraig Topper; RV32I-LABEL: packh_i16_2:
2143ac93d1fSCraig Topper; RV32I:       # %bb.0:
2153ac93d1fSCraig Topper; RV32I-NEXT:    add a0, a1, a0
2163ac93d1fSCraig Topper; RV32I-NEXT:    slli a0, a0, 8
2173ac93d1fSCraig Topper; RV32I-NEXT:    or a0, a0, a2
2183ac93d1fSCraig Topper; RV32I-NEXT:    slli a0, a0, 16
2193ac93d1fSCraig Topper; RV32I-NEXT:    srli a0, a0, 16
2203ac93d1fSCraig Topper; RV32I-NEXT:    ret
2213ac93d1fSCraig Topper;
2223ac93d1fSCraig Topper; RV32ZBKB-LABEL: packh_i16_2:
2233ac93d1fSCraig Topper; RV32ZBKB:       # %bb.0:
2243ac93d1fSCraig Topper; RV32ZBKB-NEXT:    add a0, a1, a0
2253ac93d1fSCraig Topper; RV32ZBKB-NEXT:    packh a0, a2, a0
2263ac93d1fSCraig Topper; RV32ZBKB-NEXT:    ret
2273ac93d1fSCraig Topper  %4 = add i8 %1, %0
2283ac93d1fSCraig Topper  %5 = zext i8 %4 to i16
2293ac93d1fSCraig Topper  %6 = shl i16 %5, 8
2303ac93d1fSCraig Topper  %7 = zext i8 %2 to i16
2313ac93d1fSCraig Topper  %8 = or i16 %6, %7
2323ac93d1fSCraig Topper  ret i16 %8
2333ac93d1fSCraig Topper}
2347965a21fSCraig Topper
2357965a21fSCraig Topperdefine void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) {
2367965a21fSCraig Topper; RV32I-LABEL: packh_i16_3:
2377965a21fSCraig Topper; RV32I:       # %bb.0:
2387965a21fSCraig Topper; RV32I-NEXT:    add a0, a1, a0
2397965a21fSCraig Topper; RV32I-NEXT:    slli a0, a0, 8
2407965a21fSCraig Topper; RV32I-NEXT:    or a0, a0, a2
2417965a21fSCraig Topper; RV32I-NEXT:    sh a0, 0(a3)
2427965a21fSCraig Topper; RV32I-NEXT:    ret
2437965a21fSCraig Topper;
2447965a21fSCraig Topper; RV32ZBKB-LABEL: packh_i16_3:
2457965a21fSCraig Topper; RV32ZBKB:       # %bb.0:
2467965a21fSCraig Topper; RV32ZBKB-NEXT:    add a0, a1, a0
2477965a21fSCraig Topper; RV32ZBKB-NEXT:    packh a0, a2, a0
2487965a21fSCraig Topper; RV32ZBKB-NEXT:    sh a0, 0(a3)
2497965a21fSCraig Topper; RV32ZBKB-NEXT:    ret
2507965a21fSCraig Topper  %4 = add i8 %1, %0
2517965a21fSCraig Topper  %5 = zext i8 %4 to i16
2527965a21fSCraig Topper  %6 = shl i16 %5, 8
2537965a21fSCraig Topper  %7 = zext i8 %2 to i16
2547965a21fSCraig Topper  %8 = or i16 %6, %7
2557965a21fSCraig Topper  store i16 %8, ptr %p
2567965a21fSCraig Topper  ret void
2577965a21fSCraig Topper}
258*cad72632SCraig Topper
259*cad72632SCraig Topperdefine i32 @zexth_i32(i32 %a) nounwind {
260*cad72632SCraig Topper; RV32I-LABEL: zexth_i32:
261*cad72632SCraig Topper; RV32I:       # %bb.0:
262*cad72632SCraig Topper; RV32I-NEXT:    slli a0, a0, 16
263*cad72632SCraig Topper; RV32I-NEXT:    srli a0, a0, 16
264*cad72632SCraig Topper; RV32I-NEXT:    ret
265*cad72632SCraig Topper;
266*cad72632SCraig Topper; RV32ZBKB-LABEL: zexth_i32:
267*cad72632SCraig Topper; RV32ZBKB:       # %bb.0:
268*cad72632SCraig Topper; RV32ZBKB-NEXT:    zext.h a0, a0
269*cad72632SCraig Topper; RV32ZBKB-NEXT:    ret
270*cad72632SCraig Topper  %and = and i32 %a, 65535
271*cad72632SCraig Topper  ret i32 %and
272*cad72632SCraig Topper}
273*cad72632SCraig Topper
274*cad72632SCraig Topperdefine i64 @zexth_i64(i64 %a) nounwind {
275*cad72632SCraig Topper; RV32I-LABEL: zexth_i64:
276*cad72632SCraig Topper; RV32I:       # %bb.0:
277*cad72632SCraig Topper; RV32I-NEXT:    slli a0, a0, 16
278*cad72632SCraig Topper; RV32I-NEXT:    srli a0, a0, 16
279*cad72632SCraig Topper; RV32I-NEXT:    li a1, 0
280*cad72632SCraig Topper; RV32I-NEXT:    ret
281*cad72632SCraig Topper;
282*cad72632SCraig Topper; RV32ZBKB-LABEL: zexth_i64:
283*cad72632SCraig Topper; RV32ZBKB:       # %bb.0:
284*cad72632SCraig Topper; RV32ZBKB-NEXT:    zext.h a0, a0
285*cad72632SCraig Topper; RV32ZBKB-NEXT:    li a1, 0
286*cad72632SCraig Topper; RV32ZBKB-NEXT:    ret
287*cad72632SCraig Topper  %and = and i64 %a, 65535
288*cad72632SCraig Topper  ret i64 %and
289*cad72632SCraig Topper}
290*cad72632SCraig Topper
291*cad72632SCraig Topperdefine i32 @zext_i16_to_i32(i16 %a) nounwind {
292*cad72632SCraig Topper; RV32I-LABEL: zext_i16_to_i32:
293*cad72632SCraig Topper; RV32I:       # %bb.0:
294*cad72632SCraig Topper; RV32I-NEXT:    slli a0, a0, 16
295*cad72632SCraig Topper; RV32I-NEXT:    srli a0, a0, 16
296*cad72632SCraig Topper; RV32I-NEXT:    ret
297*cad72632SCraig Topper;
298*cad72632SCraig Topper; RV32ZBKB-LABEL: zext_i16_to_i32:
299*cad72632SCraig Topper; RV32ZBKB:       # %bb.0:
300*cad72632SCraig Topper; RV32ZBKB-NEXT:    zext.h a0, a0
301*cad72632SCraig Topper; RV32ZBKB-NEXT:    ret
302*cad72632SCraig Topper  %1 = zext i16 %a to i32
303*cad72632SCraig Topper  ret i32 %1
304*cad72632SCraig Topper}
305*cad72632SCraig Topper
306*cad72632SCraig Topperdefine i64 @zext_i16_to_i64(i16 %a) nounwind {
307*cad72632SCraig Topper; RV32I-LABEL: zext_i16_to_i64:
308*cad72632SCraig Topper; RV32I:       # %bb.0:
309*cad72632SCraig Topper; RV32I-NEXT:    slli a0, a0, 16
310*cad72632SCraig Topper; RV32I-NEXT:    srli a0, a0, 16
311*cad72632SCraig Topper; RV32I-NEXT:    li a1, 0
312*cad72632SCraig Topper; RV32I-NEXT:    ret
313*cad72632SCraig Topper;
314*cad72632SCraig Topper; RV32ZBKB-LABEL: zext_i16_to_i64:
315*cad72632SCraig Topper; RV32ZBKB:       # %bb.0:
316*cad72632SCraig Topper; RV32ZBKB-NEXT:    zext.h a0, a0
317*cad72632SCraig Topper; RV32ZBKB-NEXT:    li a1, 0
318*cad72632SCraig Topper; RV32ZBKB-NEXT:    ret
319*cad72632SCraig Topper  %1 = zext i16 %a to i64
320*cad72632SCraig Topper  ret i64 %1
321*cad72632SCraig Topper}
322