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
7 define i32 @pack_i32(i32 %a, i32 %b) nounwind {
8 ; RV32I-LABEL: pack_i32:
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
16 ; RV32ZBKB-LABEL: pack_i32:
18 ; RV32ZBKB-NEXT: pack a0, a0, a1
20 %shl = and i32 %a, 65535
21 %shl1 = shl i32 %b, 16
22 %or = or i32 %shl1, %shl
26 define i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind {
27 ; RV32I-LABEL: pack_i32_2:
29 ; RV32I-NEXT: slli a1, a1, 16
30 ; RV32I-NEXT: or a0, a1, a0
33 ; RV32ZBKB-LABEL: pack_i32_2:
35 ; RV32ZBKB-NEXT: pack a0, a0, a1
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
44 define i32 @pack_i32_3(i16 zeroext %0, i16 zeroext %1, i32 %2) {
45 ; RV32I-LABEL: pack_i32_3:
47 ; RV32I-NEXT: slli a0, a0, 16
48 ; RV32I-NEXT: or a0, a0, a1
49 ; RV32I-NEXT: add a0, a0, a2
52 ; RV32ZBKB-LABEL: pack_i32_3:
54 ; RV32ZBKB-NEXT: pack a0, a1, a0
55 ; RV32ZBKB-NEXT: add a0, a0, a2
57 %4 = zext i16 %0 to i32
58 %5 = shl nuw i32 %4, 16
59 %6 = zext i16 %1 to i32
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.
70 define i64 @pack_i64(i64 %a, i64 %b) nounwind {
71 ; CHECK-LABEL: pack_i64:
73 ; CHECK-NEXT: mv a1, a2
75 %shl = and i64 %a, 4294967295
76 %shl1 = shl i64 %b, 32
77 %or = or i64 %shl1, %shl
81 define i64 @pack_i64_2(i32 %a, i32 %b) nounwind {
82 ; CHECK-LABEL: pack_i64_2:
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
92 define i64 @pack_i64_3(ptr %0, ptr %1) {
93 ; CHECK-LABEL: pack_i64_3:
95 ; CHECK-NEXT: lw a2, 0(a0)
96 ; CHECK-NEXT: lw a0, 0(a1)
97 ; CHECK-NEXT: mv a1, a2
99 %3 = load i32, ptr %0, align 4
100 %4 = zext i32 %3 to i64
102 %6 = load i32, ptr %1, align 4
103 %7 = zext i32 %6 to i64
108 define i32 @packh_i32(i32 %a, i32 %b) nounwind {
109 ; RV32I-LABEL: packh_i32:
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
117 ; RV32ZBKB-LABEL: packh_i32:
119 ; RV32ZBKB-NEXT: packh a0, a0, a1
121 %and = and i32 %a, 255
122 %and1 = shl i32 %b, 8
123 %shl = and i32 %and1, 65280
124 %or = or i32 %shl, %and
128 define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
129 ; RV32I-LABEL: packh_i32_2:
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
137 ; RV32ZBKB-LABEL: packh_i32_2:
139 ; RV32ZBKB-NEXT: packh a0, a0, a1
141 %and = and i32 %a, 255
142 %and1 = and i32 %b, 255
143 %shl = shl i32 %and1, 8
144 %or = or i32 %shl, %and
148 define i64 @packh_i64(i64 %a, i64 %b) nounwind {
149 ; RV32I-LABEL: packh_i64:
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
158 ; RV32ZBKB-LABEL: packh_i64:
160 ; RV32ZBKB-NEXT: packh a0, a0, a2
161 ; RV32ZBKB-NEXT: li a1, 0
163 %and = and i64 %a, 255
164 %and1 = shl i64 %b, 8
165 %shl = and i64 %and1, 65280
166 %or = or i64 %shl, %and
170 define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
171 ; RV32I-LABEL: packh_i64_2:
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
180 ; RV32ZBKB-LABEL: packh_i64_2:
182 ; RV32ZBKB-NEXT: packh a0, a0, a2
183 ; RV32ZBKB-NEXT: li a1, 0
185 %and = and i64 %a, 255
186 %and1 = and i64 %b, 255
187 %shl = shl i64 %and1, 8
188 %or = or i64 %shl, %and
193 define zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind {
194 ; RV32I-LABEL: packh_i16:
196 ; RV32I-NEXT: slli a1, a1, 8
197 ; RV32I-NEXT: or a0, a1, a0
200 ; RV32ZBKB-LABEL: packh_i16:
202 ; RV32ZBKB-NEXT: packh a0, a0, a1
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
212 define zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
213 ; RV32I-LABEL: packh_i16_2:
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
222 ; RV32ZBKB-LABEL: packh_i16_2:
224 ; RV32ZBKB-NEXT: add a0, a1, a0
225 ; RV32ZBKB-NEXT: packh a0, a2, a0
228 %5 = zext i8 %4 to i16
230 %7 = zext i8 %2 to i16
235 define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) {
236 ; RV32I-LABEL: packh_i16_3:
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)
244 ; RV32ZBKB-LABEL: packh_i16_3:
246 ; RV32ZBKB-NEXT: add a0, a1, a0
247 ; RV32ZBKB-NEXT: packh a0, a2, a0
248 ; RV32ZBKB-NEXT: sh a0, 0(a3)
251 %5 = zext i8 %4 to i16
253 %7 = zext i8 %2 to i16
259 define i32 @zexth_i32(i32 %a) nounwind {
260 ; RV32I-LABEL: zexth_i32:
262 ; RV32I-NEXT: slli a0, a0, 16
263 ; RV32I-NEXT: srli a0, a0, 16
266 ; RV32ZBKB-LABEL: zexth_i32:
268 ; RV32ZBKB-NEXT: zext.h a0, a0
270 %and = and i32 %a, 65535
274 define i64 @zexth_i64(i64 %a) nounwind {
275 ; RV32I-LABEL: zexth_i64:
277 ; RV32I-NEXT: slli a0, a0, 16
278 ; RV32I-NEXT: srli a0, a0, 16
279 ; RV32I-NEXT: li a1, 0
282 ; RV32ZBKB-LABEL: zexth_i64:
284 ; RV32ZBKB-NEXT: zext.h a0, a0
285 ; RV32ZBKB-NEXT: li a1, 0
287 %and = and i64 %a, 65535
291 define i32 @zext_i16_to_i32(i16 %a) nounwind {
292 ; RV32I-LABEL: zext_i16_to_i32:
294 ; RV32I-NEXT: slli a0, a0, 16
295 ; RV32I-NEXT: srli a0, a0, 16
298 ; RV32ZBKB-LABEL: zext_i16_to_i32:
300 ; RV32ZBKB-NEXT: zext.h a0, a0
302 %1 = zext i16 %a to i32
306 define i64 @zext_i16_to_i64(i16 %a) nounwind {
307 ; RV32I-LABEL: zext_i16_to_i64:
309 ; RV32I-NEXT: slli a0, a0, 16
310 ; RV32I-NEXT: srli a0, a0, 16
311 ; RV32I-NEXT: li a1, 0
314 ; RV32ZBKB-LABEL: zext_i16_to_i64:
316 ; RV32ZBKB-NEXT: zext.h a0, a0
317 ; RV32ZBKB-NEXT: li a1, 0
319 %1 = zext i16 %a to i64