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
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
109 define i32 @packh_i32(i32 %a, i32 %b) nounwind {
110 ; CHECK-LABEL: packh_i32:
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
119 %and = and i32 %a, 255
120 %and1 = shl i32 %b, 8
121 %shl = and i32 %and1, 65280
122 %or = or i32 %shl, %and
126 define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
127 ; RV32I-LABEL: packh_i32_2:
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
135 ; RV32ZBKB-LABEL: packh_i32_2:
137 ; RV32ZBKB-NEXT: packh a0, a0, a1
139 %and = and i32 %a, 255
140 %and1 = and i32 %b, 255
141 %shl = shl i32 %and1, 8
142 %or = or i32 %shl, %and
147 define i64 @packh_i64(i64 %a, i64 %b) nounwind {
148 ; CHECK-LABEL: packh_i64:
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
158 %and = and i64 %a, 255
159 %and1 = shl i64 %b, 8
160 %shl = and i64 %and1, 65280
161 %or = or i64 %shl, %and
165 ; FIXME The andi+srli for RV32ZBKB should fold to 0.
166 define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
167 ; RV32I-LABEL: packh_i64_2:
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
176 ; RV32ZBKB-LABEL: packh_i64_2:
178 ; RV32ZBKB-NEXT: andi a1, a2, 255
179 ; RV32ZBKB-NEXT: srli a1, a1, 24
180 ; RV32ZBKB-NEXT: packh a0, a0, a2
182 %and = and i64 %a, 255
183 %and1 = and i64 %b, 255
184 %shl = shl i64 %and1, 8
185 %or = or i64 %shl, %and
190 define zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind {
191 ; RV32I-LABEL: packh_i16:
193 ; RV32I-NEXT: slli a1, a1, 8
194 ; RV32I-NEXT: or a0, a1, a0
197 ; RV32ZBKB-LABEL: packh_i16:
199 ; RV32ZBKB-NEXT: packh a0, a0, a1
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
209 define zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
210 ; RV32I-LABEL: packh_i16_2:
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
218 ; RV32ZBKB-LABEL: packh_i16_2:
220 ; RV32ZBKB-NEXT: add a0, a1, a0
221 ; RV32ZBKB-NEXT: packh a0, a2, a0
224 %5 = zext i8 %4 to i16
226 %7 = zext i8 %2 to i16
231 define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) {
232 ; RV32I-LABEL: packh_i16_3:
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)
241 ; RV32ZBKB-LABEL: packh_i16_3:
243 ; RV32ZBKB-NEXT: add a0, a1, a0
244 ; RV32ZBKB-NEXT: packh a0, a2, a0
245 ; RV32ZBKB-NEXT: sh a0, 0(a3)
248 %5 = zext i8 %4 to i16
250 %7 = zext i8 %2 to i16
256 define i32 @zexth_i32(i32 %a) nounwind {
257 ; RV32I-LABEL: zexth_i32:
259 ; RV32I-NEXT: slli a0, a0, 16
260 ; RV32I-NEXT: srli a0, a0, 16
263 ; RV32ZBKB-LABEL: zexth_i32:
265 ; RV32ZBKB-NEXT: zext.h a0, a0
267 %and = and i32 %a, 65535
271 define i64 @zexth_i64(i64 %a) nounwind {
272 ; RV32I-LABEL: zexth_i64:
274 ; RV32I-NEXT: slli a0, a0, 16
275 ; RV32I-NEXT: srli a0, a0, 16
276 ; RV32I-NEXT: li a1, 0
279 ; RV32ZBKB-LABEL: zexth_i64:
281 ; RV32ZBKB-NEXT: zext.h a0, a0
282 ; RV32ZBKB-NEXT: li a1, 0
284 %and = and i64 %a, 65535
288 define i32 @zext_i16_to_i32(i16 %a) nounwind {
289 ; RV32I-LABEL: zext_i16_to_i32:
291 ; RV32I-NEXT: slli a0, a0, 16
292 ; RV32I-NEXT: srli a0, a0, 16
295 ; RV32ZBKB-LABEL: zext_i16_to_i32:
297 ; RV32ZBKB-NEXT: zext.h a0, a0
299 %1 = zext i16 %a to i32
303 define i64 @zext_i16_to_i64(i16 %a) nounwind {
304 ; RV32I-LABEL: zext_i16_to_i64:
306 ; RV32I-NEXT: slli a0, a0, 16
307 ; RV32I-NEXT: srli a0, a0, 16
308 ; RV32I-NEXT: li a1, 0
311 ; RV32ZBKB-LABEL: zext_i16_to_i64:
313 ; RV32ZBKB-NEXT: zext.h a0, a0
314 ; RV32ZBKB-NEXT: li a1, 0
316 %1 = zext i16 %a to i64