[MLIR] Prevent invalid IR from being passed outside of RemoveDeadValues (#121079)
[llvm-project.git] / llvm / test / CodeGen / RISCV / GlobalISel / rv32zbkb.ll
blobb214cf68ddce86588d4b7935e35065716fa6abb9
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:
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
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
26 define 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
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
44 define 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
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
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:
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
81 define 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
92 define 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
108 ; FIXME: Use packh.
109 define 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
126 define 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
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
146 ; FIMXE: Use packh
147 define 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
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:
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
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
190 define 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
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
209 define 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
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
231 define 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
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
256 define 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
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
271 define 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
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
288 define 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
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
303 define 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
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