xref: /llvm-project/llvm/test/CodeGen/RISCV/rv32zbkb.ll (revision cad72632eb0d612fe18c38ac4526d80a6b800f96)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32I
4; RUN: llc -mtriple=riscv32 -mattr=+zbkb -verify-machineinstrs < %s \
5; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBKB
6
7define i32 @pack_i32(i32 %a, i32 %b) nounwind {
8; RV32I-LABEL: pack_i32:
9; RV32I:       # %bb.0:
10; RV32I-NEXT:    slli a0, a0, 16
11; RV32I-NEXT:    srli a0, a0, 16
12; RV32I-NEXT:    slli a1, a1, 16
13; RV32I-NEXT:    or a0, a1, a0
14; RV32I-NEXT:    ret
15;
16; RV32ZBKB-LABEL: pack_i32:
17; RV32ZBKB:       # %bb.0:
18; RV32ZBKB-NEXT:    pack a0, a0, a1
19; RV32ZBKB-NEXT:    ret
20  %shl = and i32 %a, 65535
21  %shl1 = shl i32 %b, 16
22  %or = or i32 %shl1, %shl
23  ret i32 %or
24}
25
26define i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind {
27; RV32I-LABEL: pack_i32_2:
28; RV32I:       # %bb.0:
29; RV32I-NEXT:    slli a1, a1, 16
30; RV32I-NEXT:    or a0, a1, a0
31; RV32I-NEXT:    ret
32;
33; RV32ZBKB-LABEL: pack_i32_2:
34; RV32ZBKB:       # %bb.0:
35; RV32ZBKB-NEXT:    pack a0, a0, a1
36; RV32ZBKB-NEXT:    ret
37  %zexta = zext i16 %a to i32
38  %zextb = zext i16 %b to i32
39  %shl1 = shl i32 %zextb, 16
40  %or = or i32 %shl1, %zexta
41  ret i32 %or
42}
43
44define i32 @pack_i32_3(i16 zeroext %0, i16 zeroext %1, i32 %2) {
45; RV32I-LABEL: pack_i32_3:
46; RV32I:       # %bb.0:
47; RV32I-NEXT:    slli a0, a0, 16
48; RV32I-NEXT:    or a0, a0, a1
49; RV32I-NEXT:    add a0, a0, a2
50; RV32I-NEXT:    ret
51;
52; RV32ZBKB-LABEL: pack_i32_3:
53; RV32ZBKB:       # %bb.0:
54; RV32ZBKB-NEXT:    pack a0, a1, a0
55; RV32ZBKB-NEXT:    add a0, a0, a2
56; RV32ZBKB-NEXT:    ret
57  %4 = zext i16 %0 to i32
58  %5 = shl nuw i32 %4, 16
59  %6 = zext i16 %1 to i32
60  %7 = or i32 %5, %6
61  %8 = add i32 %7, %2
62  ret i32 %8
63}
64
65; As we are not matching directly i64 code patterns on RV32 some i64 patterns
66; don't have yet any matching bit manipulation instructions on RV32.
67; This test is presented here in case future expansions of the Bitmanip
68; extensions introduce instructions suitable for this pattern.
69
70define i64 @pack_i64(i64 %a, i64 %b) nounwind {
71; CHECK-LABEL: pack_i64:
72; CHECK:       # %bb.0:
73; CHECK-NEXT:    mv a1, a2
74; CHECK-NEXT:    ret
75  %shl = and i64 %a, 4294967295
76  %shl1 = shl i64 %b, 32
77  %or = or i64 %shl1, %shl
78  ret i64 %or
79}
80
81define i64 @pack_i64_2(i32 %a, i32 %b) nounwind {
82; CHECK-LABEL: pack_i64_2:
83; CHECK:       # %bb.0:
84; CHECK-NEXT:    ret
85  %zexta = zext i32 %a to i64
86  %zextb = zext i32 %b to i64
87  %shl1 = shl i64 %zextb, 32
88  %or = or i64 %shl1, %zexta
89  ret i64 %or
90}
91
92define i64 @pack_i64_3(ptr %0, ptr %1) {
93; CHECK-LABEL: pack_i64_3:
94; CHECK:       # %bb.0:
95; CHECK-NEXT:    lw a2, 0(a0)
96; CHECK-NEXT:    lw a0, 0(a1)
97; CHECK-NEXT:    mv a1, a2
98; CHECK-NEXT:    ret
99  %3 = load i32, ptr %0, align 4
100  %4 = zext i32 %3 to i64
101  %5 = shl i64 %4, 32
102  %6 = load i32, ptr %1, align 4
103  %7 = zext i32 %6 to i64
104  %8 = or i64 %5, %7
105  ret i64 %8
106}
107
108define i32 @packh_i32(i32 %a, i32 %b) nounwind {
109; RV32I-LABEL: packh_i32:
110; RV32I:       # %bb.0:
111; RV32I-NEXT:    andi a0, a0, 255
112; RV32I-NEXT:    slli a1, a1, 24
113; RV32I-NEXT:    srli a1, a1, 16
114; RV32I-NEXT:    or a0, a1, a0
115; RV32I-NEXT:    ret
116;
117; RV32ZBKB-LABEL: packh_i32:
118; RV32ZBKB:       # %bb.0:
119; RV32ZBKB-NEXT:    packh a0, a0, a1
120; RV32ZBKB-NEXT:    ret
121  %and = and i32 %a, 255
122  %and1 = shl i32 %b, 8
123  %shl = and i32 %and1, 65280
124  %or = or i32 %shl, %and
125  ret i32 %or
126}
127
128define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
129; RV32I-LABEL: packh_i32_2:
130; RV32I:       # %bb.0:
131; RV32I-NEXT:    andi a0, a0, 255
132; RV32I-NEXT:    andi a1, a1, 255
133; RV32I-NEXT:    slli a1, a1, 8
134; RV32I-NEXT:    or a0, a1, a0
135; RV32I-NEXT:    ret
136;
137; RV32ZBKB-LABEL: packh_i32_2:
138; RV32ZBKB:       # %bb.0:
139; RV32ZBKB-NEXT:    packh a0, a0, a1
140; RV32ZBKB-NEXT:    ret
141  %and = and i32 %a, 255
142  %and1 = and i32 %b, 255
143  %shl = shl i32 %and1, 8
144  %or = or i32 %shl, %and
145  ret i32 %or
146}
147
148define i64 @packh_i64(i64 %a, i64 %b) nounwind {
149; RV32I-LABEL: packh_i64:
150; RV32I:       # %bb.0:
151; RV32I-NEXT:    andi a0, a0, 255
152; RV32I-NEXT:    slli a2, a2, 24
153; RV32I-NEXT:    srli a2, a2, 16
154; RV32I-NEXT:    or a0, a2, a0
155; RV32I-NEXT:    li a1, 0
156; RV32I-NEXT:    ret
157;
158; RV32ZBKB-LABEL: packh_i64:
159; RV32ZBKB:       # %bb.0:
160; RV32ZBKB-NEXT:    packh a0, a0, a2
161; RV32ZBKB-NEXT:    li a1, 0
162; RV32ZBKB-NEXT:    ret
163  %and = and i64 %a, 255
164  %and1 = shl i64 %b, 8
165  %shl = and i64 %and1, 65280
166  %or = or i64 %shl, %and
167  ret i64 %or
168}
169
170define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
171; RV32I-LABEL: packh_i64_2:
172; RV32I:       # %bb.0:
173; RV32I-NEXT:    andi a0, a0, 255
174; RV32I-NEXT:    andi a1, a2, 255
175; RV32I-NEXT:    slli a1, a1, 8
176; RV32I-NEXT:    or a0, a1, a0
177; RV32I-NEXT:    li a1, 0
178; RV32I-NEXT:    ret
179;
180; RV32ZBKB-LABEL: packh_i64_2:
181; RV32ZBKB:       # %bb.0:
182; RV32ZBKB-NEXT:    packh a0, a0, a2
183; RV32ZBKB-NEXT:    li a1, 0
184; RV32ZBKB-NEXT:    ret
185  %and = and i64 %a, 255
186  %and1 = and i64 %b, 255
187  %shl = shl i64 %and1, 8
188  %or = or i64 %shl, %and
189  ret i64 %or
190}
191
192
193define zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind {
194; RV32I-LABEL: packh_i16:
195; RV32I:       # %bb.0:
196; RV32I-NEXT:    slli a1, a1, 8
197; RV32I-NEXT:    or a0, a1, a0
198; RV32I-NEXT:    ret
199;
200; RV32ZBKB-LABEL: packh_i16:
201; RV32ZBKB:       # %bb.0:
202; RV32ZBKB-NEXT:    packh a0, a0, a1
203; RV32ZBKB-NEXT:    ret
204  %zext = zext i8 %a to i16
205  %zext1 = zext i8 %b to i16
206  %shl = shl i16 %zext1, 8
207  %or = or i16 %shl, %zext
208  ret i16 %or
209}
210
211
212define zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
213; RV32I-LABEL: packh_i16_2:
214; RV32I:       # %bb.0:
215; RV32I-NEXT:    add a0, a1, a0
216; RV32I-NEXT:    slli a0, a0, 8
217; RV32I-NEXT:    or a0, a0, a2
218; RV32I-NEXT:    slli a0, a0, 16
219; RV32I-NEXT:    srli a0, a0, 16
220; RV32I-NEXT:    ret
221;
222; RV32ZBKB-LABEL: packh_i16_2:
223; RV32ZBKB:       # %bb.0:
224; RV32ZBKB-NEXT:    add a0, a1, a0
225; RV32ZBKB-NEXT:    packh a0, a2, a0
226; RV32ZBKB-NEXT:    ret
227  %4 = add i8 %1, %0
228  %5 = zext i8 %4 to i16
229  %6 = shl i16 %5, 8
230  %7 = zext i8 %2 to i16
231  %8 = or i16 %6, %7
232  ret i16 %8
233}
234
235define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) {
236; RV32I-LABEL: packh_i16_3:
237; RV32I:       # %bb.0:
238; RV32I-NEXT:    add a0, a1, a0
239; RV32I-NEXT:    slli a0, a0, 8
240; RV32I-NEXT:    or a0, a0, a2
241; RV32I-NEXT:    sh a0, 0(a3)
242; RV32I-NEXT:    ret
243;
244; RV32ZBKB-LABEL: packh_i16_3:
245; RV32ZBKB:       # %bb.0:
246; RV32ZBKB-NEXT:    add a0, a1, a0
247; RV32ZBKB-NEXT:    packh a0, a2, a0
248; RV32ZBKB-NEXT:    sh a0, 0(a3)
249; RV32ZBKB-NEXT:    ret
250  %4 = add i8 %1, %0
251  %5 = zext i8 %4 to i16
252  %6 = shl i16 %5, 8
253  %7 = zext i8 %2 to i16
254  %8 = or i16 %6, %7
255  store i16 %8, ptr %p
256  ret void
257}
258
259define i32 @zexth_i32(i32 %a) nounwind {
260; RV32I-LABEL: zexth_i32:
261; RV32I:       # %bb.0:
262; RV32I-NEXT:    slli a0, a0, 16
263; RV32I-NEXT:    srli a0, a0, 16
264; RV32I-NEXT:    ret
265;
266; RV32ZBKB-LABEL: zexth_i32:
267; RV32ZBKB:       # %bb.0:
268; RV32ZBKB-NEXT:    zext.h a0, a0
269; RV32ZBKB-NEXT:    ret
270  %and = and i32 %a, 65535
271  ret i32 %and
272}
273
274define i64 @zexth_i64(i64 %a) nounwind {
275; RV32I-LABEL: zexth_i64:
276; RV32I:       # %bb.0:
277; RV32I-NEXT:    slli a0, a0, 16
278; RV32I-NEXT:    srli a0, a0, 16
279; RV32I-NEXT:    li a1, 0
280; RV32I-NEXT:    ret
281;
282; RV32ZBKB-LABEL: zexth_i64:
283; RV32ZBKB:       # %bb.0:
284; RV32ZBKB-NEXT:    zext.h a0, a0
285; RV32ZBKB-NEXT:    li a1, 0
286; RV32ZBKB-NEXT:    ret
287  %and = and i64 %a, 65535
288  ret i64 %and
289}
290
291define i32 @zext_i16_to_i32(i16 %a) nounwind {
292; RV32I-LABEL: zext_i16_to_i32:
293; RV32I:       # %bb.0:
294; RV32I-NEXT:    slli a0, a0, 16
295; RV32I-NEXT:    srli a0, a0, 16
296; RV32I-NEXT:    ret
297;
298; RV32ZBKB-LABEL: zext_i16_to_i32:
299; RV32ZBKB:       # %bb.0:
300; RV32ZBKB-NEXT:    zext.h a0, a0
301; RV32ZBKB-NEXT:    ret
302  %1 = zext i16 %a to i32
303  ret i32 %1
304}
305
306define i64 @zext_i16_to_i64(i16 %a) nounwind {
307; RV32I-LABEL: zext_i16_to_i64:
308; RV32I:       # %bb.0:
309; RV32I-NEXT:    slli a0, a0, 16
310; RV32I-NEXT:    srli a0, a0, 16
311; RV32I-NEXT:    li a1, 0
312; RV32I-NEXT:    ret
313;
314; RV32ZBKB-LABEL: zext_i16_to_i64:
315; RV32ZBKB:       # %bb.0:
316; RV32ZBKB-NEXT:    zext.h a0, a0
317; RV32ZBKB-NEXT:    li a1, 0
318; RV32ZBKB-NEXT:    ret
319  %1 = zext i16 %a to i64
320  ret i64 %1
321}
322