[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv32zbt.ll
blob6b420dea50e8acdc488158eb154caee524dd1415
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-prefix=RV32I
4 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-b -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck %s -check-prefix=RV32B
6 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck %s -check-prefix=RV32ZBT
9 define i32 @cmix_i32(i32 %a, i32 %b, i32 %c) nounwind {
10 ; RV32I-LABEL: cmix_i32:
11 ; RV32I:       # %bb.0:
12 ; RV32I-NEXT:    and a0, a1, a0
13 ; RV32I-NEXT:    not a1, a1
14 ; RV32I-NEXT:    and a1, a1, a2
15 ; RV32I-NEXT:    or a0, a1, a0
16 ; RV32I-NEXT:    ret
18 ; RV32B-LABEL: cmix_i32:
19 ; RV32B:       # %bb.0:
20 ; RV32B-NEXT:    cmix a0, a1, a0, a2
21 ; RV32B-NEXT:    ret
23 ; RV32ZBT-LABEL: cmix_i32:
24 ; RV32ZBT:       # %bb.0:
25 ; RV32ZBT-NEXT:    cmix a0, a1, a0, a2
26 ; RV32ZBT-NEXT:    ret
27   %and = and i32 %b, %a
28   %neg = xor i32 %b, -1
29   %and1 = and i32 %neg, %c
30   %or = or i32 %and1, %and
31   ret i32 %or
34 define i64 @cmix_i64(i64 %a, i64 %b, i64 %c) nounwind {
35 ; RV32I-LABEL: cmix_i64:
36 ; RV32I:       # %bb.0:
37 ; RV32I-NEXT:    and a1, a3, a1
38 ; RV32I-NEXT:    and a0, a2, a0
39 ; RV32I-NEXT:    not a2, a2
40 ; RV32I-NEXT:    not a3, a3
41 ; RV32I-NEXT:    and a3, a3, a5
42 ; RV32I-NEXT:    and a2, a2, a4
43 ; RV32I-NEXT:    or a0, a2, a0
44 ; RV32I-NEXT:    or a1, a3, a1
45 ; RV32I-NEXT:    ret
47 ; RV32B-LABEL: cmix_i64:
48 ; RV32B:       # %bb.0:
49 ; RV32B-NEXT:    cmix a0, a2, a0, a4
50 ; RV32B-NEXT:    cmix a1, a3, a1, a5
51 ; RV32B-NEXT:    ret
53 ; RV32ZBT-LABEL: cmix_i64:
54 ; RV32ZBT:       # %bb.0:
55 ; RV32ZBT-NEXT:    cmix a0, a2, a0, a4
56 ; RV32ZBT-NEXT:    cmix a1, a3, a1, a5
57 ; RV32ZBT-NEXT:    ret
58   %and = and i64 %b, %a
59   %neg = xor i64 %b, -1
60   %and1 = and i64 %neg, %c
61   %or = or i64 %and1, %and
62   ret i64 %or
65 define i32 @cmov_i32(i32 %a, i32 %b, i32 %c) nounwind {
66 ; RV32I-LABEL: cmov_i32:
67 ; RV32I:       # %bb.0:
68 ; RV32I-NEXT:    beqz a1, .LBB2_2
69 ; RV32I-NEXT:  # %bb.1:
70 ; RV32I-NEXT:    mv a2, a0
71 ; RV32I-NEXT:  .LBB2_2:
72 ; RV32I-NEXT:    mv a0, a2
73 ; RV32I-NEXT:    ret
75 ; RV32B-LABEL: cmov_i32:
76 ; RV32B:       # %bb.0:
77 ; RV32B-NEXT:    cmov a0, a1, a0, a2
78 ; RV32B-NEXT:    ret
80 ; RV32ZBT-LABEL: cmov_i32:
81 ; RV32ZBT:       # %bb.0:
82 ; RV32ZBT-NEXT:    cmov a0, a1, a0, a2
83 ; RV32ZBT-NEXT:    ret
84   %tobool.not = icmp eq i32 %b, 0
85   %cond = select i1 %tobool.not, i32 %c, i32 %a
86   ret i32 %cond
89 define i32 @cmov_sle_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
90 ; RV32I-LABEL: cmov_sle_i32:
91 ; RV32I:       # %bb.0:
92 ; RV32I-NEXT:    bge a2, a1, .LBB3_2
93 ; RV32I-NEXT:  # %bb.1:
94 ; RV32I-NEXT:    mv a0, a3
95 ; RV32I-NEXT:  .LBB3_2:
96 ; RV32I-NEXT:    ret
98 ; RV32B-LABEL: cmov_sle_i32:
99 ; RV32B:       # %bb.0:
100 ; RV32B-NEXT:    slt a1, a2, a1
101 ; RV32B-NEXT:    cmov a0, a1, a3, a0
102 ; RV32B-NEXT:    ret
104 ; RV32ZBT-LABEL: cmov_sle_i32:
105 ; RV32ZBT:       # %bb.0:
106 ; RV32ZBT-NEXT:    slt a1, a2, a1
107 ; RV32ZBT-NEXT:    cmov a0, a1, a3, a0
108 ; RV32ZBT-NEXT:    ret
109   %tobool = icmp sle i32 %b, %c
110   %cond = select i1 %tobool, i32 %a, i32 %d
111   ret i32 %cond
114 define i32 @cmov_sge_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
115 ; RV32I-LABEL: cmov_sge_i32:
116 ; RV32I:       # %bb.0:
117 ; RV32I-NEXT:    bge a1, a2, .LBB4_2
118 ; RV32I-NEXT:  # %bb.1:
119 ; RV32I-NEXT:    mv a0, a3
120 ; RV32I-NEXT:  .LBB4_2:
121 ; RV32I-NEXT:    ret
123 ; RV32B-LABEL: cmov_sge_i32:
124 ; RV32B:       # %bb.0:
125 ; RV32B-NEXT:    slt a1, a1, a2
126 ; RV32B-NEXT:    cmov a0, a1, a3, a0
127 ; RV32B-NEXT:    ret
129 ; RV32ZBT-LABEL: cmov_sge_i32:
130 ; RV32ZBT:       # %bb.0:
131 ; RV32ZBT-NEXT:    slt a1, a1, a2
132 ; RV32ZBT-NEXT:    cmov a0, a1, a3, a0
133 ; RV32ZBT-NEXT:    ret
134   %tobool = icmp sge i32 %b, %c
135   %cond = select i1 %tobool, i32 %a, i32 %d
136   ret i32 %cond
139 define i32 @cmov_ule_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
140 ; RV32I-LABEL: cmov_ule_i32:
141 ; RV32I:       # %bb.0:
142 ; RV32I-NEXT:    bgeu a2, a1, .LBB5_2
143 ; RV32I-NEXT:  # %bb.1:
144 ; RV32I-NEXT:    mv a0, a3
145 ; RV32I-NEXT:  .LBB5_2:
146 ; RV32I-NEXT:    ret
148 ; RV32B-LABEL: cmov_ule_i32:
149 ; RV32B:       # %bb.0:
150 ; RV32B-NEXT:    sltu a1, a2, a1
151 ; RV32B-NEXT:    cmov a0, a1, a3, a0
152 ; RV32B-NEXT:    ret
154 ; RV32ZBT-LABEL: cmov_ule_i32:
155 ; RV32ZBT:       # %bb.0:
156 ; RV32ZBT-NEXT:    sltu a1, a2, a1
157 ; RV32ZBT-NEXT:    cmov a0, a1, a3, a0
158 ; RV32ZBT-NEXT:    ret
159   %tobool = icmp ule i32 %b, %c
160   %cond = select i1 %tobool, i32 %a, i32 %d
161   ret i32 %cond
164 define i32 @cmov_uge_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
165 ; RV32I-LABEL: cmov_uge_i32:
166 ; RV32I:       # %bb.0:
167 ; RV32I-NEXT:    bgeu a1, a2, .LBB6_2
168 ; RV32I-NEXT:  # %bb.1:
169 ; RV32I-NEXT:    mv a0, a3
170 ; RV32I-NEXT:  .LBB6_2:
171 ; RV32I-NEXT:    ret
173 ; RV32B-LABEL: cmov_uge_i32:
174 ; RV32B:       # %bb.0:
175 ; RV32B-NEXT:    sltu a1, a1, a2
176 ; RV32B-NEXT:    cmov a0, a1, a3, a0
177 ; RV32B-NEXT:    ret
179 ; RV32ZBT-LABEL: cmov_uge_i32:
180 ; RV32ZBT:       # %bb.0:
181 ; RV32ZBT-NEXT:    sltu a1, a1, a2
182 ; RV32ZBT-NEXT:    cmov a0, a1, a3, a0
183 ; RV32ZBT-NEXT:    ret
184   %tobool = icmp uge i32 %b, %c
185   %cond = select i1 %tobool, i32 %a, i32 %d
186   ret i32 %cond
189 define i64 @cmov_i64(i64 %a, i64 %b, i64 %c) nounwind {
190 ; RV32I-LABEL: cmov_i64:
191 ; RV32I:       # %bb.0:
192 ; RV32I-NEXT:    or a2, a2, a3
193 ; RV32I-NEXT:    beqz a2, .LBB7_2
194 ; RV32I-NEXT:  # %bb.1:
195 ; RV32I-NEXT:    mv a4, a0
196 ; RV32I-NEXT:    mv a5, a1
197 ; RV32I-NEXT:  .LBB7_2:
198 ; RV32I-NEXT:    mv a0, a4
199 ; RV32I-NEXT:    mv a1, a5
200 ; RV32I-NEXT:    ret
202 ; RV32B-LABEL: cmov_i64:
203 ; RV32B:       # %bb.0:
204 ; RV32B-NEXT:    or a2, a2, a3
205 ; RV32B-NEXT:    cmov a0, a2, a0, a4
206 ; RV32B-NEXT:    cmov a1, a2, a1, a5
207 ; RV32B-NEXT:    ret
209 ; RV32ZBT-LABEL: cmov_i64:
210 ; RV32ZBT:       # %bb.0:
211 ; RV32ZBT-NEXT:    or a2, a2, a3
212 ; RV32ZBT-NEXT:    cmov a0, a2, a0, a4
213 ; RV32ZBT-NEXT:    cmov a1, a2, a1, a5
214 ; RV32ZBT-NEXT:    ret
215   %tobool.not = icmp eq i64 %b, 0
216   %cond = select i1 %tobool.not, i64 %c, i64 %a
217   ret i64 %cond
220 define i64 @cmov_sle_i64(i64 %a, i64 %b, i64 %c, i64 %d) nounwind {
221 ; RV32I-LABEL: cmov_sle_i64:
222 ; RV32I:       # %bb.0:
223 ; RV32I-NEXT:    beq a3, a5, .LBB8_2
224 ; RV32I-NEXT:  # %bb.1:
225 ; RV32I-NEXT:    slt a2, a5, a3
226 ; RV32I-NEXT:    xori a2, a2, 1
227 ; RV32I-NEXT:    beqz a2, .LBB8_3
228 ; RV32I-NEXT:    j .LBB8_4
229 ; RV32I-NEXT:  .LBB8_2:
230 ; RV32I-NEXT:    sltu a2, a4, a2
231 ; RV32I-NEXT:    xori a2, a2, 1
232 ; RV32I-NEXT:    bnez a2, .LBB8_4
233 ; RV32I-NEXT:  .LBB8_3:
234 ; RV32I-NEXT:    mv a0, a6
235 ; RV32I-NEXT:    mv a1, a7
236 ; RV32I-NEXT:  .LBB8_4:
237 ; RV32I-NEXT:    ret
239 ; RV32B-LABEL: cmov_sle_i64:
240 ; RV32B:       # %bb.0:
241 ; RV32B-NEXT:    xor t0, a3, a5
242 ; RV32B-NEXT:    sltu a2, a4, a2
243 ; RV32B-NEXT:    xori a2, a2, 1
244 ; RV32B-NEXT:    slt a3, a5, a3
245 ; RV32B-NEXT:    xori a3, a3, 1
246 ; RV32B-NEXT:    cmov a2, t0, a3, a2
247 ; RV32B-NEXT:    cmov a0, a2, a0, a6
248 ; RV32B-NEXT:    cmov a1, a2, a1, a7
249 ; RV32B-NEXT:    ret
251 ; RV32ZBT-LABEL: cmov_sle_i64:
252 ; RV32ZBT:       # %bb.0:
253 ; RV32ZBT-NEXT:    xor t0, a3, a5
254 ; RV32ZBT-NEXT:    sltu a2, a4, a2
255 ; RV32ZBT-NEXT:    xori a2, a2, 1
256 ; RV32ZBT-NEXT:    slt a3, a5, a3
257 ; RV32ZBT-NEXT:    xori a3, a3, 1
258 ; RV32ZBT-NEXT:    cmov a2, t0, a3, a2
259 ; RV32ZBT-NEXT:    cmov a0, a2, a0, a6
260 ; RV32ZBT-NEXT:    cmov a1, a2, a1, a7
261 ; RV32ZBT-NEXT:    ret
262   %tobool = icmp sle i64 %b, %c
263   %cond = select i1 %tobool, i64 %a, i64 %d
264   ret i64 %cond
267 define i64 @cmov_sge_i64(i64 %a, i64 %b, i64 %c, i64 %d) nounwind {
268 ; RV32I-LABEL: cmov_sge_i64:
269 ; RV32I:       # %bb.0:
270 ; RV32I-NEXT:    beq a3, a5, .LBB9_2
271 ; RV32I-NEXT:  # %bb.1:
272 ; RV32I-NEXT:    slt a2, a3, a5
273 ; RV32I-NEXT:    xori a2, a2, 1
274 ; RV32I-NEXT:    beqz a2, .LBB9_3
275 ; RV32I-NEXT:    j .LBB9_4
276 ; RV32I-NEXT:  .LBB9_2:
277 ; RV32I-NEXT:    sltu a2, a2, a4
278 ; RV32I-NEXT:    xori a2, a2, 1
279 ; RV32I-NEXT:    bnez a2, .LBB9_4
280 ; RV32I-NEXT:  .LBB9_3:
281 ; RV32I-NEXT:    mv a0, a6
282 ; RV32I-NEXT:    mv a1, a7
283 ; RV32I-NEXT:  .LBB9_4:
284 ; RV32I-NEXT:    ret
286 ; RV32B-LABEL: cmov_sge_i64:
287 ; RV32B:       # %bb.0:
288 ; RV32B-NEXT:    xor t0, a3, a5
289 ; RV32B-NEXT:    sltu a2, a2, a4
290 ; RV32B-NEXT:    xori a2, a2, 1
291 ; RV32B-NEXT:    slt a3, a3, a5
292 ; RV32B-NEXT:    xori a3, a3, 1
293 ; RV32B-NEXT:    cmov a2, t0, a3, a2
294 ; RV32B-NEXT:    cmov a0, a2, a0, a6
295 ; RV32B-NEXT:    cmov a1, a2, a1, a7
296 ; RV32B-NEXT:    ret
298 ; RV32ZBT-LABEL: cmov_sge_i64:
299 ; RV32ZBT:       # %bb.0:
300 ; RV32ZBT-NEXT:    xor t0, a3, a5
301 ; RV32ZBT-NEXT:    sltu a2, a2, a4
302 ; RV32ZBT-NEXT:    xori a2, a2, 1
303 ; RV32ZBT-NEXT:    slt a3, a3, a5
304 ; RV32ZBT-NEXT:    xori a3, a3, 1
305 ; RV32ZBT-NEXT:    cmov a2, t0, a3, a2
306 ; RV32ZBT-NEXT:    cmov a0, a2, a0, a6
307 ; RV32ZBT-NEXT:    cmov a1, a2, a1, a7
308 ; RV32ZBT-NEXT:    ret
309   %tobool = icmp sge i64 %b, %c
310   %cond = select i1 %tobool, i64 %a, i64 %d
311   ret i64 %cond
314 define i64 @cmov_ule_i64(i64 %a, i64 %b, i64 %c, i64 %d) nounwind {
315 ; RV32I-LABEL: cmov_ule_i64:
316 ; RV32I:       # %bb.0:
317 ; RV32I-NEXT:    beq a3, a5, .LBB10_2
318 ; RV32I-NEXT:  # %bb.1:
319 ; RV32I-NEXT:    sltu a2, a5, a3
320 ; RV32I-NEXT:    xori a2, a2, 1
321 ; RV32I-NEXT:    beqz a2, .LBB10_3
322 ; RV32I-NEXT:    j .LBB10_4
323 ; RV32I-NEXT:  .LBB10_2:
324 ; RV32I-NEXT:    sltu a2, a4, a2
325 ; RV32I-NEXT:    xori a2, a2, 1
326 ; RV32I-NEXT:    bnez a2, .LBB10_4
327 ; RV32I-NEXT:  .LBB10_3:
328 ; RV32I-NEXT:    mv a0, a6
329 ; RV32I-NEXT:    mv a1, a7
330 ; RV32I-NEXT:  .LBB10_4:
331 ; RV32I-NEXT:    ret
333 ; RV32B-LABEL: cmov_ule_i64:
334 ; RV32B:       # %bb.0:
335 ; RV32B-NEXT:    xor t0, a3, a5
336 ; RV32B-NEXT:    sltu a2, a4, a2
337 ; RV32B-NEXT:    xori a2, a2, 1
338 ; RV32B-NEXT:    sltu a3, a5, a3
339 ; RV32B-NEXT:    xori a3, a3, 1
340 ; RV32B-NEXT:    cmov a2, t0, a3, a2
341 ; RV32B-NEXT:    cmov a0, a2, a0, a6
342 ; RV32B-NEXT:    cmov a1, a2, a1, a7
343 ; RV32B-NEXT:    ret
345 ; RV32ZBT-LABEL: cmov_ule_i64:
346 ; RV32ZBT:       # %bb.0:
347 ; RV32ZBT-NEXT:    xor t0, a3, a5
348 ; RV32ZBT-NEXT:    sltu a2, a4, a2
349 ; RV32ZBT-NEXT:    xori a2, a2, 1
350 ; RV32ZBT-NEXT:    sltu a3, a5, a3
351 ; RV32ZBT-NEXT:    xori a3, a3, 1
352 ; RV32ZBT-NEXT:    cmov a2, t0, a3, a2
353 ; RV32ZBT-NEXT:    cmov a0, a2, a0, a6
354 ; RV32ZBT-NEXT:    cmov a1, a2, a1, a7
355 ; RV32ZBT-NEXT:    ret
356   %tobool = icmp ule i64 %b, %c
357   %cond = select i1 %tobool, i64 %a, i64 %d
358   ret i64 %cond
361 define i64 @cmov_uge_i64(i64 %a, i64 %b, i64 %c, i64 %d) nounwind {
362 ; RV32I-LABEL: cmov_uge_i64:
363 ; RV32I:       # %bb.0:
364 ; RV32I-NEXT:    beq a3, a5, .LBB11_2
365 ; RV32I-NEXT:  # %bb.1:
366 ; RV32I-NEXT:    sltu a2, a3, a5
367 ; RV32I-NEXT:    xori a2, a2, 1
368 ; RV32I-NEXT:    beqz a2, .LBB11_3
369 ; RV32I-NEXT:    j .LBB11_4
370 ; RV32I-NEXT:  .LBB11_2:
371 ; RV32I-NEXT:    sltu a2, a2, a4
372 ; RV32I-NEXT:    xori a2, a2, 1
373 ; RV32I-NEXT:    bnez a2, .LBB11_4
374 ; RV32I-NEXT:  .LBB11_3:
375 ; RV32I-NEXT:    mv a0, a6
376 ; RV32I-NEXT:    mv a1, a7
377 ; RV32I-NEXT:  .LBB11_4:
378 ; RV32I-NEXT:    ret
380 ; RV32B-LABEL: cmov_uge_i64:
381 ; RV32B:       # %bb.0:
382 ; RV32B-NEXT:    xor t0, a3, a5
383 ; RV32B-NEXT:    sltu a2, a2, a4
384 ; RV32B-NEXT:    xori a2, a2, 1
385 ; RV32B-NEXT:    sltu a3, a3, a5
386 ; RV32B-NEXT:    xori a3, a3, 1
387 ; RV32B-NEXT:    cmov a2, t0, a3, a2
388 ; RV32B-NEXT:    cmov a0, a2, a0, a6
389 ; RV32B-NEXT:    cmov a1, a2, a1, a7
390 ; RV32B-NEXT:    ret
392 ; RV32ZBT-LABEL: cmov_uge_i64:
393 ; RV32ZBT:       # %bb.0:
394 ; RV32ZBT-NEXT:    xor t0, a3, a5
395 ; RV32ZBT-NEXT:    sltu a2, a2, a4
396 ; RV32ZBT-NEXT:    xori a2, a2, 1
397 ; RV32ZBT-NEXT:    sltu a3, a3, a5
398 ; RV32ZBT-NEXT:    xori a3, a3, 1
399 ; RV32ZBT-NEXT:    cmov a2, t0, a3, a2
400 ; RV32ZBT-NEXT:    cmov a0, a2, a0, a6
401 ; RV32ZBT-NEXT:    cmov a1, a2, a1, a7
402 ; RV32ZBT-NEXT:    ret
403   %tobool = icmp uge i64 %b, %c
404   %cond = select i1 %tobool, i64 %a, i64 %d
405   ret i64 %cond
408 declare i32 @llvm.fshl.i32(i32, i32, i32)
410 define i32 @fshl_i32(i32 %a, i32 %b, i32 %c) nounwind {
411 ; RV32I-LABEL: fshl_i32:
412 ; RV32I:       # %bb.0:
413 ; RV32I-NEXT:    sll a0, a0, a2
414 ; RV32I-NEXT:    not a2, a2
415 ; RV32I-NEXT:    srli a1, a1, 1
416 ; RV32I-NEXT:    srl a1, a1, a2
417 ; RV32I-NEXT:    or a0, a0, a1
418 ; RV32I-NEXT:    ret
420 ; RV32B-LABEL: fshl_i32:
421 ; RV32B:       # %bb.0:
422 ; RV32B-NEXT:    andi a2, a2, 31
423 ; RV32B-NEXT:    fsl a0, a0, a1, a2
424 ; RV32B-NEXT:    ret
426 ; RV32ZBT-LABEL: fshl_i32:
427 ; RV32ZBT:       # %bb.0:
428 ; RV32ZBT-NEXT:    andi a2, a2, 31
429 ; RV32ZBT-NEXT:    fsl a0, a0, a1, a2
430 ; RV32ZBT-NEXT:    ret
431   %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %c)
432   ret i32 %1
435 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
436 ; don't have yet an efficient pattern-matching with bit manipulation
437 ; instructions on RV32.
438 ; This test is presented here in case future expansions of the experimental-b
439 ; extension introduce instructions that can match more efficiently this pattern.
441 declare i64 @llvm.fshl.i64(i64, i64, i64)
443 define i64 @fshl_i64(i64 %a, i64 %b, i64 %c) nounwind {
444 ; RV32I-LABEL: fshl_i64:
445 ; RV32I:       # %bb.0:
446 ; RV32I-NEXT:    andi a5, a4, 63
447 ; RV32I-NEXT:    addi a7, a5, -32
448 ; RV32I-NEXT:    addi a6, zero, 31
449 ; RV32I-NEXT:    bltz a7, .LBB13_2
450 ; RV32I-NEXT:  # %bb.1:
451 ; RV32I-NEXT:    sll a1, a0, a7
452 ; RV32I-NEXT:    j .LBB13_3
453 ; RV32I-NEXT:  .LBB13_2:
454 ; RV32I-NEXT:    sll t0, a1, a4
455 ; RV32I-NEXT:    sub a5, a6, a5
456 ; RV32I-NEXT:    srli a1, a0, 1
457 ; RV32I-NEXT:    srl a1, a1, a5
458 ; RV32I-NEXT:    or a1, t0, a1
459 ; RV32I-NEXT:  .LBB13_3:
460 ; RV32I-NEXT:    not t2, a4
461 ; RV32I-NEXT:    andi t1, t2, 63
462 ; RV32I-NEXT:    addi a5, t1, -32
463 ; RV32I-NEXT:    srli t0, a3, 1
464 ; RV32I-NEXT:    bltz a5, .LBB13_5
465 ; RV32I-NEXT:  # %bb.4:
466 ; RV32I-NEXT:    srl a2, t0, a5
467 ; RV32I-NEXT:    bltz a7, .LBB13_6
468 ; RV32I-NEXT:    j .LBB13_7
469 ; RV32I-NEXT:  .LBB13_5:
470 ; RV32I-NEXT:    srl a5, t0, t2
471 ; RV32I-NEXT:    or a1, a1, a5
472 ; RV32I-NEXT:    slli a3, a3, 31
473 ; RV32I-NEXT:    srli a2, a2, 1
474 ; RV32I-NEXT:    or a2, a2, a3
475 ; RV32I-NEXT:    srl a2, a2, t2
476 ; RV32I-NEXT:    sub a3, a6, t1
477 ; RV32I-NEXT:    slli a5, t0, 1
478 ; RV32I-NEXT:    sll a3, a5, a3
479 ; RV32I-NEXT:    or a2, a2, a3
480 ; RV32I-NEXT:    bgez a7, .LBB13_7
481 ; RV32I-NEXT:  .LBB13_6:
482 ; RV32I-NEXT:    sll a0, a0, a4
483 ; RV32I-NEXT:    or a2, a2, a0
484 ; RV32I-NEXT:  .LBB13_7:
485 ; RV32I-NEXT:    mv a0, a2
486 ; RV32I-NEXT:    ret
488 ; RV32B-LABEL: fshl_i64:
489 ; RV32B:       # %bb.0:
490 ; RV32B-NEXT:    sll a7, a1, a4
491 ; RV32B-NEXT:    andi a5, a4, 63
492 ; RV32B-NEXT:    addi a6, zero, 31
493 ; RV32B-NEXT:    sub t0, a6, a5
494 ; RV32B-NEXT:    srli a1, a0, 1
495 ; RV32B-NEXT:    srl a1, a1, t0
496 ; RV32B-NEXT:    or a7, a7, a1
497 ; RV32B-NEXT:    addi t1, a5, -32
498 ; RV32B-NEXT:    sll t0, a0, t1
499 ; RV32B-NEXT:    slti a1, t1, 0
500 ; RV32B-NEXT:    cmov t0, a1, a7, t0
501 ; RV32B-NEXT:    not a7, a4
502 ; RV32B-NEXT:    srli t4, a3, 1
503 ; RV32B-NEXT:    srl t2, t4, a7
504 ; RV32B-NEXT:    addi a1, zero, 63
505 ; RV32B-NEXT:    andn t3, a1, a4
506 ; RV32B-NEXT:    addi a5, t3, -32
507 ; RV32B-NEXT:    srai a1, a5, 31
508 ; RV32B-NEXT:    and a1, a1, t2
509 ; RV32B-NEXT:    or a1, t0, a1
510 ; RV32B-NEXT:    fsri a2, a2, a3, 1
511 ; RV32B-NEXT:    srl a7, a2, a7
512 ; RV32B-NEXT:    sub a3, a6, t3
513 ; RV32B-NEXT:    slli a2, t4, 1
514 ; RV32B-NEXT:    sll a2, a2, a3
515 ; RV32B-NEXT:    or a2, a7, a2
516 ; RV32B-NEXT:    srl a3, t4, a5
517 ; RV32B-NEXT:    slti a5, a5, 0
518 ; RV32B-NEXT:    cmov a2, a5, a2, a3
519 ; RV32B-NEXT:    sll a0, a0, a4
520 ; RV32B-NEXT:    srai a3, t1, 31
521 ; RV32B-NEXT:    and a0, a3, a0
522 ; RV32B-NEXT:    or a0, a0, a2
523 ; RV32B-NEXT:    ret
525 ; RV32ZBT-LABEL: fshl_i64:
526 ; RV32ZBT:       # %bb.0:
527 ; RV32ZBT-NEXT:    sll a7, a1, a4
528 ; RV32ZBT-NEXT:    andi a5, a4, 63
529 ; RV32ZBT-NEXT:    addi a6, zero, 31
530 ; RV32ZBT-NEXT:    sub t0, a6, a5
531 ; RV32ZBT-NEXT:    srli a1, a0, 1
532 ; RV32ZBT-NEXT:    srl a1, a1, t0
533 ; RV32ZBT-NEXT:    or a7, a7, a1
534 ; RV32ZBT-NEXT:    addi t1, a5, -32
535 ; RV32ZBT-NEXT:    sll t0, a0, t1
536 ; RV32ZBT-NEXT:    slti a1, t1, 0
537 ; RV32ZBT-NEXT:    cmov t0, a1, a7, t0
538 ; RV32ZBT-NEXT:    not a5, a4
539 ; RV32ZBT-NEXT:    srli a7, a3, 1
540 ; RV32ZBT-NEXT:    srl t4, a7, a5
541 ; RV32ZBT-NEXT:    andi t2, a5, 63
542 ; RV32ZBT-NEXT:    addi t3, t2, -32
543 ; RV32ZBT-NEXT:    srai a1, t3, 31
544 ; RV32ZBT-NEXT:    and a1, a1, t4
545 ; RV32ZBT-NEXT:    or a1, t0, a1
546 ; RV32ZBT-NEXT:    fsri a2, a2, a3, 1
547 ; RV32ZBT-NEXT:    srl a2, a2, a5
548 ; RV32ZBT-NEXT:    sub a3, a6, t2
549 ; RV32ZBT-NEXT:    slli a5, a7, 1
550 ; RV32ZBT-NEXT:    sll a3, a5, a3
551 ; RV32ZBT-NEXT:    or a2, a2, a3
552 ; RV32ZBT-NEXT:    srl a3, a7, t3
553 ; RV32ZBT-NEXT:    slti a5, t3, 0
554 ; RV32ZBT-NEXT:    cmov a2, a5, a2, a3
555 ; RV32ZBT-NEXT:    sll a0, a0, a4
556 ; RV32ZBT-NEXT:    srai a3, t1, 31
557 ; RV32ZBT-NEXT:    and a0, a3, a0
558 ; RV32ZBT-NEXT:    or a0, a0, a2
559 ; RV32ZBT-NEXT:    ret
560   %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %b, i64 %c)
561   ret i64 %1
564 declare i32 @llvm.fshr.i32(i32, i32, i32)
566 define i32 @fshr_i32(i32 %a, i32 %b, i32 %c) nounwind {
567 ; RV32I-LABEL: fshr_i32:
568 ; RV32I:       # %bb.0:
569 ; RV32I-NEXT:    srl a1, a1, a2
570 ; RV32I-NEXT:    not a2, a2
571 ; RV32I-NEXT:    slli a0, a0, 1
572 ; RV32I-NEXT:    sll a0, a0, a2
573 ; RV32I-NEXT:    or a0, a0, a1
574 ; RV32I-NEXT:    ret
576 ; RV32B-LABEL: fshr_i32:
577 ; RV32B:       # %bb.0:
578 ; RV32B-NEXT:    andi a2, a2, 31
579 ; RV32B-NEXT:    fsr a0, a1, a0, a2
580 ; RV32B-NEXT:    ret
582 ; RV32ZBT-LABEL: fshr_i32:
583 ; RV32ZBT:       # %bb.0:
584 ; RV32ZBT-NEXT:    andi a2, a2, 31
585 ; RV32ZBT-NEXT:    fsr a0, a1, a0, a2
586 ; RV32ZBT-NEXT:    ret
587   %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %c)
588   ret i32 %1
591 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
592 ; don't have yet an efficient pattern-matching with bit manipulation
593 ; instructions on RV32.
594 ; This test is presented here in case future expansions of the experimental-b
595 ; extension introduce instructions that can match more efficiently this pattern.
597 declare i64 @llvm.fshr.i64(i64, i64, i64)
599 define i64 @fshr_i64(i64 %a, i64 %b, i64 %c) nounwind {
600 ; RV32I-LABEL: fshr_i64:
601 ; RV32I:       # %bb.0:
602 ; RV32I-NEXT:    mv t0, a0
603 ; RV32I-NEXT:    andi a0, a4, 63
604 ; RV32I-NEXT:    addi a6, a0, -32
605 ; RV32I-NEXT:    addi a7, zero, 31
606 ; RV32I-NEXT:    bltz a6, .LBB15_2
607 ; RV32I-NEXT:  # %bb.1:
608 ; RV32I-NEXT:    srl a0, a3, a6
609 ; RV32I-NEXT:    j .LBB15_3
610 ; RV32I-NEXT:  .LBB15_2:
611 ; RV32I-NEXT:    srl a2, a2, a4
612 ; RV32I-NEXT:    sub a0, a7, a0
613 ; RV32I-NEXT:    slli a5, a3, 1
614 ; RV32I-NEXT:    sll a0, a5, a0
615 ; RV32I-NEXT:    or a0, a2, a0
616 ; RV32I-NEXT:  .LBB15_3:
617 ; RV32I-NEXT:    not t2, a4
618 ; RV32I-NEXT:    andi a5, t2, 63
619 ; RV32I-NEXT:    addi a2, a5, -32
620 ; RV32I-NEXT:    slli t1, t0, 1
621 ; RV32I-NEXT:    bltz a2, .LBB15_5
622 ; RV32I-NEXT:  # %bb.4:
623 ; RV32I-NEXT:    sll a1, t1, a2
624 ; RV32I-NEXT:    bltz a6, .LBB15_6
625 ; RV32I-NEXT:    j .LBB15_7
626 ; RV32I-NEXT:  .LBB15_5:
627 ; RV32I-NEXT:    sll a2, t1, t2
628 ; RV32I-NEXT:    or a0, a0, a2
629 ; RV32I-NEXT:    lui a2, 524288
630 ; RV32I-NEXT:    addi a2, a2, -1
631 ; RV32I-NEXT:    and a2, t0, a2
632 ; RV32I-NEXT:    sub a5, a7, a5
633 ; RV32I-NEXT:    srl a2, a2, a5
634 ; RV32I-NEXT:    srli a5, t0, 31
635 ; RV32I-NEXT:    slli a1, a1, 1
636 ; RV32I-NEXT:    or a1, a1, a5
637 ; RV32I-NEXT:    sll a1, a1, t2
638 ; RV32I-NEXT:    or a1, a1, a2
639 ; RV32I-NEXT:    bgez a6, .LBB15_7
640 ; RV32I-NEXT:  .LBB15_6:
641 ; RV32I-NEXT:    srl a2, a3, a4
642 ; RV32I-NEXT:    or a1, a1, a2
643 ; RV32I-NEXT:  .LBB15_7:
644 ; RV32I-NEXT:    ret
646 ; RV32B-LABEL: fshr_i64:
647 ; RV32B:       # %bb.0:
648 ; RV32B-NEXT:    srl a7, a2, a4
649 ; RV32B-NEXT:    andi a5, a4, 63
650 ; RV32B-NEXT:    addi a6, zero, 31
651 ; RV32B-NEXT:    sub t0, a6, a5
652 ; RV32B-NEXT:    slli a2, a3, 1
653 ; RV32B-NEXT:    sll a2, a2, t0
654 ; RV32B-NEXT:    or a7, a7, a2
655 ; RV32B-NEXT:    addi t2, a5, -32
656 ; RV32B-NEXT:    srl t0, a3, t2
657 ; RV32B-NEXT:    slti a2, t2, 0
658 ; RV32B-NEXT:    cmov a7, a2, a7, t0
659 ; RV32B-NEXT:    not t3, a4
660 ; RV32B-NEXT:    slli t0, a0, 1
661 ; RV32B-NEXT:    sll t1, t0, t3
662 ; RV32B-NEXT:    addi a5, zero, 63
663 ; RV32B-NEXT:    andn t4, a5, a4
664 ; RV32B-NEXT:    addi a2, t4, -32
665 ; RV32B-NEXT:    srai a5, a2, 31
666 ; RV32B-NEXT:    and a5, a5, t1
667 ; RV32B-NEXT:    or a7, a5, a7
668 ; RV32B-NEXT:    fsri a1, a0, a1, 31
669 ; RV32B-NEXT:    sll a1, a1, t3
670 ; RV32B-NEXT:    sub a5, a6, t4
671 ; RV32B-NEXT:    bclri a0, a0, 31
672 ; RV32B-NEXT:    srl a0, a0, a5
673 ; RV32B-NEXT:    or a0, a1, a0
674 ; RV32B-NEXT:    sll a1, t0, a2
675 ; RV32B-NEXT:    slti a2, a2, 0
676 ; RV32B-NEXT:    cmov a0, a2, a0, a1
677 ; RV32B-NEXT:    srl a1, a3, a4
678 ; RV32B-NEXT:    srai a2, t2, 31
679 ; RV32B-NEXT:    and a1, a2, a1
680 ; RV32B-NEXT:    or a1, a0, a1
681 ; RV32B-NEXT:    mv a0, a7
682 ; RV32B-NEXT:    ret
684 ; RV32ZBT-LABEL: fshr_i64:
685 ; RV32ZBT:       # %bb.0:
686 ; RV32ZBT-NEXT:    srl a7, a2, a4
687 ; RV32ZBT-NEXT:    andi a5, a4, 63
688 ; RV32ZBT-NEXT:    addi a6, zero, 31
689 ; RV32ZBT-NEXT:    sub t0, a6, a5
690 ; RV32ZBT-NEXT:    slli a2, a3, 1
691 ; RV32ZBT-NEXT:    sll a2, a2, t0
692 ; RV32ZBT-NEXT:    or a7, a7, a2
693 ; RV32ZBT-NEXT:    addi t2, a5, -32
694 ; RV32ZBT-NEXT:    srl t0, a3, t2
695 ; RV32ZBT-NEXT:    slti a2, t2, 0
696 ; RV32ZBT-NEXT:    cmov a7, a2, a7, t0
697 ; RV32ZBT-NEXT:    not t4, a4
698 ; RV32ZBT-NEXT:    slli t0, a0, 1
699 ; RV32ZBT-NEXT:    sll t1, t0, t4
700 ; RV32ZBT-NEXT:    andi t3, t4, 63
701 ; RV32ZBT-NEXT:    addi a5, t3, -32
702 ; RV32ZBT-NEXT:    srai a2, a5, 31
703 ; RV32ZBT-NEXT:    and a2, a2, t1
704 ; RV32ZBT-NEXT:    or a7, a2, a7
705 ; RV32ZBT-NEXT:    lui a2, 524288
706 ; RV32ZBT-NEXT:    addi a2, a2, -1
707 ; RV32ZBT-NEXT:    and t1, a0, a2
708 ; RV32ZBT-NEXT:    sub a2, a6, t3
709 ; RV32ZBT-NEXT:    srl a2, t1, a2
710 ; RV32ZBT-NEXT:    fsri a0, a0, a1, 31
711 ; RV32ZBT-NEXT:    sll a0, a0, t4
712 ; RV32ZBT-NEXT:    or a0, a0, a2
713 ; RV32ZBT-NEXT:    sll a1, t0, a5
714 ; RV32ZBT-NEXT:    slti a2, a5, 0
715 ; RV32ZBT-NEXT:    cmov a0, a2, a0, a1
716 ; RV32ZBT-NEXT:    srl a1, a3, a4
717 ; RV32ZBT-NEXT:    srai a2, t2, 31
718 ; RV32ZBT-NEXT:    and a1, a2, a1
719 ; RV32ZBT-NEXT:    or a1, a0, a1
720 ; RV32ZBT-NEXT:    mv a0, a7
721 ; RV32ZBT-NEXT:    ret
722   %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %b, i64 %c)
723   ret i64 %1
726 define i32 @fshri_i32(i32 %a, i32 %b) nounwind {
727 ; RV32I-LABEL: fshri_i32:
728 ; RV32I:       # %bb.0:
729 ; RV32I-NEXT:    srli a1, a1, 5
730 ; RV32I-NEXT:    slli a0, a0, 27
731 ; RV32I-NEXT:    or a0, a0, a1
732 ; RV32I-NEXT:    ret
734 ; RV32B-LABEL: fshri_i32:
735 ; RV32B:       # %bb.0:
736 ; RV32B-NEXT:    fsri a0, a1, a0, 5
737 ; RV32B-NEXT:    ret
739 ; RV32ZBT-LABEL: fshri_i32:
740 ; RV32ZBT:       # %bb.0:
741 ; RV32ZBT-NEXT:    fsri a0, a1, a0, 5
742 ; RV32ZBT-NEXT:    ret
743   %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 5)
744   ret i32 %1
747 define i64 @fshri_i64(i64 %a, i64 %b) nounwind {
748 ; RV32I-LABEL: fshri_i64:
749 ; RV32I:       # %bb.0:
750 ; RV32I-NEXT:    slli a1, a3, 27
751 ; RV32I-NEXT:    srli a2, a2, 5
752 ; RV32I-NEXT:    or a2, a2, a1
753 ; RV32I-NEXT:    srli a1, a3, 5
754 ; RV32I-NEXT:    slli a0, a0, 27
755 ; RV32I-NEXT:    or a1, a0, a1
756 ; RV32I-NEXT:    mv a0, a2
757 ; RV32I-NEXT:    ret
759 ; RV32B-LABEL: fshri_i64:
760 ; RV32B:       # %bb.0:
761 ; RV32B-NEXT:    fsri a2, a2, a3, 5
762 ; RV32B-NEXT:    fsri a1, a3, a0, 5
763 ; RV32B-NEXT:    mv a0, a2
764 ; RV32B-NEXT:    ret
766 ; RV32ZBT-LABEL: fshri_i64:
767 ; RV32ZBT:       # %bb.0:
768 ; RV32ZBT-NEXT:    fsri a2, a2, a3, 5
769 ; RV32ZBT-NEXT:    fsri a1, a3, a0, 5
770 ; RV32ZBT-NEXT:    mv a0, a2
771 ; RV32ZBT-NEXT:    ret
772   %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %b, i64 5)
773   ret i64 %1
776 define i32 @fshli_i32(i32 %a, i32 %b) nounwind {
777 ; RV32I-LABEL: fshli_i32:
778 ; RV32I:       # %bb.0:
779 ; RV32I-NEXT:    srli a1, a1, 27
780 ; RV32I-NEXT:    slli a0, a0, 5
781 ; RV32I-NEXT:    or a0, a0, a1
782 ; RV32I-NEXT:    ret
784 ; RV32B-LABEL: fshli_i32:
785 ; RV32B:       # %bb.0:
786 ; RV32B-NEXT:    fsri a0, a1, a0, 27
787 ; RV32B-NEXT:    ret
789 ; RV32ZBT-LABEL: fshli_i32:
790 ; RV32ZBT:       # %bb.0:
791 ; RV32ZBT-NEXT:    fsri a0, a1, a0, 27
792 ; RV32ZBT-NEXT:    ret
793   %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 5)
794   ret i32 %1
797 define i64 @fshli_i64(i64 %a, i64 %b) nounwind {
798 ; RV32I-LABEL: fshli_i64:
799 ; RV32I:       # %bb.0:
800 ; RV32I-NEXT:    srli a2, a3, 27
801 ; RV32I-NEXT:    slli a3, a0, 5
802 ; RV32I-NEXT:    or a2, a3, a2
803 ; RV32I-NEXT:    srli a0, a0, 27
804 ; RV32I-NEXT:    slli a1, a1, 5
805 ; RV32I-NEXT:    or a1, a1, a0
806 ; RV32I-NEXT:    mv a0, a2
807 ; RV32I-NEXT:    ret
809 ; RV32B-LABEL: fshli_i64:
810 ; RV32B:       # %bb.0:
811 ; RV32B-NEXT:    fsri a2, a3, a0, 27
812 ; RV32B-NEXT:    fsri a1, a0, a1, 27
813 ; RV32B-NEXT:    mv a0, a2
814 ; RV32B-NEXT:    ret
816 ; RV32ZBT-LABEL: fshli_i64:
817 ; RV32ZBT:       # %bb.0:
818 ; RV32ZBT-NEXT:    fsri a2, a3, a0, 27
819 ; RV32ZBT-NEXT:    fsri a1, a0, a1, 27
820 ; RV32ZBT-NEXT:    mv a0, a2
821 ; RV32ZBT-NEXT:    ret
822   %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %b, i64 5)
823   ret i64 %1