[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / CodeGen / RISCV / GlobalISel / rv32zbb-zbkb.ll
blob68bf9240ccd1df5371292296510facc7076654fc
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=+zbb -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBKB,RV32ZBB
6 ; RUN: llc -mtriple=riscv32 -global-isel -mattr=+zbkb -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBKB,RV32ZBKB
9 define i32 @andn_i32(i32 %a, i32 %b) nounwind {
10 ; RV32I-LABEL: andn_i32:
11 ; RV32I:       # %bb.0:
12 ; RV32I-NEXT:    not a1, a1
13 ; RV32I-NEXT:    and a0, a1, a0
14 ; RV32I-NEXT:    ret
16 ; RV32ZBB-ZBKB-LABEL: andn_i32:
17 ; RV32ZBB-ZBKB:       # %bb.0:
18 ; RV32ZBB-ZBKB-NEXT:    andn a0, a0, a1
19 ; RV32ZBB-ZBKB-NEXT:    ret
20   %neg = xor i32 %b, -1
21   %and = and i32 %neg, %a
22   ret i32 %and
25 define i64 @andn_i64(i64 %a, i64 %b) nounwind {
26 ; RV32I-LABEL: andn_i64:
27 ; RV32I:       # %bb.0:
28 ; RV32I-NEXT:    not a2, a2
29 ; RV32I-NEXT:    not a3, a3
30 ; RV32I-NEXT:    and a0, a2, a0
31 ; RV32I-NEXT:    and a1, a3, a1
32 ; RV32I-NEXT:    ret
34 ; RV32ZBB-ZBKB-LABEL: andn_i64:
35 ; RV32ZBB-ZBKB:       # %bb.0:
36 ; RV32ZBB-ZBKB-NEXT:    andn a0, a0, a2
37 ; RV32ZBB-ZBKB-NEXT:    andn a1, a1, a3
38 ; RV32ZBB-ZBKB-NEXT:    ret
39   %neg = xor i64 %b, -1
40   %and = and i64 %neg, %a
41   ret i64 %and
44 define i32 @orn_i32(i32 %a, i32 %b) nounwind {
45 ; RV32I-LABEL: orn_i32:
46 ; RV32I:       # %bb.0:
47 ; RV32I-NEXT:    not a1, a1
48 ; RV32I-NEXT:    or a0, a1, a0
49 ; RV32I-NEXT:    ret
51 ; RV32ZBB-ZBKB-LABEL: orn_i32:
52 ; RV32ZBB-ZBKB:       # %bb.0:
53 ; RV32ZBB-ZBKB-NEXT:    orn a0, a0, a1
54 ; RV32ZBB-ZBKB-NEXT:    ret
55   %neg = xor i32 %b, -1
56   %or = or i32 %neg, %a
57   ret i32 %or
60 define i64 @orn_i64(i64 %a, i64 %b) nounwind {
61 ; RV32I-LABEL: orn_i64:
62 ; RV32I:       # %bb.0:
63 ; RV32I-NEXT:    not a2, a2
64 ; RV32I-NEXT:    not a3, a3
65 ; RV32I-NEXT:    or a0, a2, a0
66 ; RV32I-NEXT:    or a1, a3, a1
67 ; RV32I-NEXT:    ret
69 ; RV32ZBB-ZBKB-LABEL: orn_i64:
70 ; RV32ZBB-ZBKB:       # %bb.0:
71 ; RV32ZBB-ZBKB-NEXT:    orn a0, a0, a2
72 ; RV32ZBB-ZBKB-NEXT:    orn a1, a1, a3
73 ; RV32ZBB-ZBKB-NEXT:    ret
74   %neg = xor i64 %b, -1
75   %or = or i64 %neg, %a
76   ret i64 %or
79 define i32 @xnor_i32(i32 %a, i32 %b) nounwind {
80 ; RV32I-LABEL: xnor_i32:
81 ; RV32I:       # %bb.0:
82 ; RV32I-NEXT:    not a0, a0
83 ; RV32I-NEXT:    xor a0, a0, a1
84 ; RV32I-NEXT:    ret
86 ; RV32ZBB-ZBKB-LABEL: xnor_i32:
87 ; RV32ZBB-ZBKB:       # %bb.0:
88 ; RV32ZBB-ZBKB-NEXT:    xnor a0, a0, a1
89 ; RV32ZBB-ZBKB-NEXT:    ret
90   %neg = xor i32 %a, -1
91   %xor = xor i32 %neg, %b
92   ret i32 %xor
95 define i64 @xnor_i64(i64 %a, i64 %b) nounwind {
96 ; RV32I-LABEL: xnor_i64:
97 ; RV32I:       # %bb.0:
98 ; RV32I-NEXT:    not a0, a0
99 ; RV32I-NEXT:    not a1, a1
100 ; RV32I-NEXT:    xor a0, a0, a2
101 ; RV32I-NEXT:    xor a1, a1, a3
102 ; RV32I-NEXT:    ret
104 ; RV32ZBB-ZBKB-LABEL: xnor_i64:
105 ; RV32ZBB-ZBKB:       # %bb.0:
106 ; RV32ZBB-ZBKB-NEXT:    xnor a0, a0, a2
107 ; RV32ZBB-ZBKB-NEXT:    xnor a1, a1, a3
108 ; RV32ZBB-ZBKB-NEXT:    ret
109   %neg = xor i64 %a, -1
110   %xor = xor i64 %neg, %b
111   ret i64 %xor
114 declare i32 @llvm.fshl.i32(i32, i32, i32)
116 define i32 @rol_i32(i32 %a, i32 %b) nounwind {
117 ; RV32I-LABEL: rol_i32:
118 ; RV32I:       # %bb.0:
119 ; RV32I-NEXT:    neg a2, a1
120 ; RV32I-NEXT:    sll a1, a0, a1
121 ; RV32I-NEXT:    srl a0, a0, a2
122 ; RV32I-NEXT:    or a0, a1, a0
123 ; RV32I-NEXT:    ret
125 ; RV32ZBB-ZBKB-LABEL: rol_i32:
126 ; RV32ZBB-ZBKB:       # %bb.0:
127 ; RV32ZBB-ZBKB-NEXT:    rol a0, a0, a1
128 ; RV32ZBB-ZBKB-NEXT:    ret
129   %or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)
130   ret i32 %or
133 ; This test is presented here in case future expansions of the Bitmanip
134 ; extensions introduce instructions suitable for this pattern.
136 declare i64 @llvm.fshl.i64(i64, i64, i64)
138 define i64 @rol_i64(i64 %a, i64 %b) nounwind {
139 ; CHECK-LABEL: rol_i64:
140 ; CHECK:       # %bb.0:
141 ; CHECK-NEXT:    andi a6, a2, 63
142 ; CHECK-NEXT:    li a4, 32
143 ; CHECK-NEXT:    bltu a6, a4, .LBB7_2
144 ; CHECK-NEXT:  # %bb.1:
145 ; CHECK-NEXT:    li a3, 0
146 ; CHECK-NEXT:    sll a7, a0, a6
147 ; CHECK-NEXT:    j .LBB7_3
148 ; CHECK-NEXT:  .LBB7_2:
149 ; CHECK-NEXT:    sll a3, a0, a2
150 ; CHECK-NEXT:    neg a5, a6
151 ; CHECK-NEXT:    srl a5, a0, a5
152 ; CHECK-NEXT:    sll a7, a1, a2
153 ; CHECK-NEXT:    or a7, a5, a7
154 ; CHECK-NEXT:  .LBB7_3:
155 ; CHECK-NEXT:    neg a5, a2
156 ; CHECK-NEXT:    mv a2, a1
157 ; CHECK-NEXT:    beqz a6, .LBB7_5
158 ; CHECK-NEXT:  # %bb.4:
159 ; CHECK-NEXT:    mv a2, a7
160 ; CHECK-NEXT:  .LBB7_5:
161 ; CHECK-NEXT:    andi a6, a5, 63
162 ; CHECK-NEXT:    bltu a6, a4, .LBB7_7
163 ; CHECK-NEXT:  # %bb.6:
164 ; CHECK-NEXT:    srl a7, a1, a6
165 ; CHECK-NEXT:    bnez a6, .LBB7_8
166 ; CHECK-NEXT:    j .LBB7_9
167 ; CHECK-NEXT:  .LBB7_7:
168 ; CHECK-NEXT:    srl a7, a0, a5
169 ; CHECK-NEXT:    neg t0, a6
170 ; CHECK-NEXT:    sll t0, a1, t0
171 ; CHECK-NEXT:    or a7, a7, t0
172 ; CHECK-NEXT:    beqz a6, .LBB7_9
173 ; CHECK-NEXT:  .LBB7_8:
174 ; CHECK-NEXT:    mv a0, a7
175 ; CHECK-NEXT:  .LBB7_9:
176 ; CHECK-NEXT:    bltu a6, a4, .LBB7_11
177 ; CHECK-NEXT:  # %bb.10:
178 ; CHECK-NEXT:    li a1, 0
179 ; CHECK-NEXT:    j .LBB7_12
180 ; CHECK-NEXT:  .LBB7_11:
181 ; CHECK-NEXT:    srl a1, a1, a5
182 ; CHECK-NEXT:  .LBB7_12:
183 ; CHECK-NEXT:    or a0, a3, a0
184 ; CHECK-NEXT:    or a1, a2, a1
185 ; CHECK-NEXT:    ret
186   %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
187   ret i64 %or
190 declare i32 @llvm.fshr.i32(i32, i32, i32)
192 define i32 @ror_i32(i32 %a, i32 %b) nounwind {
193 ; RV32I-LABEL: ror_i32:
194 ; RV32I:       # %bb.0:
195 ; RV32I-NEXT:    neg a2, a1
196 ; RV32I-NEXT:    srl a1, a0, a1
197 ; RV32I-NEXT:    sll a0, a0, a2
198 ; RV32I-NEXT:    or a0, a1, a0
199 ; RV32I-NEXT:    ret
201 ; RV32ZBB-ZBKB-LABEL: ror_i32:
202 ; RV32ZBB-ZBKB:       # %bb.0:
203 ; RV32ZBB-ZBKB-NEXT:    ror a0, a0, a1
204 ; RV32ZBB-ZBKB-NEXT:    ret
205   %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)
206   ret i32 %or
209 ; This test is presented here in case future expansions of the Bitmanip
210 ; extensions introduce instructions suitable for this pattern.
212 declare i64 @llvm.fshr.i64(i64, i64, i64)
214 define i64 @ror_i64(i64 %a, i64 %b) nounwind {
215 ; CHECK-LABEL: ror_i64:
216 ; CHECK:       # %bb.0:
217 ; CHECK-NEXT:    andi a5, a2, 63
218 ; CHECK-NEXT:    li a4, 32
219 ; CHECK-NEXT:    bltu a5, a4, .LBB9_2
220 ; CHECK-NEXT:  # %bb.1:
221 ; CHECK-NEXT:    srl a6, a1, a5
222 ; CHECK-NEXT:    mv a3, a0
223 ; CHECK-NEXT:    bnez a5, .LBB9_3
224 ; CHECK-NEXT:    j .LBB9_4
225 ; CHECK-NEXT:  .LBB9_2:
226 ; CHECK-NEXT:    srl a3, a0, a2
227 ; CHECK-NEXT:    neg a6, a5
228 ; CHECK-NEXT:    sll a6, a1, a6
229 ; CHECK-NEXT:    or a6, a3, a6
230 ; CHECK-NEXT:    mv a3, a0
231 ; CHECK-NEXT:    beqz a5, .LBB9_4
232 ; CHECK-NEXT:  .LBB9_3:
233 ; CHECK-NEXT:    mv a3, a6
234 ; CHECK-NEXT:  .LBB9_4:
235 ; CHECK-NEXT:    neg a6, a2
236 ; CHECK-NEXT:    bltu a5, a4, .LBB9_7
237 ; CHECK-NEXT:  # %bb.5:
238 ; CHECK-NEXT:    li a2, 0
239 ; CHECK-NEXT:    andi a5, a6, 63
240 ; CHECK-NEXT:    bgeu a5, a4, .LBB9_8
241 ; CHECK-NEXT:  .LBB9_6:
242 ; CHECK-NEXT:    sll a4, a0, a6
243 ; CHECK-NEXT:    neg a7, a5
244 ; CHECK-NEXT:    srl a0, a0, a7
245 ; CHECK-NEXT:    sll a6, a1, a6
246 ; CHECK-NEXT:    or a0, a0, a6
247 ; CHECK-NEXT:    bnez a5, .LBB9_9
248 ; CHECK-NEXT:    j .LBB9_10
249 ; CHECK-NEXT:  .LBB9_7:
250 ; CHECK-NEXT:    srl a2, a1, a2
251 ; CHECK-NEXT:    andi a5, a6, 63
252 ; CHECK-NEXT:    bltu a5, a4, .LBB9_6
253 ; CHECK-NEXT:  .LBB9_8:
254 ; CHECK-NEXT:    li a4, 0
255 ; CHECK-NEXT:    sll a0, a0, a5
256 ; CHECK-NEXT:    beqz a5, .LBB9_10
257 ; CHECK-NEXT:  .LBB9_9:
258 ; CHECK-NEXT:    mv a1, a0
259 ; CHECK-NEXT:  .LBB9_10:
260 ; CHECK-NEXT:    or a0, a3, a4
261 ; CHECK-NEXT:    or a1, a2, a1
262 ; CHECK-NEXT:    ret
263   %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
264   ret i64 %or
267 define i32 @rori_i32_fshl(i32 %a) nounwind {
268 ; RV32I-LABEL: rori_i32_fshl:
269 ; RV32I:       # %bb.0:
270 ; RV32I-NEXT:    slli a1, a0, 31
271 ; RV32I-NEXT:    srli a0, a0, 1
272 ; RV32I-NEXT:    or a0, a1, a0
273 ; RV32I-NEXT:    ret
275 ; RV32ZBB-ZBKB-LABEL: rori_i32_fshl:
276 ; RV32ZBB-ZBKB:       # %bb.0:
277 ; RV32ZBB-ZBKB-NEXT:    rori a0, a0, 1
278 ; RV32ZBB-ZBKB-NEXT:    ret
279   %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)
280   ret i32 %1
283 define i32 @rori_i32_fshr(i32 %a) nounwind {
284 ; RV32I-LABEL: rori_i32_fshr:
285 ; RV32I:       # %bb.0:
286 ; RV32I-NEXT:    srli a1, a0, 31
287 ; RV32I-NEXT:    slli a0, a0, 1
288 ; RV32I-NEXT:    or a0, a1, a0
289 ; RV32I-NEXT:    ret
291 ; RV32ZBB-ZBKB-LABEL: rori_i32_fshr:
292 ; RV32ZBB-ZBKB:       # %bb.0:
293 ; RV32ZBB-ZBKB-NEXT:    rori a0, a0, 31
294 ; RV32ZBB-ZBKB-NEXT:    ret
295   %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
296   ret i32 %1
299 define i64 @rori_i64(i64 %a) nounwind {
300 ; CHECK-LABEL: rori_i64:
301 ; CHECK:       # %bb.0:
302 ; CHECK-NEXT:    slli a2, a0, 31
303 ; CHECK-NEXT:    srli a0, a0, 1
304 ; CHECK-NEXT:    slli a3, a1, 31
305 ; CHECK-NEXT:    srli a1, a1, 1
306 ; CHECK-NEXT:    or a0, a0, a3
307 ; CHECK-NEXT:    or a1, a2, a1
308 ; CHECK-NEXT:    ret
309   %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)
310   ret i64 %1
313 define i64 @rori_i64_fshr(i64 %a) nounwind {
314 ; CHECK-LABEL: rori_i64_fshr:
315 ; CHECK:       # %bb.0:
316 ; CHECK-NEXT:    srli a2, a1, 31
317 ; CHECK-NEXT:    slli a3, a0, 1
318 ; CHECK-NEXT:    slli a1, a1, 1
319 ; CHECK-NEXT:    srli a0, a0, 31
320 ; CHECK-NEXT:    or a1, a1, a0
321 ; CHECK-NEXT:    or a0, a2, a3
322 ; CHECK-NEXT:    ret
323   %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
324   ret i64 %1
327 define i8 @srli_i8(i8 %a) nounwind {
328 ; CHECK-LABEL: srli_i8:
329 ; CHECK:       # %bb.0:
330 ; CHECK-NEXT:    andi a0, a0, 255
331 ; CHECK-NEXT:    srli a0, a0, 6
332 ; CHECK-NEXT:    ret
333   %1 = lshr i8 %a, 6
334   ret i8 %1
337 ; FIXME: We should use slli+srai with Zbb for better compression.
338 define i8 @srai_i8(i8 %a) nounwind {
339 ; RV32I-LABEL: srai_i8:
340 ; RV32I:       # %bb.0:
341 ; RV32I-NEXT:    slli a0, a0, 24
342 ; RV32I-NEXT:    srai a0, a0, 29
343 ; RV32I-NEXT:    ret
345 ; RV32ZBB-LABEL: srai_i8:
346 ; RV32ZBB:       # %bb.0:
347 ; RV32ZBB-NEXT:    sext.b a0, a0
348 ; RV32ZBB-NEXT:    srai a0, a0, 5
349 ; RV32ZBB-NEXT:    ret
351 ; RV32ZBKB-LABEL: srai_i8:
352 ; RV32ZBKB:       # %bb.0:
353 ; RV32ZBKB-NEXT:    slli a0, a0, 24
354 ; RV32ZBKB-NEXT:    srai a0, a0, 29
355 ; RV32ZBKB-NEXT:    ret
356   %1 = ashr i8 %a, 5
357   ret i8 %1
360 ; FIXME: We should use slli+srli.
361 define i16 @srli_i16(i16 %a) nounwind {
362 ; RV32I-LABEL: srli_i16:
363 ; RV32I:       # %bb.0:
364 ; RV32I-NEXT:    lui a1, 16
365 ; RV32I-NEXT:    addi a1, a1, -1
366 ; RV32I-NEXT:    and a0, a0, a1
367 ; RV32I-NEXT:    srli a0, a0, 6
368 ; RV32I-NEXT:    ret
370 ; RV32ZBB-ZBKB-LABEL: srli_i16:
371 ; RV32ZBB-ZBKB:       # %bb.0:
372 ; RV32ZBB-ZBKB-NEXT:    zext.h a0, a0
373 ; RV32ZBB-ZBKB-NEXT:    srli a0, a0, 6
374 ; RV32ZBB-ZBKB-NEXT:    ret
375   %1 = lshr i16 %a, 6
376   ret i16 %1
379 ; FIXME: We should use slli+srai with Zbb/Zbkb for better compression.
380 define i16 @srai_i16(i16 %a) nounwind {
381 ; RV32I-LABEL: srai_i16:
382 ; RV32I:       # %bb.0:
383 ; RV32I-NEXT:    slli a0, a0, 16
384 ; RV32I-NEXT:    srai a0, a0, 25
385 ; RV32I-NEXT:    ret
387 ; RV32ZBB-LABEL: srai_i16:
388 ; RV32ZBB:       # %bb.0:
389 ; RV32ZBB-NEXT:    sext.h a0, a0
390 ; RV32ZBB-NEXT:    srai a0, a0, 9
391 ; RV32ZBB-NEXT:    ret
393 ; RV32ZBKB-LABEL: srai_i16:
394 ; RV32ZBKB:       # %bb.0:
395 ; RV32ZBKB-NEXT:    slli a0, a0, 16
396 ; RV32ZBKB-NEXT:    srai a0, a0, 25
397 ; RV32ZBKB-NEXT:    ret
398   %1 = ashr i16 %a, 9
399   ret i16 %1