xref: /llvm-project/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbkb.ll (revision d78fe84d49b3db675ae4c502ead38ce9e5c2539f)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -global-isel -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32I
4; RUN: llc -mtriple=riscv32 -global-isel -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
108; FIXME: Use packh.
109define i32 @packh_i32(i32 %a, i32 %b) nounwind {
110; CHECK-LABEL: packh_i32:
111; CHECK:       # %bb.0:
112; CHECK-NEXT:    lui a2, 16
113; CHECK-NEXT:    andi a0, a0, 255
114; CHECK-NEXT:    addi a2, a2, -256
115; CHECK-NEXT:    slli a1, a1, 8
116; CHECK-NEXT:    and a1, a1, a2
117; CHECK-NEXT:    or a0, a1, a0
118; CHECK-NEXT:    ret
119  %and = and i32 %a, 255
120  %and1 = shl i32 %b, 8
121  %shl = and i32 %and1, 65280
122  %or = or i32 %shl, %and
123  ret i32 %or
124}
125
126define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
127; RV32I-LABEL: packh_i32_2:
128; RV32I:       # %bb.0:
129; RV32I-NEXT:    andi a0, a0, 255
130; RV32I-NEXT:    andi a1, a1, 255
131; RV32I-NEXT:    slli a1, a1, 8
132; RV32I-NEXT:    or a0, a1, a0
133; RV32I-NEXT:    ret
134;
135; RV32ZBKB-LABEL: packh_i32_2:
136; RV32ZBKB:       # %bb.0:
137; RV32ZBKB-NEXT:    packh a0, a0, a1
138; RV32ZBKB-NEXT:    ret
139  %and = and i32 %a, 255
140  %and1 = and i32 %b, 255
141  %shl = shl i32 %and1, 8
142  %or = or i32 %shl, %and
143  ret i32 %or
144}
145
146; FIMXE: Use packh
147define i64 @packh_i64(i64 %a, i64 %b) nounwind {
148; CHECK-LABEL: packh_i64:
149; CHECK:       # %bb.0:
150; CHECK-NEXT:    lui a1, 16
151; CHECK-NEXT:    andi a0, a0, 255
152; CHECK-NEXT:    addi a1, a1, -256
153; CHECK-NEXT:    slli a2, a2, 8
154; CHECK-NEXT:    and a1, a2, a1
155; CHECK-NEXT:    or a0, a1, a0
156; CHECK-NEXT:    li a1, 0
157; CHECK-NEXT:    ret
158  %and = and i64 %a, 255
159  %and1 = shl i64 %b, 8
160  %shl = and i64 %and1, 65280
161  %or = or i64 %shl, %and
162  ret i64 %or
163}
164
165; FIXME The andi+srli for RV32ZBKB should fold to 0.
166define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
167; RV32I-LABEL: packh_i64_2:
168; RV32I:       # %bb.0:
169; RV32I-NEXT:    andi a0, a0, 255
170; RV32I-NEXT:    andi a1, a2, 255
171; RV32I-NEXT:    slli a2, a1, 8
172; RV32I-NEXT:    srli a1, a1, 24
173; RV32I-NEXT:    or a0, a2, a0
174; RV32I-NEXT:    ret
175;
176; RV32ZBKB-LABEL: packh_i64_2:
177; RV32ZBKB:       # %bb.0:
178; RV32ZBKB-NEXT:    andi a1, a2, 255
179; RV32ZBKB-NEXT:    srli a1, a1, 24
180; RV32ZBKB-NEXT:    packh a0, a0, a2
181; RV32ZBKB-NEXT:    ret
182  %and = and i64 %a, 255
183  %and1 = and i64 %b, 255
184  %shl = shl i64 %and1, 8
185  %or = or i64 %shl, %and
186  ret i64 %or
187}
188
189
190define zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind {
191; RV32I-LABEL: packh_i16:
192; RV32I:       # %bb.0:
193; RV32I-NEXT:    slli a1, a1, 8
194; RV32I-NEXT:    or a0, a1, a0
195; RV32I-NEXT:    ret
196;
197; RV32ZBKB-LABEL: packh_i16:
198; RV32ZBKB:       # %bb.0:
199; RV32ZBKB-NEXT:    packh a0, a0, a1
200; RV32ZBKB-NEXT:    ret
201  %zext = zext i8 %a to i16
202  %zext1 = zext i8 %b to i16
203  %shl = shl i16 %zext1, 8
204  %or = or i16 %shl, %zext
205  ret i16 %or
206}
207
208
209define zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
210; RV32I-LABEL: packh_i16_2:
211; RV32I:       # %bb.0:
212; RV32I-NEXT:    add a0, a1, a0
213; RV32I-NEXT:    andi a0, a0, 255
214; RV32I-NEXT:    slli a0, a0, 8
215; RV32I-NEXT:    or a0, a0, a2
216; RV32I-NEXT:    ret
217;
218; RV32ZBKB-LABEL: packh_i16_2:
219; RV32ZBKB:       # %bb.0:
220; RV32ZBKB-NEXT:    add a0, a1, a0
221; RV32ZBKB-NEXT:    packh a0, a2, a0
222; RV32ZBKB-NEXT:    ret
223  %4 = add i8 %1, %0
224  %5 = zext i8 %4 to i16
225  %6 = shl i16 %5, 8
226  %7 = zext i8 %2 to i16
227  %8 = or i16 %6, %7
228  ret i16 %8
229}
230
231define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) {
232; RV32I-LABEL: packh_i16_3:
233; RV32I:       # %bb.0:
234; RV32I-NEXT:    add a0, a1, a0
235; RV32I-NEXT:    andi a0, a0, 255
236; RV32I-NEXT:    slli a0, a0, 8
237; RV32I-NEXT:    or a0, a0, a2
238; RV32I-NEXT:    sh a0, 0(a3)
239; RV32I-NEXT:    ret
240;
241; RV32ZBKB-LABEL: packh_i16_3:
242; RV32ZBKB:       # %bb.0:
243; RV32ZBKB-NEXT:    add a0, a1, a0
244; RV32ZBKB-NEXT:    packh a0, a2, a0
245; RV32ZBKB-NEXT:    sh a0, 0(a3)
246; RV32ZBKB-NEXT:    ret
247  %4 = add i8 %1, %0
248  %5 = zext i8 %4 to i16
249  %6 = shl i16 %5, 8
250  %7 = zext i8 %2 to i16
251  %8 = or i16 %6, %7
252  store i16 %8, ptr %p
253  ret void
254}
255
256define i32 @zexth_i32(i32 %a) nounwind {
257; RV32I-LABEL: zexth_i32:
258; RV32I:       # %bb.0:
259; RV32I-NEXT:    slli a0, a0, 16
260; RV32I-NEXT:    srli a0, a0, 16
261; RV32I-NEXT:    ret
262;
263; RV32ZBKB-LABEL: zexth_i32:
264; RV32ZBKB:       # %bb.0:
265; RV32ZBKB-NEXT:    zext.h a0, a0
266; RV32ZBKB-NEXT:    ret
267  %and = and i32 %a, 65535
268  ret i32 %and
269}
270
271define i64 @zexth_i64(i64 %a) nounwind {
272; RV32I-LABEL: zexth_i64:
273; RV32I:       # %bb.0:
274; RV32I-NEXT:    slli a0, a0, 16
275; RV32I-NEXT:    srli a0, a0, 16
276; RV32I-NEXT:    li a1, 0
277; RV32I-NEXT:    ret
278;
279; RV32ZBKB-LABEL: zexth_i64:
280; RV32ZBKB:       # %bb.0:
281; RV32ZBKB-NEXT:    zext.h a0, a0
282; RV32ZBKB-NEXT:    li a1, 0
283; RV32ZBKB-NEXT:    ret
284  %and = and i64 %a, 65535
285  ret i64 %and
286}
287
288define i32 @zext_i16_to_i32(i16 %a) nounwind {
289; RV32I-LABEL: zext_i16_to_i32:
290; RV32I:       # %bb.0:
291; RV32I-NEXT:    slli a0, a0, 16
292; RV32I-NEXT:    srli a0, a0, 16
293; RV32I-NEXT:    ret
294;
295; RV32ZBKB-LABEL: zext_i16_to_i32:
296; RV32ZBKB:       # %bb.0:
297; RV32ZBKB-NEXT:    zext.h a0, a0
298; RV32ZBKB-NEXT:    ret
299  %1 = zext i16 %a to i32
300  ret i32 %1
301}
302
303define i64 @zext_i16_to_i64(i16 %a) nounwind {
304; RV32I-LABEL: zext_i16_to_i64:
305; RV32I:       # %bb.0:
306; RV32I-NEXT:    slli a0, a0, 16
307; RV32I-NEXT:    srli a0, a0, 16
308; RV32I-NEXT:    li a1, 0
309; RV32I-NEXT:    ret
310;
311; RV32ZBKB-LABEL: zext_i16_to_i64:
312; RV32ZBKB:       # %bb.0:
313; RV32ZBKB-NEXT:    zext.h a0, a0
314; RV32ZBKB-NEXT:    li a1, 0
315; RV32ZBKB-NEXT:    ret
316  %1 = zext i16 %a to i64
317  ret i64 %1
318}
319