[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv32zbb.ll
blobddae369e1a6745187ba42c68dc562b4cb511c837
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=+zbb -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBB
7 declare i32 @llvm.ctlz.i32(i32, i1)
9 define i32 @ctlz_i32(i32 %a) nounwind {
10 ; RV32I-LABEL: ctlz_i32:
11 ; RV32I:       # %bb.0:
12 ; RV32I-NEXT:    beqz a0, .LBB0_2
13 ; RV32I-NEXT:  # %bb.1: # %cond.false
14 ; RV32I-NEXT:    addi sp, sp, -16
15 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
16 ; RV32I-NEXT:    srli a1, a0, 1
17 ; RV32I-NEXT:    or a0, a0, a1
18 ; RV32I-NEXT:    srli a1, a0, 2
19 ; RV32I-NEXT:    or a0, a0, a1
20 ; RV32I-NEXT:    srli a1, a0, 4
21 ; RV32I-NEXT:    or a0, a0, a1
22 ; RV32I-NEXT:    srli a1, a0, 8
23 ; RV32I-NEXT:    or a0, a0, a1
24 ; RV32I-NEXT:    srli a1, a0, 16
25 ; RV32I-NEXT:    or a0, a0, a1
26 ; RV32I-NEXT:    not a0, a0
27 ; RV32I-NEXT:    srli a1, a0, 1
28 ; RV32I-NEXT:    lui a2, 349525
29 ; RV32I-NEXT:    addi a2, a2, 1365
30 ; RV32I-NEXT:    and a1, a1, a2
31 ; RV32I-NEXT:    sub a0, a0, a1
32 ; RV32I-NEXT:    lui a1, 209715
33 ; RV32I-NEXT:    addi a1, a1, 819
34 ; RV32I-NEXT:    and a2, a0, a1
35 ; RV32I-NEXT:    srli a0, a0, 2
36 ; RV32I-NEXT:    and a0, a0, a1
37 ; RV32I-NEXT:    add a0, a2, a0
38 ; RV32I-NEXT:    srli a1, a0, 4
39 ; RV32I-NEXT:    add a0, a0, a1
40 ; RV32I-NEXT:    lui a1, 61681
41 ; RV32I-NEXT:    addi a1, a1, -241
42 ; RV32I-NEXT:    and a0, a0, a1
43 ; RV32I-NEXT:    lui a1, 4112
44 ; RV32I-NEXT:    addi a1, a1, 257
45 ; RV32I-NEXT:    call __mulsi3@plt
46 ; RV32I-NEXT:    srli a0, a0, 24
47 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
48 ; RV32I-NEXT:    addi sp, sp, 16
49 ; RV32I-NEXT:    ret
50 ; RV32I-NEXT:  .LBB0_2:
51 ; RV32I-NEXT:    li a0, 32
52 ; RV32I-NEXT:    ret
54 ; RV32ZBB-LABEL: ctlz_i32:
55 ; RV32ZBB:       # %bb.0:
56 ; RV32ZBB-NEXT:    clz a0, a0
57 ; RV32ZBB-NEXT:    ret
58   %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
59   ret i32 %1
62 declare i64 @llvm.ctlz.i64(i64, i1)
64 define i64 @ctlz_i64(i64 %a) nounwind {
65 ; RV32I-LABEL: ctlz_i64:
66 ; RV32I:       # %bb.0:
67 ; RV32I-NEXT:    addi sp, sp, -32
68 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
69 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
70 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
71 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
72 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
73 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
74 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
75 ; RV32I-NEXT:    sw s6, 0(sp) # 4-byte Folded Spill
76 ; RV32I-NEXT:    mv s0, a1
77 ; RV32I-NEXT:    mv s2, a0
78 ; RV32I-NEXT:    srli a0, a1, 1
79 ; RV32I-NEXT:    or a0, a1, a0
80 ; RV32I-NEXT:    srli a1, a0, 2
81 ; RV32I-NEXT:    or a0, a0, a1
82 ; RV32I-NEXT:    srli a1, a0, 4
83 ; RV32I-NEXT:    or a0, a0, a1
84 ; RV32I-NEXT:    srli a1, a0, 8
85 ; RV32I-NEXT:    or a0, a0, a1
86 ; RV32I-NEXT:    srli a1, a0, 16
87 ; RV32I-NEXT:    or a0, a0, a1
88 ; RV32I-NEXT:    not a0, a0
89 ; RV32I-NEXT:    srli a1, a0, 1
90 ; RV32I-NEXT:    lui a2, 349525
91 ; RV32I-NEXT:    addi s4, a2, 1365
92 ; RV32I-NEXT:    and a1, a1, s4
93 ; RV32I-NEXT:    sub a0, a0, a1
94 ; RV32I-NEXT:    lui a1, 209715
95 ; RV32I-NEXT:    addi s5, a1, 819
96 ; RV32I-NEXT:    and a1, a0, s5
97 ; RV32I-NEXT:    srli a0, a0, 2
98 ; RV32I-NEXT:    and a0, a0, s5
99 ; RV32I-NEXT:    add a0, a1, a0
100 ; RV32I-NEXT:    srli a1, a0, 4
101 ; RV32I-NEXT:    add a0, a0, a1
102 ; RV32I-NEXT:    lui a1, 61681
103 ; RV32I-NEXT:    addi s6, a1, -241
104 ; RV32I-NEXT:    and a0, a0, s6
105 ; RV32I-NEXT:    lui a1, 4112
106 ; RV32I-NEXT:    addi s3, a1, 257
107 ; RV32I-NEXT:    mv a1, s3
108 ; RV32I-NEXT:    call __mulsi3@plt
109 ; RV32I-NEXT:    mv s1, a0
110 ; RV32I-NEXT:    srli a0, s2, 1
111 ; RV32I-NEXT:    or a0, s2, a0
112 ; RV32I-NEXT:    srli a1, a0, 2
113 ; RV32I-NEXT:    or a0, a0, a1
114 ; RV32I-NEXT:    srli a1, a0, 4
115 ; RV32I-NEXT:    or a0, a0, a1
116 ; RV32I-NEXT:    srli a1, a0, 8
117 ; RV32I-NEXT:    or a0, a0, a1
118 ; RV32I-NEXT:    srli a1, a0, 16
119 ; RV32I-NEXT:    or a0, a0, a1
120 ; RV32I-NEXT:    not a0, a0
121 ; RV32I-NEXT:    srli a1, a0, 1
122 ; RV32I-NEXT:    and a1, a1, s4
123 ; RV32I-NEXT:    sub a0, a0, a1
124 ; RV32I-NEXT:    and a1, a0, s5
125 ; RV32I-NEXT:    srli a0, a0, 2
126 ; RV32I-NEXT:    and a0, a0, s5
127 ; RV32I-NEXT:    add a0, a1, a0
128 ; RV32I-NEXT:    srli a1, a0, 4
129 ; RV32I-NEXT:    add a0, a0, a1
130 ; RV32I-NEXT:    and a0, a0, s6
131 ; RV32I-NEXT:    mv a1, s3
132 ; RV32I-NEXT:    call __mulsi3@plt
133 ; RV32I-NEXT:    bnez s0, .LBB1_2
134 ; RV32I-NEXT:  # %bb.1:
135 ; RV32I-NEXT:    srli a0, a0, 24
136 ; RV32I-NEXT:    addi a0, a0, 32
137 ; RV32I-NEXT:    j .LBB1_3
138 ; RV32I-NEXT:  .LBB1_2:
139 ; RV32I-NEXT:    srli a0, s1, 24
140 ; RV32I-NEXT:  .LBB1_3:
141 ; RV32I-NEXT:    li a1, 0
142 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
143 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
144 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
145 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
146 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
147 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
148 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
149 ; RV32I-NEXT:    lw s6, 0(sp) # 4-byte Folded Reload
150 ; RV32I-NEXT:    addi sp, sp, 32
151 ; RV32I-NEXT:    ret
153 ; RV32ZBB-LABEL: ctlz_i64:
154 ; RV32ZBB:       # %bb.0:
155 ; RV32ZBB-NEXT:    bnez a1, .LBB1_2
156 ; RV32ZBB-NEXT:  # %bb.1:
157 ; RV32ZBB-NEXT:    clz a0, a0
158 ; RV32ZBB-NEXT:    addi a0, a0, 32
159 ; RV32ZBB-NEXT:    li a1, 0
160 ; RV32ZBB-NEXT:    ret
161 ; RV32ZBB-NEXT:  .LBB1_2:
162 ; RV32ZBB-NEXT:    clz a0, a1
163 ; RV32ZBB-NEXT:    li a1, 0
164 ; RV32ZBB-NEXT:    ret
165   %1 = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
166   ret i64 %1
169 declare i32 @llvm.cttz.i32(i32, i1)
171 define i32 @cttz_i32(i32 %a) nounwind {
172 ; RV32I-LABEL: cttz_i32:
173 ; RV32I:       # %bb.0:
174 ; RV32I-NEXT:    beqz a0, .LBB2_4
175 ; RV32I-NEXT:  # %bb.1: # %cond.false
176 ; RV32I-NEXT:    addi sp, sp, -16
177 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
178 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
179 ; RV32I-NEXT:    mv s0, a0
180 ; RV32I-NEXT:    neg a0, a0
181 ; RV32I-NEXT:    and a0, s0, a0
182 ; RV32I-NEXT:    lui a1, 30667
183 ; RV32I-NEXT:    addi a1, a1, 1329
184 ; RV32I-NEXT:    call __mulsi3@plt
185 ; RV32I-NEXT:    mv a1, a0
186 ; RV32I-NEXT:    li a0, 32
187 ; RV32I-NEXT:    beqz s0, .LBB2_3
188 ; RV32I-NEXT:  # %bb.2: # %cond.false
189 ; RV32I-NEXT:    srli a0, a1, 27
190 ; RV32I-NEXT:    lui a1, %hi(.LCPI2_0)
191 ; RV32I-NEXT:    addi a1, a1, %lo(.LCPI2_0)
192 ; RV32I-NEXT:    add a0, a1, a0
193 ; RV32I-NEXT:    lbu a0, 0(a0)
194 ; RV32I-NEXT:  .LBB2_3: # %cond.false
195 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
196 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
197 ; RV32I-NEXT:    addi sp, sp, 16
198 ; RV32I-NEXT:    ret
199 ; RV32I-NEXT:  .LBB2_4:
200 ; RV32I-NEXT:    li a0, 32
201 ; RV32I-NEXT:    ret
203 ; RV32ZBB-LABEL: cttz_i32:
204 ; RV32ZBB:       # %bb.0:
205 ; RV32ZBB-NEXT:    ctz a0, a0
206 ; RV32ZBB-NEXT:    ret
207   %1 = call i32 @llvm.cttz.i32(i32 %a, i1 false)
208   ret i32 %1
211 declare i64 @llvm.cttz.i64(i64, i1)
213 define i64 @cttz_i64(i64 %a) nounwind {
214 ; RV32I-LABEL: cttz_i64:
215 ; RV32I:       # %bb.0:
216 ; RV32I-NEXT:    addi sp, sp, -32
217 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
218 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
219 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
220 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
221 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
222 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
223 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
224 ; RV32I-NEXT:    mv s1, a1
225 ; RV32I-NEXT:    mv s0, a0
226 ; RV32I-NEXT:    neg a0, a0
227 ; RV32I-NEXT:    and a0, s0, a0
228 ; RV32I-NEXT:    lui a1, 30667
229 ; RV32I-NEXT:    addi s3, a1, 1329
230 ; RV32I-NEXT:    mv a1, s3
231 ; RV32I-NEXT:    call __mulsi3@plt
232 ; RV32I-NEXT:    lui a1, %hi(.LCPI3_0)
233 ; RV32I-NEXT:    addi s5, a1, %lo(.LCPI3_0)
234 ; RV32I-NEXT:    li s4, 32
235 ; RV32I-NEXT:    li s2, 32
236 ; RV32I-NEXT:    beqz s0, .LBB3_2
237 ; RV32I-NEXT:  # %bb.1:
238 ; RV32I-NEXT:    srli a0, a0, 27
239 ; RV32I-NEXT:    add a0, s5, a0
240 ; RV32I-NEXT:    lbu s2, 0(a0)
241 ; RV32I-NEXT:  .LBB3_2:
242 ; RV32I-NEXT:    neg a0, s1
243 ; RV32I-NEXT:    and a0, s1, a0
244 ; RV32I-NEXT:    mv a1, s3
245 ; RV32I-NEXT:    call __mulsi3@plt
246 ; RV32I-NEXT:    beqz s1, .LBB3_4
247 ; RV32I-NEXT:  # %bb.3:
248 ; RV32I-NEXT:    srli a0, a0, 27
249 ; RV32I-NEXT:    add a0, s5, a0
250 ; RV32I-NEXT:    lbu s4, 0(a0)
251 ; RV32I-NEXT:  .LBB3_4:
252 ; RV32I-NEXT:    bnez s0, .LBB3_6
253 ; RV32I-NEXT:  # %bb.5:
254 ; RV32I-NEXT:    addi s2, s4, 32
255 ; RV32I-NEXT:  .LBB3_6:
256 ; RV32I-NEXT:    mv a0, s2
257 ; RV32I-NEXT:    li a1, 0
258 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
259 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
260 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
261 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
262 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
263 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
264 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
265 ; RV32I-NEXT:    addi sp, sp, 32
266 ; RV32I-NEXT:    ret
268 ; RV32ZBB-LABEL: cttz_i64:
269 ; RV32ZBB:       # %bb.0:
270 ; RV32ZBB-NEXT:    bnez a0, .LBB3_2
271 ; RV32ZBB-NEXT:  # %bb.1:
272 ; RV32ZBB-NEXT:    ctz a0, a1
273 ; RV32ZBB-NEXT:    addi a0, a0, 32
274 ; RV32ZBB-NEXT:    li a1, 0
275 ; RV32ZBB-NEXT:    ret
276 ; RV32ZBB-NEXT:  .LBB3_2:
277 ; RV32ZBB-NEXT:    ctz a0, a0
278 ; RV32ZBB-NEXT:    li a1, 0
279 ; RV32ZBB-NEXT:    ret
280   %1 = call i64 @llvm.cttz.i64(i64 %a, i1 false)
281   ret i64 %1
284 declare i32 @llvm.ctpop.i32(i32)
286 define i32 @ctpop_i32(i32 %a) nounwind {
287 ; RV32I-LABEL: ctpop_i32:
288 ; RV32I:       # %bb.0:
289 ; RV32I-NEXT:    addi sp, sp, -16
290 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
291 ; RV32I-NEXT:    srli a1, a0, 1
292 ; RV32I-NEXT:    lui a2, 349525
293 ; RV32I-NEXT:    addi a2, a2, 1365
294 ; RV32I-NEXT:    and a1, a1, a2
295 ; RV32I-NEXT:    sub a0, a0, a1
296 ; RV32I-NEXT:    lui a1, 209715
297 ; RV32I-NEXT:    addi a1, a1, 819
298 ; RV32I-NEXT:    and a2, a0, a1
299 ; RV32I-NEXT:    srli a0, a0, 2
300 ; RV32I-NEXT:    and a0, a0, a1
301 ; RV32I-NEXT:    add a0, a2, a0
302 ; RV32I-NEXT:    srli a1, a0, 4
303 ; RV32I-NEXT:    add a0, a0, a1
304 ; RV32I-NEXT:    lui a1, 61681
305 ; RV32I-NEXT:    addi a1, a1, -241
306 ; RV32I-NEXT:    and a0, a0, a1
307 ; RV32I-NEXT:    lui a1, 4112
308 ; RV32I-NEXT:    addi a1, a1, 257
309 ; RV32I-NEXT:    call __mulsi3@plt
310 ; RV32I-NEXT:    srli a0, a0, 24
311 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
312 ; RV32I-NEXT:    addi sp, sp, 16
313 ; RV32I-NEXT:    ret
315 ; RV32ZBB-LABEL: ctpop_i32:
316 ; RV32ZBB:       # %bb.0:
317 ; RV32ZBB-NEXT:    cpop a0, a0
318 ; RV32ZBB-NEXT:    ret
319   %1 = call i32 @llvm.ctpop.i32(i32 %a)
320   ret i32 %1
323 declare i64 @llvm.ctpop.i64(i64)
325 define i64 @ctpop_i64(i64 %a) nounwind {
326 ; RV32I-LABEL: ctpop_i64:
327 ; RV32I:       # %bb.0:
328 ; RV32I-NEXT:    addi sp, sp, -32
329 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
330 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
331 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
332 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
333 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
334 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
335 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
336 ; RV32I-NEXT:    mv s0, a0
337 ; RV32I-NEXT:    srli a0, a1, 1
338 ; RV32I-NEXT:    lui a2, 349525
339 ; RV32I-NEXT:    addi s2, a2, 1365
340 ; RV32I-NEXT:    and a0, a0, s2
341 ; RV32I-NEXT:    sub a0, a1, a0
342 ; RV32I-NEXT:    lui a1, 209715
343 ; RV32I-NEXT:    addi s3, a1, 819
344 ; RV32I-NEXT:    and a1, a0, s3
345 ; RV32I-NEXT:    srli a0, a0, 2
346 ; RV32I-NEXT:    and a0, a0, s3
347 ; RV32I-NEXT:    add a0, a1, a0
348 ; RV32I-NEXT:    srli a1, a0, 4
349 ; RV32I-NEXT:    add a0, a0, a1
350 ; RV32I-NEXT:    lui a1, 61681
351 ; RV32I-NEXT:    addi s4, a1, -241
352 ; RV32I-NEXT:    and a0, a0, s4
353 ; RV32I-NEXT:    lui a1, 4112
354 ; RV32I-NEXT:    addi s1, a1, 257
355 ; RV32I-NEXT:    mv a1, s1
356 ; RV32I-NEXT:    call __mulsi3@plt
357 ; RV32I-NEXT:    srli s5, a0, 24
358 ; RV32I-NEXT:    srli a0, s0, 1
359 ; RV32I-NEXT:    and a0, a0, s2
360 ; RV32I-NEXT:    sub a0, s0, a0
361 ; RV32I-NEXT:    and a1, a0, s3
362 ; RV32I-NEXT:    srli a0, a0, 2
363 ; RV32I-NEXT:    and a0, a0, s3
364 ; RV32I-NEXT:    add a0, a1, a0
365 ; RV32I-NEXT:    srli a1, a0, 4
366 ; RV32I-NEXT:    add a0, a0, a1
367 ; RV32I-NEXT:    and a0, a0, s4
368 ; RV32I-NEXT:    mv a1, s1
369 ; RV32I-NEXT:    call __mulsi3@plt
370 ; RV32I-NEXT:    srli a0, a0, 24
371 ; RV32I-NEXT:    add a0, a0, s5
372 ; RV32I-NEXT:    li a1, 0
373 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
374 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
375 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
376 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
377 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
378 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
379 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
380 ; RV32I-NEXT:    addi sp, sp, 32
381 ; RV32I-NEXT:    ret
383 ; RV32ZBB-LABEL: ctpop_i64:
384 ; RV32ZBB:       # %bb.0:
385 ; RV32ZBB-NEXT:    cpop a1, a1
386 ; RV32ZBB-NEXT:    cpop a0, a0
387 ; RV32ZBB-NEXT:    add a0, a0, a1
388 ; RV32ZBB-NEXT:    li a1, 0
389 ; RV32ZBB-NEXT:    ret
390   %1 = call i64 @llvm.ctpop.i64(i64 %a)
391   ret i64 %1
394 define i32 @sextb_i32(i32 %a) nounwind {
395 ; RV32I-LABEL: sextb_i32:
396 ; RV32I:       # %bb.0:
397 ; RV32I-NEXT:    slli a0, a0, 24
398 ; RV32I-NEXT:    srai a0, a0, 24
399 ; RV32I-NEXT:    ret
401 ; RV32ZBB-LABEL: sextb_i32:
402 ; RV32ZBB:       # %bb.0:
403 ; RV32ZBB-NEXT:    sext.b a0, a0
404 ; RV32ZBB-NEXT:    ret
405   %shl = shl i32 %a, 24
406   %shr = ashr exact i32 %shl, 24
407   ret i32 %shr
410 define i64 @sextb_i64(i64 %a) nounwind {
411 ; RV32I-LABEL: sextb_i64:
412 ; RV32I:       # %bb.0:
413 ; RV32I-NEXT:    slli a1, a0, 24
414 ; RV32I-NEXT:    srai a0, a1, 24
415 ; RV32I-NEXT:    srai a1, a1, 31
416 ; RV32I-NEXT:    ret
418 ; RV32ZBB-LABEL: sextb_i64:
419 ; RV32ZBB:       # %bb.0:
420 ; RV32ZBB-NEXT:    sext.b a0, a0
421 ; RV32ZBB-NEXT:    srai a1, a0, 31
422 ; RV32ZBB-NEXT:    ret
423   %shl = shl i64 %a, 56
424   %shr = ashr exact i64 %shl, 56
425   ret i64 %shr
428 define i32 @sexth_i32(i32 %a) nounwind {
429 ; RV32I-LABEL: sexth_i32:
430 ; RV32I:       # %bb.0:
431 ; RV32I-NEXT:    slli a0, a0, 16
432 ; RV32I-NEXT:    srai a0, a0, 16
433 ; RV32I-NEXT:    ret
435 ; RV32ZBB-LABEL: sexth_i32:
436 ; RV32ZBB:       # %bb.0:
437 ; RV32ZBB-NEXT:    sext.h a0, a0
438 ; RV32ZBB-NEXT:    ret
439   %shl = shl i32 %a, 16
440   %shr = ashr exact i32 %shl, 16
441   ret i32 %shr
444 define i64 @sexth_i64(i64 %a) nounwind {
445 ; RV32I-LABEL: sexth_i64:
446 ; RV32I:       # %bb.0:
447 ; RV32I-NEXT:    slli a1, a0, 16
448 ; RV32I-NEXT:    srai a0, a1, 16
449 ; RV32I-NEXT:    srai a1, a1, 31
450 ; RV32I-NEXT:    ret
452 ; RV32ZBB-LABEL: sexth_i64:
453 ; RV32ZBB:       # %bb.0:
454 ; RV32ZBB-NEXT:    sext.h a0, a0
455 ; RV32ZBB-NEXT:    srai a1, a0, 31
456 ; RV32ZBB-NEXT:    ret
457   %shl = shl i64 %a, 48
458   %shr = ashr exact i64 %shl, 48
459   ret i64 %shr
462 define i32 @min_i32(i32 %a, i32 %b) nounwind {
463 ; RV32I-LABEL: min_i32:
464 ; RV32I:       # %bb.0:
465 ; RV32I-NEXT:    blt a0, a1, .LBB10_2
466 ; RV32I-NEXT:  # %bb.1:
467 ; RV32I-NEXT:    mv a0, a1
468 ; RV32I-NEXT:  .LBB10_2:
469 ; RV32I-NEXT:    ret
471 ; RV32ZBB-LABEL: min_i32:
472 ; RV32ZBB:       # %bb.0:
473 ; RV32ZBB-NEXT:    min a0, a0, a1
474 ; RV32ZBB-NEXT:    ret
475   %cmp = icmp slt i32 %a, %b
476   %cond = select i1 %cmp, i32 %a, i32 %b
477   ret i32 %cond
480 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
481 ; don't have yet any matching bit manipulation instructions on RV32.
482 ; This test is presented here in case future expansions of the Bitmanip
483 ; extensions introduce instructions suitable for this pattern.
485 define i64 @min_i64(i64 %a, i64 %b) nounwind {
486 ; RV32I-LABEL: min_i64:
487 ; RV32I:       # %bb.0:
488 ; RV32I-NEXT:    beq a1, a3, .LBB11_2
489 ; RV32I-NEXT:  # %bb.1:
490 ; RV32I-NEXT:    slt a4, a1, a3
491 ; RV32I-NEXT:    beqz a4, .LBB11_3
492 ; RV32I-NEXT:    j .LBB11_4
493 ; RV32I-NEXT:  .LBB11_2:
494 ; RV32I-NEXT:    sltu a4, a0, a2
495 ; RV32I-NEXT:    bnez a4, .LBB11_4
496 ; RV32I-NEXT:  .LBB11_3:
497 ; RV32I-NEXT:    mv a0, a2
498 ; RV32I-NEXT:    mv a1, a3
499 ; RV32I-NEXT:  .LBB11_4:
500 ; RV32I-NEXT:    ret
502 ; RV32ZBB-LABEL: min_i64:
503 ; RV32ZBB:       # %bb.0:
504 ; RV32ZBB-NEXT:    mv a4, a0
505 ; RV32ZBB-NEXT:    bge a1, a3, .LBB11_3
506 ; RV32ZBB-NEXT:  # %bb.1:
507 ; RV32ZBB-NEXT:    beq a1, a3, .LBB11_4
508 ; RV32ZBB-NEXT:  .LBB11_2:
509 ; RV32ZBB-NEXT:    min a1, a1, a3
510 ; RV32ZBB-NEXT:    ret
511 ; RV32ZBB-NEXT:  .LBB11_3:
512 ; RV32ZBB-NEXT:    mv a0, a2
513 ; RV32ZBB-NEXT:    bne a1, a3, .LBB11_2
514 ; RV32ZBB-NEXT:  .LBB11_4:
515 ; RV32ZBB-NEXT:    minu a0, a4, a2
516 ; RV32ZBB-NEXT:    min a1, a1, a3
517 ; RV32ZBB-NEXT:    ret
518   %cmp = icmp slt i64 %a, %b
519   %cond = select i1 %cmp, i64 %a, i64 %b
520   ret i64 %cond
523 define i32 @max_i32(i32 %a, i32 %b) nounwind {
524 ; RV32I-LABEL: max_i32:
525 ; RV32I:       # %bb.0:
526 ; RV32I-NEXT:    blt a1, a0, .LBB12_2
527 ; RV32I-NEXT:  # %bb.1:
528 ; RV32I-NEXT:    mv a0, a1
529 ; RV32I-NEXT:  .LBB12_2:
530 ; RV32I-NEXT:    ret
532 ; RV32ZBB-LABEL: max_i32:
533 ; RV32ZBB:       # %bb.0:
534 ; RV32ZBB-NEXT:    max a0, a0, a1
535 ; RV32ZBB-NEXT:    ret
536   %cmp = icmp sgt i32 %a, %b
537   %cond = select i1 %cmp, i32 %a, i32 %b
538   ret i32 %cond
541 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
542 ; don't have yet any matching bit manipulation instructions on RV32.
543 ; This test is presented here in case future expansions of the Bitmanip
544 ; extensions introduce instructions suitable for this pattern.
546 define i64 @max_i64(i64 %a, i64 %b) nounwind {
547 ; RV32I-LABEL: max_i64:
548 ; RV32I:       # %bb.0:
549 ; RV32I-NEXT:    beq a1, a3, .LBB13_2
550 ; RV32I-NEXT:  # %bb.1:
551 ; RV32I-NEXT:    slt a4, a3, a1
552 ; RV32I-NEXT:    beqz a4, .LBB13_3
553 ; RV32I-NEXT:    j .LBB13_4
554 ; RV32I-NEXT:  .LBB13_2:
555 ; RV32I-NEXT:    sltu a4, a2, a0
556 ; RV32I-NEXT:    bnez a4, .LBB13_4
557 ; RV32I-NEXT:  .LBB13_3:
558 ; RV32I-NEXT:    mv a0, a2
559 ; RV32I-NEXT:    mv a1, a3
560 ; RV32I-NEXT:  .LBB13_4:
561 ; RV32I-NEXT:    ret
563 ; RV32ZBB-LABEL: max_i64:
564 ; RV32ZBB:       # %bb.0:
565 ; RV32ZBB-NEXT:    mv a4, a0
566 ; RV32ZBB-NEXT:    bge a3, a1, .LBB13_3
567 ; RV32ZBB-NEXT:  # %bb.1:
568 ; RV32ZBB-NEXT:    beq a1, a3, .LBB13_4
569 ; RV32ZBB-NEXT:  .LBB13_2:
570 ; RV32ZBB-NEXT:    max a1, a1, a3
571 ; RV32ZBB-NEXT:    ret
572 ; RV32ZBB-NEXT:  .LBB13_3:
573 ; RV32ZBB-NEXT:    mv a0, a2
574 ; RV32ZBB-NEXT:    bne a1, a3, .LBB13_2
575 ; RV32ZBB-NEXT:  .LBB13_4:
576 ; RV32ZBB-NEXT:    maxu a0, a4, a2
577 ; RV32ZBB-NEXT:    max a1, a1, a3
578 ; RV32ZBB-NEXT:    ret
579   %cmp = icmp sgt i64 %a, %b
580   %cond = select i1 %cmp, i64 %a, i64 %b
581   ret i64 %cond
584 define i32 @minu_i32(i32 %a, i32 %b) nounwind {
585 ; RV32I-LABEL: minu_i32:
586 ; RV32I:       # %bb.0:
587 ; RV32I-NEXT:    bltu a0, a1, .LBB14_2
588 ; RV32I-NEXT:  # %bb.1:
589 ; RV32I-NEXT:    mv a0, a1
590 ; RV32I-NEXT:  .LBB14_2:
591 ; RV32I-NEXT:    ret
593 ; RV32ZBB-LABEL: minu_i32:
594 ; RV32ZBB:       # %bb.0:
595 ; RV32ZBB-NEXT:    minu a0, a0, a1
596 ; RV32ZBB-NEXT:    ret
597   %cmp = icmp ult i32 %a, %b
598   %cond = select i1 %cmp, i32 %a, i32 %b
599   ret i32 %cond
602 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
603 ; don't have yet any matching bit manipulation instructions on RV32.
604 ; This test is presented here in case future expansions of the Bitmanip
605 ; extensions introduce instructions suitable for this pattern.
607 define i64 @minu_i64(i64 %a, i64 %b) nounwind {
608 ; RV32I-LABEL: minu_i64:
609 ; RV32I:       # %bb.0:
610 ; RV32I-NEXT:    beq a1, a3, .LBB15_2
611 ; RV32I-NEXT:  # %bb.1:
612 ; RV32I-NEXT:    sltu a4, a1, a3
613 ; RV32I-NEXT:    beqz a4, .LBB15_3
614 ; RV32I-NEXT:    j .LBB15_4
615 ; RV32I-NEXT:  .LBB15_2:
616 ; RV32I-NEXT:    sltu a4, a0, a2
617 ; RV32I-NEXT:    bnez a4, .LBB15_4
618 ; RV32I-NEXT:  .LBB15_3:
619 ; RV32I-NEXT:    mv a0, a2
620 ; RV32I-NEXT:    mv a1, a3
621 ; RV32I-NEXT:  .LBB15_4:
622 ; RV32I-NEXT:    ret
624 ; RV32ZBB-LABEL: minu_i64:
625 ; RV32ZBB:       # %bb.0:
626 ; RV32ZBB-NEXT:    mv a4, a0
627 ; RV32ZBB-NEXT:    bgeu a1, a3, .LBB15_3
628 ; RV32ZBB-NEXT:  # %bb.1:
629 ; RV32ZBB-NEXT:    beq a1, a3, .LBB15_4
630 ; RV32ZBB-NEXT:  .LBB15_2:
631 ; RV32ZBB-NEXT:    minu a1, a1, a3
632 ; RV32ZBB-NEXT:    ret
633 ; RV32ZBB-NEXT:  .LBB15_3:
634 ; RV32ZBB-NEXT:    mv a0, a2
635 ; RV32ZBB-NEXT:    bne a1, a3, .LBB15_2
636 ; RV32ZBB-NEXT:  .LBB15_4:
637 ; RV32ZBB-NEXT:    minu a0, a4, a2
638 ; RV32ZBB-NEXT:    minu a1, a1, a3
639 ; RV32ZBB-NEXT:    ret
640   %cmp = icmp ult i64 %a, %b
641   %cond = select i1 %cmp, i64 %a, i64 %b
642   ret i64 %cond
645 define i32 @maxu_i32(i32 %a, i32 %b) nounwind {
646 ; RV32I-LABEL: maxu_i32:
647 ; RV32I:       # %bb.0:
648 ; RV32I-NEXT:    bltu a1, a0, .LBB16_2
649 ; RV32I-NEXT:  # %bb.1:
650 ; RV32I-NEXT:    mv a0, a1
651 ; RV32I-NEXT:  .LBB16_2:
652 ; RV32I-NEXT:    ret
654 ; RV32ZBB-LABEL: maxu_i32:
655 ; RV32ZBB:       # %bb.0:
656 ; RV32ZBB-NEXT:    maxu a0, a0, a1
657 ; RV32ZBB-NEXT:    ret
658   %cmp = icmp ugt i32 %a, %b
659   %cond = select i1 %cmp, i32 %a, i32 %b
660   ret i32 %cond
663 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
664 ; don't have yet any matching bit manipulation instructions on RV32.
665 ; This test is presented here in case future expansions of the Bitmanip
666 ; extensions introduce instructions suitable for this pattern.
668 define i64 @maxu_i64(i64 %a, i64 %b) nounwind {
669 ; RV32I-LABEL: maxu_i64:
670 ; RV32I:       # %bb.0:
671 ; RV32I-NEXT:    beq a1, a3, .LBB17_2
672 ; RV32I-NEXT:  # %bb.1:
673 ; RV32I-NEXT:    sltu a4, a3, a1
674 ; RV32I-NEXT:    beqz a4, .LBB17_3
675 ; RV32I-NEXT:    j .LBB17_4
676 ; RV32I-NEXT:  .LBB17_2:
677 ; RV32I-NEXT:    sltu a4, a2, a0
678 ; RV32I-NEXT:    bnez a4, .LBB17_4
679 ; RV32I-NEXT:  .LBB17_3:
680 ; RV32I-NEXT:    mv a0, a2
681 ; RV32I-NEXT:    mv a1, a3
682 ; RV32I-NEXT:  .LBB17_4:
683 ; RV32I-NEXT:    ret
685 ; RV32ZBB-LABEL: maxu_i64:
686 ; RV32ZBB:       # %bb.0:
687 ; RV32ZBB-NEXT:    mv a4, a0
688 ; RV32ZBB-NEXT:    bgeu a3, a1, .LBB17_3
689 ; RV32ZBB-NEXT:  # %bb.1:
690 ; RV32ZBB-NEXT:    beq a1, a3, .LBB17_4
691 ; RV32ZBB-NEXT:  .LBB17_2:
692 ; RV32ZBB-NEXT:    maxu a1, a1, a3
693 ; RV32ZBB-NEXT:    ret
694 ; RV32ZBB-NEXT:  .LBB17_3:
695 ; RV32ZBB-NEXT:    mv a0, a2
696 ; RV32ZBB-NEXT:    bne a1, a3, .LBB17_2
697 ; RV32ZBB-NEXT:  .LBB17_4:
698 ; RV32ZBB-NEXT:    maxu a0, a4, a2
699 ; RV32ZBB-NEXT:    maxu a1, a1, a3
700 ; RV32ZBB-NEXT:    ret
701   %cmp = icmp ugt i64 %a, %b
702   %cond = select i1 %cmp, i64 %a, i64 %b
703   ret i64 %cond
706 declare i32 @llvm.abs.i32(i32, i1 immarg)
708 define i32 @abs_i32(i32 %x) {
709 ; RV32I-LABEL: abs_i32:
710 ; RV32I:       # %bb.0:
711 ; RV32I-NEXT:    srai a1, a0, 31
712 ; RV32I-NEXT:    xor a0, a0, a1
713 ; RV32I-NEXT:    sub a0, a0, a1
714 ; RV32I-NEXT:    ret
716 ; RV32ZBB-LABEL: abs_i32:
717 ; RV32ZBB:       # %bb.0:
718 ; RV32ZBB-NEXT:    neg a1, a0
719 ; RV32ZBB-NEXT:    max a0, a0, a1
720 ; RV32ZBB-NEXT:    ret
721   %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
722   ret i32 %abs
725 declare i64 @llvm.abs.i64(i64, i1 immarg)
727 define i64 @abs_i64(i64 %x) {
728 ; CHECK-LABEL: abs_i64:
729 ; CHECK:       # %bb.0:
730 ; CHECK-NEXT:    bgez a1, .LBB19_2
731 ; CHECK-NEXT:  # %bb.1:
732 ; CHECK-NEXT:    snez a2, a0
733 ; CHECK-NEXT:    neg a0, a0
734 ; CHECK-NEXT:    add a1, a1, a2
735 ; CHECK-NEXT:    neg a1, a1
736 ; CHECK-NEXT:  .LBB19_2:
737 ; CHECK-NEXT:    ret
738   %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
739   ret i64 %abs
742 define i32 @zexth_i32(i32 %a) nounwind {
743 ; RV32I-LABEL: zexth_i32:
744 ; RV32I:       # %bb.0:
745 ; RV32I-NEXT:    slli a0, a0, 16
746 ; RV32I-NEXT:    srli a0, a0, 16
747 ; RV32I-NEXT:    ret
749 ; RV32ZBB-LABEL: zexth_i32:
750 ; RV32ZBB:       # %bb.0:
751 ; RV32ZBB-NEXT:    zext.h a0, a0
752 ; RV32ZBB-NEXT:    ret
753   %and = and i32 %a, 65535
754   ret i32 %and
757 define i64 @zexth_i64(i64 %a) nounwind {
758 ; RV32I-LABEL: zexth_i64:
759 ; RV32I:       # %bb.0:
760 ; RV32I-NEXT:    slli a0, a0, 16
761 ; RV32I-NEXT:    srli a0, a0, 16
762 ; RV32I-NEXT:    li a1, 0
763 ; RV32I-NEXT:    ret
765 ; RV32ZBB-LABEL: zexth_i64:
766 ; RV32ZBB:       # %bb.0:
767 ; RV32ZBB-NEXT:    zext.h a0, a0
768 ; RV32ZBB-NEXT:    li a1, 0
769 ; RV32ZBB-NEXT:    ret
770   %and = and i64 %a, 65535
771   ret i64 %and
774 declare i32 @llvm.bswap.i32(i32)
776 define i32 @bswap_i32(i32 %a) nounwind {
777 ; RV32I-LABEL: bswap_i32:
778 ; RV32I:       # %bb.0:
779 ; RV32I-NEXT:    srli a1, a0, 8
780 ; RV32I-NEXT:    lui a2, 16
781 ; RV32I-NEXT:    addi a2, a2, -256
782 ; RV32I-NEXT:    and a1, a1, a2
783 ; RV32I-NEXT:    srli a2, a0, 24
784 ; RV32I-NEXT:    or a1, a1, a2
785 ; RV32I-NEXT:    slli a2, a0, 8
786 ; RV32I-NEXT:    lui a3, 4080
787 ; RV32I-NEXT:    and a2, a2, a3
788 ; RV32I-NEXT:    slli a0, a0, 24
789 ; RV32I-NEXT:    or a0, a0, a2
790 ; RV32I-NEXT:    or a0, a0, a1
791 ; RV32I-NEXT:    ret
793 ; RV32ZBB-LABEL: bswap_i32:
794 ; RV32ZBB:       # %bb.0:
795 ; RV32ZBB-NEXT:    rev8 a0, a0
796 ; RV32ZBB-NEXT:    ret
797   %1 = tail call i32 @llvm.bswap.i32(i32 %a)
798   ret i32 %1
801 declare i64 @llvm.bswap.i64(i64)
803 define i64 @bswap_i64(i64 %a) {
804 ; RV32I-LABEL: bswap_i64:
805 ; RV32I:       # %bb.0:
806 ; RV32I-NEXT:    srli a2, a1, 8
807 ; RV32I-NEXT:    lui a3, 16
808 ; RV32I-NEXT:    addi a3, a3, -256
809 ; RV32I-NEXT:    and a2, a2, a3
810 ; RV32I-NEXT:    srli a4, a1, 24
811 ; RV32I-NEXT:    or a2, a2, a4
812 ; RV32I-NEXT:    slli a4, a1, 8
813 ; RV32I-NEXT:    lui a5, 4080
814 ; RV32I-NEXT:    and a4, a4, a5
815 ; RV32I-NEXT:    slli a1, a1, 24
816 ; RV32I-NEXT:    or a1, a1, a4
817 ; RV32I-NEXT:    or a2, a1, a2
818 ; RV32I-NEXT:    srli a1, a0, 8
819 ; RV32I-NEXT:    and a1, a1, a3
820 ; RV32I-NEXT:    srli a3, a0, 24
821 ; RV32I-NEXT:    or a1, a1, a3
822 ; RV32I-NEXT:    slli a3, a0, 8
823 ; RV32I-NEXT:    and a3, a3, a5
824 ; RV32I-NEXT:    slli a0, a0, 24
825 ; RV32I-NEXT:    or a0, a0, a3
826 ; RV32I-NEXT:    or a1, a0, a1
827 ; RV32I-NEXT:    mv a0, a2
828 ; RV32I-NEXT:    ret
830 ; RV32ZBB-LABEL: bswap_i64:
831 ; RV32ZBB:       # %bb.0:
832 ; RV32ZBB-NEXT:    rev8 a2, a1
833 ; RV32ZBB-NEXT:    rev8 a1, a0
834 ; RV32ZBB-NEXT:    mv a0, a2
835 ; RV32ZBB-NEXT:    ret
836   %1 = call i64 @llvm.bswap.i64(i64 %a)
837   ret i64 %1