Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv64-legal-i32 / rv64zbb.ll
blob695ddd6d308ecbefa0b38c3272a6a5c1f4c3d9a1
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
3 ; RUN:   -riscv-experimental-rv64-legal-i32 | FileCheck %s -check-prefix=RV64I
4 ; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \
5 ; RUN:   -riscv-experimental-rv64-legal-i32 | FileCheck %s -check-prefix=RV64ZBB
7 declare i32 @llvm.ctlz.i32(i32, i1)
9 define signext i32 @ctlz_i32(i32 signext %a) nounwind {
10 ; RV64I-LABEL: ctlz_i32:
11 ; RV64I:       # %bb.0:
12 ; RV64I-NEXT:    beqz a0, .LBB0_2
13 ; RV64I-NEXT:  # %bb.1: # %cond.false
14 ; RV64I-NEXT:    addi sp, sp, -16
15 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
16 ; RV64I-NEXT:    srliw a1, a0, 1
17 ; RV64I-NEXT:    or a0, a0, a1
18 ; RV64I-NEXT:    srliw a1, a0, 2
19 ; RV64I-NEXT:    or a0, a0, a1
20 ; RV64I-NEXT:    srliw a1, a0, 4
21 ; RV64I-NEXT:    or a0, a0, a1
22 ; RV64I-NEXT:    srliw a1, a0, 8
23 ; RV64I-NEXT:    or a0, a0, a1
24 ; RV64I-NEXT:    srliw a1, a0, 16
25 ; RV64I-NEXT:    or a0, a0, a1
26 ; RV64I-NEXT:    not a0, a0
27 ; RV64I-NEXT:    srliw a1, a0, 1
28 ; RV64I-NEXT:    lui a2, 349525
29 ; RV64I-NEXT:    addi a2, a2, 1365
30 ; RV64I-NEXT:    and a1, a1, a2
31 ; RV64I-NEXT:    subw a0, a0, a1
32 ; RV64I-NEXT:    lui a1, 209715
33 ; RV64I-NEXT:    addi a1, a1, 819
34 ; RV64I-NEXT:    and a2, a0, a1
35 ; RV64I-NEXT:    srliw a0, a0, 2
36 ; RV64I-NEXT:    and a0, a0, a1
37 ; RV64I-NEXT:    add a0, a2, a0
38 ; RV64I-NEXT:    srliw a1, a0, 4
39 ; RV64I-NEXT:    addw a0, a0, a1
40 ; RV64I-NEXT:    lui a1, 61681
41 ; RV64I-NEXT:    addiw a1, a1, -241
42 ; RV64I-NEXT:    and a0, a0, a1
43 ; RV64I-NEXT:    lui a1, 4112
44 ; RV64I-NEXT:    addiw a1, a1, 257
45 ; RV64I-NEXT:    call __muldi3@plt
46 ; RV64I-NEXT:    srliw a0, a0, 24
47 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
48 ; RV64I-NEXT:    addi sp, sp, 16
49 ; RV64I-NEXT:    ret
50 ; RV64I-NEXT:  .LBB0_2:
51 ; RV64I-NEXT:    li a0, 32
52 ; RV64I-NEXT:    ret
54 ; RV64ZBB-LABEL: ctlz_i32:
55 ; RV64ZBB:       # %bb.0:
56 ; RV64ZBB-NEXT:    clzw a0, a0
57 ; RV64ZBB-NEXT:    ret
58   %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
59   ret i32 %1
62 define signext i32 @log2_i32(i32 signext %a) nounwind {
63 ; RV64I-LABEL: log2_i32:
64 ; RV64I:       # %bb.0:
65 ; RV64I-NEXT:    beqz a0, .LBB1_2
66 ; RV64I-NEXT:  # %bb.1: # %cond.false
67 ; RV64I-NEXT:    addi sp, sp, -16
68 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
69 ; RV64I-NEXT:    srliw a1, a0, 1
70 ; RV64I-NEXT:    or a0, a0, a1
71 ; RV64I-NEXT:    srliw a1, a0, 2
72 ; RV64I-NEXT:    or a0, a0, a1
73 ; RV64I-NEXT:    srliw a1, a0, 4
74 ; RV64I-NEXT:    or a0, a0, a1
75 ; RV64I-NEXT:    srliw a1, a0, 8
76 ; RV64I-NEXT:    or a0, a0, a1
77 ; RV64I-NEXT:    srliw a1, a0, 16
78 ; RV64I-NEXT:    or a0, a0, a1
79 ; RV64I-NEXT:    not a0, a0
80 ; RV64I-NEXT:    srliw a1, a0, 1
81 ; RV64I-NEXT:    lui a2, 349525
82 ; RV64I-NEXT:    addi a2, a2, 1365
83 ; RV64I-NEXT:    and a1, a1, a2
84 ; RV64I-NEXT:    subw a0, a0, a1
85 ; RV64I-NEXT:    lui a1, 209715
86 ; RV64I-NEXT:    addi a1, a1, 819
87 ; RV64I-NEXT:    and a2, a0, a1
88 ; RV64I-NEXT:    srliw a0, a0, 2
89 ; RV64I-NEXT:    and a0, a0, a1
90 ; RV64I-NEXT:    add a0, a2, a0
91 ; RV64I-NEXT:    srliw a1, a0, 4
92 ; RV64I-NEXT:    addw a0, a0, a1
93 ; RV64I-NEXT:    lui a1, 61681
94 ; RV64I-NEXT:    addiw a1, a1, -241
95 ; RV64I-NEXT:    and a0, a0, a1
96 ; RV64I-NEXT:    lui a1, 4112
97 ; RV64I-NEXT:    addiw a1, a1, 257
98 ; RV64I-NEXT:    call __muldi3@plt
99 ; RV64I-NEXT:    srliw a0, a0, 24
100 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
101 ; RV64I-NEXT:    addi sp, sp, 16
102 ; RV64I-NEXT:    j .LBB1_3
103 ; RV64I-NEXT:  .LBB1_2:
104 ; RV64I-NEXT:    li a0, 32
105 ; RV64I-NEXT:  .LBB1_3: # %cond.end
106 ; RV64I-NEXT:    li a1, 31
107 ; RV64I-NEXT:    subw a0, a1, a0
108 ; RV64I-NEXT:    ret
110 ; RV64ZBB-LABEL: log2_i32:
111 ; RV64ZBB:       # %bb.0:
112 ; RV64ZBB-NEXT:    clzw a0, a0
113 ; RV64ZBB-NEXT:    li a1, 31
114 ; RV64ZBB-NEXT:    subw a0, a1, a0
115 ; RV64ZBB-NEXT:    ret
116   %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
117   %2 = sub i32 31, %1
118   ret i32 %2
121 define signext i32 @log2_ceil_i32(i32 signext %a) nounwind {
122 ; RV64I-LABEL: log2_ceil_i32:
123 ; RV64I:       # %bb.0:
124 ; RV64I-NEXT:    addi sp, sp, -16
125 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
126 ; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
127 ; RV64I-NEXT:    addiw a0, a0, -1
128 ; RV64I-NEXT:    li s0, 32
129 ; RV64I-NEXT:    li a1, 32
130 ; RV64I-NEXT:    beqz a0, .LBB2_2
131 ; RV64I-NEXT:  # %bb.1: # %cond.false
132 ; RV64I-NEXT:    srliw a1, a0, 1
133 ; RV64I-NEXT:    or a0, a0, a1
134 ; RV64I-NEXT:    srliw a1, a0, 2
135 ; RV64I-NEXT:    or a0, a0, a1
136 ; RV64I-NEXT:    srliw a1, a0, 4
137 ; RV64I-NEXT:    or a0, a0, a1
138 ; RV64I-NEXT:    srliw a1, a0, 8
139 ; RV64I-NEXT:    or a0, a0, a1
140 ; RV64I-NEXT:    srliw a1, a0, 16
141 ; RV64I-NEXT:    or a0, a0, a1
142 ; RV64I-NEXT:    not a0, a0
143 ; RV64I-NEXT:    srliw a1, a0, 1
144 ; RV64I-NEXT:    lui a2, 349525
145 ; RV64I-NEXT:    addi a2, a2, 1365
146 ; RV64I-NEXT:    and a1, a1, a2
147 ; RV64I-NEXT:    subw a0, a0, a1
148 ; RV64I-NEXT:    lui a1, 209715
149 ; RV64I-NEXT:    addi a1, a1, 819
150 ; RV64I-NEXT:    and a2, a0, a1
151 ; RV64I-NEXT:    srliw a0, a0, 2
152 ; RV64I-NEXT:    and a0, a0, a1
153 ; RV64I-NEXT:    add a0, a2, a0
154 ; RV64I-NEXT:    srliw a1, a0, 4
155 ; RV64I-NEXT:    addw a0, a0, a1
156 ; RV64I-NEXT:    lui a1, 61681
157 ; RV64I-NEXT:    addiw a1, a1, -241
158 ; RV64I-NEXT:    and a0, a0, a1
159 ; RV64I-NEXT:    lui a1, 4112
160 ; RV64I-NEXT:    addiw a1, a1, 257
161 ; RV64I-NEXT:    call __muldi3@plt
162 ; RV64I-NEXT:    srliw a1, a0, 24
163 ; RV64I-NEXT:  .LBB2_2: # %cond.end
164 ; RV64I-NEXT:    subw a0, s0, a1
165 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
166 ; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
167 ; RV64I-NEXT:    addi sp, sp, 16
168 ; RV64I-NEXT:    ret
170 ; RV64ZBB-LABEL: log2_ceil_i32:
171 ; RV64ZBB:       # %bb.0:
172 ; RV64ZBB-NEXT:    addi a0, a0, -1
173 ; RV64ZBB-NEXT:    clzw a0, a0
174 ; RV64ZBB-NEXT:    li a1, 32
175 ; RV64ZBB-NEXT:    subw a0, a1, a0
176 ; RV64ZBB-NEXT:    ret
177   %1 = sub i32 %a, 1
178   %2 = call i32 @llvm.ctlz.i32(i32 %1, i1 false)
179   %3 = sub i32 32, %2
180   ret i32 %3
183 define signext i32 @findLastSet_i32(i32 signext %a) nounwind {
184 ; RV64I-LABEL: findLastSet_i32:
185 ; RV64I:       # %bb.0:
186 ; RV64I-NEXT:    addi sp, sp, -16
187 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
188 ; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
189 ; RV64I-NEXT:    mv s0, a0
190 ; RV64I-NEXT:    srliw a0, a0, 1
191 ; RV64I-NEXT:    or a0, s0, a0
192 ; RV64I-NEXT:    srliw a1, a0, 2
193 ; RV64I-NEXT:    or a0, a0, a1
194 ; RV64I-NEXT:    srliw a1, a0, 4
195 ; RV64I-NEXT:    or a0, a0, a1
196 ; RV64I-NEXT:    srliw a1, a0, 8
197 ; RV64I-NEXT:    or a0, a0, a1
198 ; RV64I-NEXT:    srliw a1, a0, 16
199 ; RV64I-NEXT:    or a0, a0, a1
200 ; RV64I-NEXT:    not a0, a0
201 ; RV64I-NEXT:    srliw a1, a0, 1
202 ; RV64I-NEXT:    lui a2, 349525
203 ; RV64I-NEXT:    addi a2, a2, 1365
204 ; RV64I-NEXT:    and a1, a1, a2
205 ; RV64I-NEXT:    subw a0, a0, a1
206 ; RV64I-NEXT:    lui a1, 209715
207 ; RV64I-NEXT:    addi a1, a1, 819
208 ; RV64I-NEXT:    and a2, a0, a1
209 ; RV64I-NEXT:    srliw a0, a0, 2
210 ; RV64I-NEXT:    and a0, a0, a1
211 ; RV64I-NEXT:    add a0, a2, a0
212 ; RV64I-NEXT:    srliw a1, a0, 4
213 ; RV64I-NEXT:    addw a0, a0, a1
214 ; RV64I-NEXT:    lui a1, 61681
215 ; RV64I-NEXT:    addiw a1, a1, -241
216 ; RV64I-NEXT:    and a0, a0, a1
217 ; RV64I-NEXT:    lui a1, 4112
218 ; RV64I-NEXT:    addiw a1, a1, 257
219 ; RV64I-NEXT:    call __muldi3@plt
220 ; RV64I-NEXT:    srliw a0, a0, 24
221 ; RV64I-NEXT:    xori a0, a0, 31
222 ; RV64I-NEXT:    snez a1, s0
223 ; RV64I-NEXT:    addiw a1, a1, -1
224 ; RV64I-NEXT:    or a0, a1, a0
225 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
226 ; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
227 ; RV64I-NEXT:    addi sp, sp, 16
228 ; RV64I-NEXT:    ret
230 ; RV64ZBB-LABEL: findLastSet_i32:
231 ; RV64ZBB:       # %bb.0:
232 ; RV64ZBB-NEXT:    clzw a1, a0
233 ; RV64ZBB-NEXT:    xori a1, a1, 31
234 ; RV64ZBB-NEXT:    snez a0, a0
235 ; RV64ZBB-NEXT:    addiw a0, a0, -1
236 ; RV64ZBB-NEXT:    or a0, a0, a1
237 ; RV64ZBB-NEXT:    ret
238   %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 true)
239   %2 = xor i32 31, %1
240   %3 = icmp eq i32 %a, 0
241   %4 = select i1 %3, i32 -1, i32 %2
242   ret i32 %4
245 define i32 @ctlz_lshr_i32(i32 signext %a) {
246 ; RV64I-LABEL: ctlz_lshr_i32:
247 ; RV64I:       # %bb.0:
248 ; RV64I-NEXT:    srliw a0, a0, 1
249 ; RV64I-NEXT:    beqz a0, .LBB4_2
250 ; RV64I-NEXT:  # %bb.1: # %cond.false
251 ; RV64I-NEXT:    addi sp, sp, -16
252 ; RV64I-NEXT:    .cfi_def_cfa_offset 16
253 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
254 ; RV64I-NEXT:    .cfi_offset ra, -8
255 ; RV64I-NEXT:    srliw a1, a0, 1
256 ; RV64I-NEXT:    or a0, a0, a1
257 ; RV64I-NEXT:    srliw a1, a0, 2
258 ; RV64I-NEXT:    or a0, a0, a1
259 ; RV64I-NEXT:    srliw a1, a0, 4
260 ; RV64I-NEXT:    or a0, a0, a1
261 ; RV64I-NEXT:    srliw a1, a0, 8
262 ; RV64I-NEXT:    or a0, a0, a1
263 ; RV64I-NEXT:    srliw a1, a0, 16
264 ; RV64I-NEXT:    or a0, a0, a1
265 ; RV64I-NEXT:    not a0, a0
266 ; RV64I-NEXT:    srliw a1, a0, 1
267 ; RV64I-NEXT:    lui a2, 349525
268 ; RV64I-NEXT:    addi a2, a2, 1365
269 ; RV64I-NEXT:    and a1, a1, a2
270 ; RV64I-NEXT:    subw a0, a0, a1
271 ; RV64I-NEXT:    lui a1, 209715
272 ; RV64I-NEXT:    addi a1, a1, 819
273 ; RV64I-NEXT:    and a2, a0, a1
274 ; RV64I-NEXT:    srliw a0, a0, 2
275 ; RV64I-NEXT:    and a0, a0, a1
276 ; RV64I-NEXT:    add a0, a2, a0
277 ; RV64I-NEXT:    srliw a1, a0, 4
278 ; RV64I-NEXT:    addw a0, a0, a1
279 ; RV64I-NEXT:    lui a1, 61681
280 ; RV64I-NEXT:    addiw a1, a1, -241
281 ; RV64I-NEXT:    and a0, a0, a1
282 ; RV64I-NEXT:    lui a1, 4112
283 ; RV64I-NEXT:    addiw a1, a1, 257
284 ; RV64I-NEXT:    call __muldi3@plt
285 ; RV64I-NEXT:    srliw a0, a0, 24
286 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
287 ; RV64I-NEXT:    addi sp, sp, 16
288 ; RV64I-NEXT:    ret
289 ; RV64I-NEXT:  .LBB4_2:
290 ; RV64I-NEXT:    li a0, 32
291 ; RV64I-NEXT:    ret
293 ; RV64ZBB-LABEL: ctlz_lshr_i32:
294 ; RV64ZBB:       # %bb.0:
295 ; RV64ZBB-NEXT:    srliw a0, a0, 1
296 ; RV64ZBB-NEXT:    clzw a0, a0
297 ; RV64ZBB-NEXT:    ret
298   %1 = lshr i32 %a, 1
299   %2 = call i32 @llvm.ctlz.i32(i32 %1, i1 false)
300   ret i32 %2
303 declare i64 @llvm.ctlz.i64(i64, i1)
305 define i64 @ctlz_i64(i64 %a) nounwind {
306 ; RV64I-LABEL: ctlz_i64:
307 ; RV64I:       # %bb.0:
308 ; RV64I-NEXT:    beqz a0, .LBB5_2
309 ; RV64I-NEXT:  # %bb.1: # %cond.false
310 ; RV64I-NEXT:    addi sp, sp, -16
311 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
312 ; RV64I-NEXT:    srli a1, a0, 1
313 ; RV64I-NEXT:    or a0, a0, a1
314 ; RV64I-NEXT:    srli a1, a0, 2
315 ; RV64I-NEXT:    or a0, a0, a1
316 ; RV64I-NEXT:    srli a1, a0, 4
317 ; RV64I-NEXT:    or a0, a0, a1
318 ; RV64I-NEXT:    srli a1, a0, 8
319 ; RV64I-NEXT:    or a0, a0, a1
320 ; RV64I-NEXT:    srli a1, a0, 16
321 ; RV64I-NEXT:    or a0, a0, a1
322 ; RV64I-NEXT:    srli a1, a0, 32
323 ; RV64I-NEXT:    or a0, a0, a1
324 ; RV64I-NEXT:    not a0, a0
325 ; RV64I-NEXT:    srli a1, a0, 1
326 ; RV64I-NEXT:    lui a2, 349525
327 ; RV64I-NEXT:    addiw a2, a2, 1365
328 ; RV64I-NEXT:    slli a3, a2, 32
329 ; RV64I-NEXT:    add a2, a2, a3
330 ; RV64I-NEXT:    and a1, a1, a2
331 ; RV64I-NEXT:    sub a0, a0, a1
332 ; RV64I-NEXT:    lui a1, 209715
333 ; RV64I-NEXT:    addiw a1, a1, 819
334 ; RV64I-NEXT:    slli a2, a1, 32
335 ; RV64I-NEXT:    add a1, a1, a2
336 ; RV64I-NEXT:    and a2, a0, a1
337 ; RV64I-NEXT:    srli a0, a0, 2
338 ; RV64I-NEXT:    and a0, a0, a1
339 ; RV64I-NEXT:    add a0, a2, a0
340 ; RV64I-NEXT:    srli a1, a0, 4
341 ; RV64I-NEXT:    add a0, a0, a1
342 ; RV64I-NEXT:    lui a1, 61681
343 ; RV64I-NEXT:    addiw a1, a1, -241
344 ; RV64I-NEXT:    slli a2, a1, 32
345 ; RV64I-NEXT:    add a1, a1, a2
346 ; RV64I-NEXT:    and a0, a0, a1
347 ; RV64I-NEXT:    lui a1, 4112
348 ; RV64I-NEXT:    addiw a1, a1, 257
349 ; RV64I-NEXT:    slli a2, a1, 32
350 ; RV64I-NEXT:    add a1, a1, a2
351 ; RV64I-NEXT:    call __muldi3@plt
352 ; RV64I-NEXT:    srli a0, a0, 56
353 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
354 ; RV64I-NEXT:    addi sp, sp, 16
355 ; RV64I-NEXT:    ret
356 ; RV64I-NEXT:  .LBB5_2:
357 ; RV64I-NEXT:    li a0, 64
358 ; RV64I-NEXT:    ret
360 ; RV64ZBB-LABEL: ctlz_i64:
361 ; RV64ZBB:       # %bb.0:
362 ; RV64ZBB-NEXT:    clz a0, a0
363 ; RV64ZBB-NEXT:    ret
364   %1 = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
365   ret i64 %1
368 declare i32 @llvm.cttz.i32(i32, i1)
370 define signext i32 @cttz_i32(i32 signext %a) nounwind {
371 ; RV64I-LABEL: cttz_i32:
372 ; RV64I:       # %bb.0:
373 ; RV64I-NEXT:    beqz a0, .LBB6_2
374 ; RV64I-NEXT:  # %bb.1: # %cond.false
375 ; RV64I-NEXT:    addi sp, sp, -16
376 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
377 ; RV64I-NEXT:    negw a1, a0
378 ; RV64I-NEXT:    and a0, a0, a1
379 ; RV64I-NEXT:    lui a1, 30667
380 ; RV64I-NEXT:    addiw a1, a1, 1329
381 ; RV64I-NEXT:    call __muldi3@plt
382 ; RV64I-NEXT:    srliw a0, a0, 27
383 ; RV64I-NEXT:    slli a0, a0, 32
384 ; RV64I-NEXT:    srli a0, a0, 32
385 ; RV64I-NEXT:    lui a1, %hi(.LCPI6_0)
386 ; RV64I-NEXT:    addi a1, a1, %lo(.LCPI6_0)
387 ; RV64I-NEXT:    add a0, a1, a0
388 ; RV64I-NEXT:    lbu a0, 0(a0)
389 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
390 ; RV64I-NEXT:    addi sp, sp, 16
391 ; RV64I-NEXT:    ret
392 ; RV64I-NEXT:  .LBB6_2:
393 ; RV64I-NEXT:    li a0, 32
394 ; RV64I-NEXT:    ret
396 ; RV64ZBB-LABEL: cttz_i32:
397 ; RV64ZBB:       # %bb.0:
398 ; RV64ZBB-NEXT:    ctzw a0, a0
399 ; RV64ZBB-NEXT:    ret
400   %1 = call i32 @llvm.cttz.i32(i32 %a, i1 false)
401   ret i32 %1
404 define signext i32 @cttz_zero_undef_i32(i32 signext %a) nounwind {
405 ; RV64I-LABEL: cttz_zero_undef_i32:
406 ; RV64I:       # %bb.0:
407 ; RV64I-NEXT:    addi sp, sp, -16
408 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
409 ; RV64I-NEXT:    negw a1, a0
410 ; RV64I-NEXT:    and a0, a0, a1
411 ; RV64I-NEXT:    lui a1, 30667
412 ; RV64I-NEXT:    addiw a1, a1, 1329
413 ; RV64I-NEXT:    call __muldi3@plt
414 ; RV64I-NEXT:    srliw a0, a0, 27
415 ; RV64I-NEXT:    slli a0, a0, 32
416 ; RV64I-NEXT:    srli a0, a0, 32
417 ; RV64I-NEXT:    lui a1, %hi(.LCPI7_0)
418 ; RV64I-NEXT:    addi a1, a1, %lo(.LCPI7_0)
419 ; RV64I-NEXT:    add a0, a1, a0
420 ; RV64I-NEXT:    lbu a0, 0(a0)
421 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
422 ; RV64I-NEXT:    addi sp, sp, 16
423 ; RV64I-NEXT:    ret
425 ; RV64ZBB-LABEL: cttz_zero_undef_i32:
426 ; RV64ZBB:       # %bb.0:
427 ; RV64ZBB-NEXT:    ctzw a0, a0
428 ; RV64ZBB-NEXT:    ret
429   %1 = call i32 @llvm.cttz.i32(i32 %a, i1 true)
430   ret i32 %1
433 define signext i32 @findFirstSet_i32(i32 signext %a) nounwind {
434 ; RV64I-LABEL: findFirstSet_i32:
435 ; RV64I:       # %bb.0:
436 ; RV64I-NEXT:    addi sp, sp, -16
437 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
438 ; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
439 ; RV64I-NEXT:    mv s0, a0
440 ; RV64I-NEXT:    negw a0, a0
441 ; RV64I-NEXT:    and a0, s0, a0
442 ; RV64I-NEXT:    lui a1, 30667
443 ; RV64I-NEXT:    addiw a1, a1, 1329
444 ; RV64I-NEXT:    call __muldi3@plt
445 ; RV64I-NEXT:    srliw a0, a0, 27
446 ; RV64I-NEXT:    slli a0, a0, 32
447 ; RV64I-NEXT:    srli a0, a0, 32
448 ; RV64I-NEXT:    lui a1, %hi(.LCPI8_0)
449 ; RV64I-NEXT:    addi a1, a1, %lo(.LCPI8_0)
450 ; RV64I-NEXT:    add a0, a1, a0
451 ; RV64I-NEXT:    lbu a0, 0(a0)
452 ; RV64I-NEXT:    snez a1, s0
453 ; RV64I-NEXT:    addi a1, a1, -1
454 ; RV64I-NEXT:    or a0, a1, a0
455 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
456 ; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
457 ; RV64I-NEXT:    addi sp, sp, 16
458 ; RV64I-NEXT:    ret
460 ; RV64ZBB-LABEL: findFirstSet_i32:
461 ; RV64ZBB:       # %bb.0:
462 ; RV64ZBB-NEXT:    ctzw a1, a0
463 ; RV64ZBB-NEXT:    snez a0, a0
464 ; RV64ZBB-NEXT:    addiw a0, a0, -1
465 ; RV64ZBB-NEXT:    or a0, a0, a1
466 ; RV64ZBB-NEXT:    ret
467   %1 = call i32 @llvm.cttz.i32(i32 %a, i1 true)
468   %2 = icmp eq i32 %a, 0
469   %3 = select i1 %2, i32 -1, i32 %1
470   ret i32 %3
473 define signext i32 @ffs_i32(i32 signext %a) nounwind {
474 ; RV64I-LABEL: ffs_i32:
475 ; RV64I:       # %bb.0:
476 ; RV64I-NEXT:    addi sp, sp, -16
477 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
478 ; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
479 ; RV64I-NEXT:    mv s0, a0
480 ; RV64I-NEXT:    negw a0, a0
481 ; RV64I-NEXT:    and a0, s0, a0
482 ; RV64I-NEXT:    lui a1, 30667
483 ; RV64I-NEXT:    addiw a1, a1, 1329
484 ; RV64I-NEXT:    call __muldi3@plt
485 ; RV64I-NEXT:    srliw a0, a0, 27
486 ; RV64I-NEXT:    slli a0, a0, 32
487 ; RV64I-NEXT:    srli a0, a0, 32
488 ; RV64I-NEXT:    lui a1, %hi(.LCPI9_0)
489 ; RV64I-NEXT:    addi a1, a1, %lo(.LCPI9_0)
490 ; RV64I-NEXT:    add a0, a1, a0
491 ; RV64I-NEXT:    lbu a0, 0(a0)
492 ; RV64I-NEXT:    addi a0, a0, 1
493 ; RV64I-NEXT:    seqz a1, s0
494 ; RV64I-NEXT:    addi a1, a1, -1
495 ; RV64I-NEXT:    and a0, a1, a0
496 ; RV64I-NEXT:    slli a0, a0, 32
497 ; RV64I-NEXT:    srli a0, a0, 32
498 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
499 ; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
500 ; RV64I-NEXT:    addi sp, sp, 16
501 ; RV64I-NEXT:    ret
503 ; RV64ZBB-LABEL: ffs_i32:
504 ; RV64ZBB:       # %bb.0:
505 ; RV64ZBB-NEXT:    ctzw a1, a0
506 ; RV64ZBB-NEXT:    addi a1, a1, 1
507 ; RV64ZBB-NEXT:    seqz a0, a0
508 ; RV64ZBB-NEXT:    addi a0, a0, -1
509 ; RV64ZBB-NEXT:    and a0, a0, a1
510 ; RV64ZBB-NEXT:    zext.h a0, a0
511 ; RV64ZBB-NEXT:    ret
512   %1 = call i32 @llvm.cttz.i32(i32 %a, i1 true)
513   %2 = add i32 %1, 1
514   %3 = icmp eq i32 %a, 0
515   %4 = select i1 %3, i32 0, i32 %2
516   ret i32 %4
519 declare i64 @llvm.cttz.i64(i64, i1)
521 define i64 @cttz_i64(i64 %a) nounwind {
522 ; RV64I-LABEL: cttz_i64:
523 ; RV64I:       # %bb.0:
524 ; RV64I-NEXT:    beqz a0, .LBB10_2
525 ; RV64I-NEXT:  # %bb.1: # %cond.false
526 ; RV64I-NEXT:    addi sp, sp, -16
527 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
528 ; RV64I-NEXT:    neg a1, a0
529 ; RV64I-NEXT:    and a0, a0, a1
530 ; RV64I-NEXT:    lui a1, %hi(.LCPI10_0)
531 ; RV64I-NEXT:    ld a1, %lo(.LCPI10_0)(a1)
532 ; RV64I-NEXT:    call __muldi3@plt
533 ; RV64I-NEXT:    srli a0, a0, 58
534 ; RV64I-NEXT:    lui a1, %hi(.LCPI10_1)
535 ; RV64I-NEXT:    addi a1, a1, %lo(.LCPI10_1)
536 ; RV64I-NEXT:    add a0, a1, a0
537 ; RV64I-NEXT:    lbu a0, 0(a0)
538 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
539 ; RV64I-NEXT:    addi sp, sp, 16
540 ; RV64I-NEXT:    ret
541 ; RV64I-NEXT:  .LBB10_2:
542 ; RV64I-NEXT:    li a0, 64
543 ; RV64I-NEXT:    ret
545 ; RV64ZBB-LABEL: cttz_i64:
546 ; RV64ZBB:       # %bb.0:
547 ; RV64ZBB-NEXT:    ctz a0, a0
548 ; RV64ZBB-NEXT:    ret
549   %1 = call i64 @llvm.cttz.i64(i64 %a, i1 false)
550   ret i64 %1
553 declare i32 @llvm.ctpop.i32(i32)
555 define signext i32 @ctpop_i32(i32 signext %a) nounwind {
556 ; RV64I-LABEL: ctpop_i32:
557 ; RV64I:       # %bb.0:
558 ; RV64I-NEXT:    addi sp, sp, -16
559 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
560 ; RV64I-NEXT:    srliw a1, a0, 1
561 ; RV64I-NEXT:    lui a2, 349525
562 ; RV64I-NEXT:    addi a2, a2, 1365
563 ; RV64I-NEXT:    and a1, a1, a2
564 ; RV64I-NEXT:    subw a0, a0, a1
565 ; RV64I-NEXT:    lui a1, 209715
566 ; RV64I-NEXT:    addi a1, a1, 819
567 ; RV64I-NEXT:    and a2, a0, a1
568 ; RV64I-NEXT:    srliw a0, a0, 2
569 ; RV64I-NEXT:    and a0, a0, a1
570 ; RV64I-NEXT:    add a0, a2, a0
571 ; RV64I-NEXT:    srliw a1, a0, 4
572 ; RV64I-NEXT:    addw a0, a0, a1
573 ; RV64I-NEXT:    lui a1, 61681
574 ; RV64I-NEXT:    addiw a1, a1, -241
575 ; RV64I-NEXT:    and a0, a0, a1
576 ; RV64I-NEXT:    lui a1, 4112
577 ; RV64I-NEXT:    addiw a1, a1, 257
578 ; RV64I-NEXT:    call __muldi3@plt
579 ; RV64I-NEXT:    srliw a0, a0, 24
580 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
581 ; RV64I-NEXT:    addi sp, sp, 16
582 ; RV64I-NEXT:    ret
584 ; RV64ZBB-LABEL: ctpop_i32:
585 ; RV64ZBB:       # %bb.0:
586 ; RV64ZBB-NEXT:    cpopw a0, a0
587 ; RV64ZBB-NEXT:    ret
588   %1 = call i32 @llvm.ctpop.i32(i32 %a)
589   ret i32 %1
592 define signext i32 @ctpop_i32_load(ptr %p) nounwind {
593 ; RV64I-LABEL: ctpop_i32_load:
594 ; RV64I:       # %bb.0:
595 ; RV64I-NEXT:    addi sp, sp, -16
596 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
597 ; RV64I-NEXT:    lw a0, 0(a0)
598 ; RV64I-NEXT:    srliw a1, a0, 1
599 ; RV64I-NEXT:    lui a2, 349525
600 ; RV64I-NEXT:    addi a2, a2, 1365
601 ; RV64I-NEXT:    and a1, a1, a2
602 ; RV64I-NEXT:    subw a0, a0, a1
603 ; RV64I-NEXT:    lui a1, 209715
604 ; RV64I-NEXT:    addi a1, a1, 819
605 ; RV64I-NEXT:    and a2, a0, a1
606 ; RV64I-NEXT:    srliw a0, a0, 2
607 ; RV64I-NEXT:    and a0, a0, a1
608 ; RV64I-NEXT:    add a0, a2, a0
609 ; RV64I-NEXT:    srliw a1, a0, 4
610 ; RV64I-NEXT:    addw a0, a0, a1
611 ; RV64I-NEXT:    lui a1, 61681
612 ; RV64I-NEXT:    addiw a1, a1, -241
613 ; RV64I-NEXT:    and a0, a0, a1
614 ; RV64I-NEXT:    lui a1, 4112
615 ; RV64I-NEXT:    addiw a1, a1, 257
616 ; RV64I-NEXT:    call __muldi3@plt
617 ; RV64I-NEXT:    srliw a0, a0, 24
618 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
619 ; RV64I-NEXT:    addi sp, sp, 16
620 ; RV64I-NEXT:    ret
622 ; RV64ZBB-LABEL: ctpop_i32_load:
623 ; RV64ZBB:       # %bb.0:
624 ; RV64ZBB-NEXT:    lw a0, 0(a0)
625 ; RV64ZBB-NEXT:    cpopw a0, a0
626 ; RV64ZBB-NEXT:    ret
627   %a = load i32, ptr %p
628   %1 = call i32 @llvm.ctpop.i32(i32 %a)
629   ret i32 %1
632 declare i64 @llvm.ctpop.i64(i64)
634 define i64 @ctpop_i64(i64 %a) nounwind {
635 ; RV64I-LABEL: ctpop_i64:
636 ; RV64I:       # %bb.0:
637 ; RV64I-NEXT:    addi sp, sp, -16
638 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
639 ; RV64I-NEXT:    srli a1, a0, 1
640 ; RV64I-NEXT:    lui a2, 349525
641 ; RV64I-NEXT:    addiw a2, a2, 1365
642 ; RV64I-NEXT:    slli a3, a2, 32
643 ; RV64I-NEXT:    add a2, a2, a3
644 ; RV64I-NEXT:    and a1, a1, a2
645 ; RV64I-NEXT:    sub a0, a0, a1
646 ; RV64I-NEXT:    lui a1, 209715
647 ; RV64I-NEXT:    addiw a1, a1, 819
648 ; RV64I-NEXT:    slli a2, a1, 32
649 ; RV64I-NEXT:    add a1, a1, a2
650 ; RV64I-NEXT:    and a2, a0, a1
651 ; RV64I-NEXT:    srli a0, a0, 2
652 ; RV64I-NEXT:    and a0, a0, a1
653 ; RV64I-NEXT:    add a0, a2, a0
654 ; RV64I-NEXT:    srli a1, a0, 4
655 ; RV64I-NEXT:    add a0, a0, a1
656 ; RV64I-NEXT:    lui a1, 61681
657 ; RV64I-NEXT:    addiw a1, a1, -241
658 ; RV64I-NEXT:    slli a2, a1, 32
659 ; RV64I-NEXT:    add a1, a1, a2
660 ; RV64I-NEXT:    and a0, a0, a1
661 ; RV64I-NEXT:    lui a1, 4112
662 ; RV64I-NEXT:    addiw a1, a1, 257
663 ; RV64I-NEXT:    slli a2, a1, 32
664 ; RV64I-NEXT:    add a1, a1, a2
665 ; RV64I-NEXT:    call __muldi3@plt
666 ; RV64I-NEXT:    srli a0, a0, 56
667 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
668 ; RV64I-NEXT:    addi sp, sp, 16
669 ; RV64I-NEXT:    ret
671 ; RV64ZBB-LABEL: ctpop_i64:
672 ; RV64ZBB:       # %bb.0:
673 ; RV64ZBB-NEXT:    cpop a0, a0
674 ; RV64ZBB-NEXT:    ret
675   %1 = call i64 @llvm.ctpop.i64(i64 %a)
676   ret i64 %1
679 define signext i32 @sextb_i32(i32 signext %a) nounwind {
680 ; RV64I-LABEL: sextb_i32:
681 ; RV64I:       # %bb.0:
682 ; RV64I-NEXT:    slli a0, a0, 56
683 ; RV64I-NEXT:    srai a0, a0, 56
684 ; RV64I-NEXT:    ret
686 ; RV64ZBB-LABEL: sextb_i32:
687 ; RV64ZBB:       # %bb.0:
688 ; RV64ZBB-NEXT:    sext.b a0, a0
689 ; RV64ZBB-NEXT:    ret
690   %shl = shl i32 %a, 24
691   %shr = ashr exact i32 %shl, 24
692   ret i32 %shr
695 define i64 @sextb_i64(i64 %a) nounwind {
696 ; RV64I-LABEL: sextb_i64:
697 ; RV64I:       # %bb.0:
698 ; RV64I-NEXT:    slli a0, a0, 56
699 ; RV64I-NEXT:    srai a0, a0, 56
700 ; RV64I-NEXT:    ret
702 ; RV64ZBB-LABEL: sextb_i64:
703 ; RV64ZBB:       # %bb.0:
704 ; RV64ZBB-NEXT:    sext.b a0, a0
705 ; RV64ZBB-NEXT:    ret
706   %shl = shl i64 %a, 56
707   %shr = ashr exact i64 %shl, 56
708   ret i64 %shr
711 define signext i32 @sexth_i32(i32 signext %a) nounwind {
712 ; RV64I-LABEL: sexth_i32:
713 ; RV64I:       # %bb.0:
714 ; RV64I-NEXT:    slli a0, a0, 48
715 ; RV64I-NEXT:    srai a0, a0, 48
716 ; RV64I-NEXT:    ret
718 ; RV64ZBB-LABEL: sexth_i32:
719 ; RV64ZBB:       # %bb.0:
720 ; RV64ZBB-NEXT:    sext.h a0, a0
721 ; RV64ZBB-NEXT:    ret
722   %shl = shl i32 %a, 16
723   %shr = ashr exact i32 %shl, 16
724   ret i32 %shr
727 define i64 @sexth_i64(i64 %a) nounwind {
728 ; RV64I-LABEL: sexth_i64:
729 ; RV64I:       # %bb.0:
730 ; RV64I-NEXT:    slli a0, a0, 48
731 ; RV64I-NEXT:    srai a0, a0, 48
732 ; RV64I-NEXT:    ret
734 ; RV64ZBB-LABEL: sexth_i64:
735 ; RV64ZBB:       # %bb.0:
736 ; RV64ZBB-NEXT:    sext.h a0, a0
737 ; RV64ZBB-NEXT:    ret
738   %shl = shl i64 %a, 48
739   %shr = ashr exact i64 %shl, 48
740   ret i64 %shr
743 define signext i32 @min_i32(i32 signext %a, i32 signext %b) nounwind {
744 ; RV64I-LABEL: min_i32:
745 ; RV64I:       # %bb.0:
746 ; RV64I-NEXT:    blt a0, a1, .LBB18_2
747 ; RV64I-NEXT:  # %bb.1:
748 ; RV64I-NEXT:    mv a0, a1
749 ; RV64I-NEXT:  .LBB18_2:
750 ; RV64I-NEXT:    ret
752 ; RV64ZBB-LABEL: min_i32:
753 ; RV64ZBB:       # %bb.0:
754 ; RV64ZBB-NEXT:    min a0, a0, a1
755 ; RV64ZBB-NEXT:    ret
756   %cmp = icmp slt i32 %a, %b
757   %cond = select i1 %cmp, i32 %a, i32 %b
758   ret i32 %cond
761 define i64 @min_i64(i64 %a, i64 %b) nounwind {
762 ; RV64I-LABEL: min_i64:
763 ; RV64I:       # %bb.0:
764 ; RV64I-NEXT:    blt a0, a1, .LBB19_2
765 ; RV64I-NEXT:  # %bb.1:
766 ; RV64I-NEXT:    mv a0, a1
767 ; RV64I-NEXT:  .LBB19_2:
768 ; RV64I-NEXT:    ret
770 ; RV64ZBB-LABEL: min_i64:
771 ; RV64ZBB:       # %bb.0:
772 ; RV64ZBB-NEXT:    min a0, a0, a1
773 ; RV64ZBB-NEXT:    ret
774   %cmp = icmp slt i64 %a, %b
775   %cond = select i1 %cmp, i64 %a, i64 %b
776   ret i64 %cond
779 define signext i32 @max_i32(i32 signext %a, i32 signext %b) nounwind {
780 ; RV64I-LABEL: max_i32:
781 ; RV64I:       # %bb.0:
782 ; RV64I-NEXT:    blt a1, a0, .LBB20_2
783 ; RV64I-NEXT:  # %bb.1:
784 ; RV64I-NEXT:    mv a0, a1
785 ; RV64I-NEXT:  .LBB20_2:
786 ; RV64I-NEXT:    ret
788 ; RV64ZBB-LABEL: max_i32:
789 ; RV64ZBB:       # %bb.0:
790 ; RV64ZBB-NEXT:    max a0, a0, a1
791 ; RV64ZBB-NEXT:    ret
792   %cmp = icmp sgt i32 %a, %b
793   %cond = select i1 %cmp, i32 %a, i32 %b
794   ret i32 %cond
797 define i64 @max_i64(i64 %a, i64 %b) nounwind {
798 ; RV64I-LABEL: max_i64:
799 ; RV64I:       # %bb.0:
800 ; RV64I-NEXT:    blt a1, a0, .LBB21_2
801 ; RV64I-NEXT:  # %bb.1:
802 ; RV64I-NEXT:    mv a0, a1
803 ; RV64I-NEXT:  .LBB21_2:
804 ; RV64I-NEXT:    ret
806 ; RV64ZBB-LABEL: max_i64:
807 ; RV64ZBB:       # %bb.0:
808 ; RV64ZBB-NEXT:    max a0, a0, a1
809 ; RV64ZBB-NEXT:    ret
810   %cmp = icmp sgt i64 %a, %b
811   %cond = select i1 %cmp, i64 %a, i64 %b
812   ret i64 %cond
815 define signext i32 @minu_i32(i32 signext %a, i32 signext %b) nounwind {
816 ; RV64I-LABEL: minu_i32:
817 ; RV64I:       # %bb.0:
818 ; RV64I-NEXT:    bltu a0, a1, .LBB22_2
819 ; RV64I-NEXT:  # %bb.1:
820 ; RV64I-NEXT:    mv a0, a1
821 ; RV64I-NEXT:  .LBB22_2:
822 ; RV64I-NEXT:    ret
824 ; RV64ZBB-LABEL: minu_i32:
825 ; RV64ZBB:       # %bb.0:
826 ; RV64ZBB-NEXT:    minu a0, a0, a1
827 ; RV64ZBB-NEXT:    ret
828   %cmp = icmp ult i32 %a, %b
829   %cond = select i1 %cmp, i32 %a, i32 %b
830   ret i32 %cond
833 define i64 @minu_i64(i64 %a, i64 %b) nounwind {
834 ; RV64I-LABEL: minu_i64:
835 ; RV64I:       # %bb.0:
836 ; RV64I-NEXT:    bltu a0, a1, .LBB23_2
837 ; RV64I-NEXT:  # %bb.1:
838 ; RV64I-NEXT:    mv a0, a1
839 ; RV64I-NEXT:  .LBB23_2:
840 ; RV64I-NEXT:    ret
842 ; RV64ZBB-LABEL: minu_i64:
843 ; RV64ZBB:       # %bb.0:
844 ; RV64ZBB-NEXT:    minu a0, a0, a1
845 ; RV64ZBB-NEXT:    ret
846   %cmp = icmp ult i64 %a, %b
847   %cond = select i1 %cmp, i64 %a, i64 %b
848   ret i64 %cond
851 define signext i32 @maxu_i32(i32 signext %a, i32 signext %b) nounwind {
852 ; RV64I-LABEL: maxu_i32:
853 ; RV64I:       # %bb.0:
854 ; RV64I-NEXT:    bltu a1, a0, .LBB24_2
855 ; RV64I-NEXT:  # %bb.1:
856 ; RV64I-NEXT:    mv a0, a1
857 ; RV64I-NEXT:  .LBB24_2:
858 ; RV64I-NEXT:    ret
860 ; RV64ZBB-LABEL: maxu_i32:
861 ; RV64ZBB:       # %bb.0:
862 ; RV64ZBB-NEXT:    maxu a0, a0, a1
863 ; RV64ZBB-NEXT:    ret
864   %cmp = icmp ugt i32 %a, %b
865   %cond = select i1 %cmp, i32 %a, i32 %b
866   ret i32 %cond
869 define i64 @maxu_i64(i64 %a, i64 %b) nounwind {
870 ; RV64I-LABEL: maxu_i64:
871 ; RV64I:       # %bb.0:
872 ; RV64I-NEXT:    bltu a1, a0, .LBB25_2
873 ; RV64I-NEXT:  # %bb.1:
874 ; RV64I-NEXT:    mv a0, a1
875 ; RV64I-NEXT:  .LBB25_2:
876 ; RV64I-NEXT:    ret
878 ; RV64ZBB-LABEL: maxu_i64:
879 ; RV64ZBB:       # %bb.0:
880 ; RV64ZBB-NEXT:    maxu a0, a0, a1
881 ; RV64ZBB-NEXT:    ret
882   %cmp = icmp ugt i64 %a, %b
883   %cond = select i1 %cmp, i64 %a, i64 %b
884   ret i64 %cond
887 declare i32 @llvm.abs.i32(i32, i1 immarg)
889 define i32 @abs_i32(i32 %x) {
890 ; RV64I-LABEL: abs_i32:
891 ; RV64I:       # %bb.0:
892 ; RV64I-NEXT:    sraiw a1, a0, 31
893 ; RV64I-NEXT:    xor a0, a0, a1
894 ; RV64I-NEXT:    subw a0, a0, a1
895 ; RV64I-NEXT:    ret
897 ; RV64ZBB-LABEL: abs_i32:
898 ; RV64ZBB:       # %bb.0:
899 ; RV64ZBB-NEXT:    sraiw a1, a0, 31
900 ; RV64ZBB-NEXT:    xor a0, a0, a1
901 ; RV64ZBB-NEXT:    subw a0, a0, a1
902 ; RV64ZBB-NEXT:    ret
903   %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
904   ret i32 %abs
907 define signext i32 @abs_i32_sext(i32 signext %x) {
908 ; RV64I-LABEL: abs_i32_sext:
909 ; RV64I:       # %bb.0:
910 ; RV64I-NEXT:    sraiw a1, a0, 31
911 ; RV64I-NEXT:    xor a0, a0, a1
912 ; RV64I-NEXT:    subw a0, a0, a1
913 ; RV64I-NEXT:    ret
915 ; RV64ZBB-LABEL: abs_i32_sext:
916 ; RV64ZBB:       # %bb.0:
917 ; RV64ZBB-NEXT:    sraiw a1, a0, 31
918 ; RV64ZBB-NEXT:    xor a0, a0, a1
919 ; RV64ZBB-NEXT:    subw a0, a0, a1
920 ; RV64ZBB-NEXT:    ret
921   %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
922   ret i32 %abs
925 declare i64 @llvm.abs.i64(i64, i1 immarg)
927 define i64 @abs_i64(i64 %x) {
928 ; RV64I-LABEL: abs_i64:
929 ; RV64I:       # %bb.0:
930 ; RV64I-NEXT:    srai a1, a0, 63
931 ; RV64I-NEXT:    xor a0, a0, a1
932 ; RV64I-NEXT:    sub a0, a0, a1
933 ; RV64I-NEXT:    ret
935 ; RV64ZBB-LABEL: abs_i64:
936 ; RV64ZBB:       # %bb.0:
937 ; RV64ZBB-NEXT:    neg a1, a0
938 ; RV64ZBB-NEXT:    max a0, a0, a1
939 ; RV64ZBB-NEXT:    ret
940   %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
941   ret i64 %abs
944 define i32 @zexth_i32(i32 %a) nounwind {
945 ; RV64I-LABEL: zexth_i32:
946 ; RV64I:       # %bb.0:
947 ; RV64I-NEXT:    lui a1, 16
948 ; RV64I-NEXT:    addiw a1, a1, -1
949 ; RV64I-NEXT:    and a0, a0, a1
950 ; RV64I-NEXT:    ret
952 ; RV64ZBB-LABEL: zexth_i32:
953 ; RV64ZBB:       # %bb.0:
954 ; RV64ZBB-NEXT:    lui a1, 16
955 ; RV64ZBB-NEXT:    addiw a1, a1, -1
956 ; RV64ZBB-NEXT:    and a0, a0, a1
957 ; RV64ZBB-NEXT:    ret
958   %and = and i32 %a, 65535
959   ret i32 %and
962 define i64 @zexth_i64(i64 %a) nounwind {
963 ; RV64I-LABEL: zexth_i64:
964 ; RV64I:       # %bb.0:
965 ; RV64I-NEXT:    slli a0, a0, 48
966 ; RV64I-NEXT:    srli a0, a0, 48
967 ; RV64I-NEXT:    ret
969 ; RV64ZBB-LABEL: zexth_i64:
970 ; RV64ZBB:       # %bb.0:
971 ; RV64ZBB-NEXT:    zext.h a0, a0
972 ; RV64ZBB-NEXT:    ret
973   %and = and i64 %a, 65535
974   ret i64 %and
977 declare i32 @llvm.bswap.i32(i32)
979 define signext i32 @bswap_i32(i32 signext %a) nounwind {
980 ; RV64I-LABEL: bswap_i32:
981 ; RV64I:       # %bb.0:
982 ; RV64I-NEXT:    srliw a1, a0, 8
983 ; RV64I-NEXT:    lui a2, 16
984 ; RV64I-NEXT:    addiw a2, a2, -256
985 ; RV64I-NEXT:    and a1, a1, a2
986 ; RV64I-NEXT:    srliw a3, a0, 24
987 ; RV64I-NEXT:    or a1, a1, a3
988 ; RV64I-NEXT:    and a2, a0, a2
989 ; RV64I-NEXT:    slliw a2, a2, 8
990 ; RV64I-NEXT:    slliw a0, a0, 24
991 ; RV64I-NEXT:    or a0, a0, a2
992 ; RV64I-NEXT:    or a0, a0, a1
993 ; RV64I-NEXT:    ret
995 ; RV64ZBB-LABEL: bswap_i32:
996 ; RV64ZBB:       # %bb.0:
997 ; RV64ZBB-NEXT:    rev8 a0, a0
998 ; RV64ZBB-NEXT:    srai a0, a0, 32
999 ; RV64ZBB-NEXT:    ret
1000   %1 = tail call i32 @llvm.bswap.i32(i32 %a)
1001   ret i32 %1
1004 ; Similar to bswap_i32 but the result is not sign extended.
1005 define void @bswap_i32_nosext(i32 signext %a, ptr %x) nounwind {
1006 ; RV64I-LABEL: bswap_i32_nosext:
1007 ; RV64I:       # %bb.0:
1008 ; RV64I-NEXT:    srliw a2, a0, 8
1009 ; RV64I-NEXT:    lui a3, 16
1010 ; RV64I-NEXT:    addi a3, a3, -256
1011 ; RV64I-NEXT:    and a2, a2, a3
1012 ; RV64I-NEXT:    srliw a4, a0, 24
1013 ; RV64I-NEXT:    or a2, a2, a4
1014 ; RV64I-NEXT:    and a3, a0, a3
1015 ; RV64I-NEXT:    slli a3, a3, 8
1016 ; RV64I-NEXT:    slli a0, a0, 24
1017 ; RV64I-NEXT:    or a0, a0, a3
1018 ; RV64I-NEXT:    or a0, a0, a2
1019 ; RV64I-NEXT:    sw a0, 0(a1)
1020 ; RV64I-NEXT:    ret
1022 ; RV64ZBB-LABEL: bswap_i32_nosext:
1023 ; RV64ZBB:       # %bb.0:
1024 ; RV64ZBB-NEXT:    rev8 a0, a0
1025 ; RV64ZBB-NEXT:    srli a0, a0, 32
1026 ; RV64ZBB-NEXT:    sw a0, 0(a1)
1027 ; RV64ZBB-NEXT:    ret
1028   %1 = tail call i32 @llvm.bswap.i32(i32 %a)
1029   store i32 %1, ptr %x
1030   ret void
1033 declare i64 @llvm.bswap.i64(i64)
1035 define i64 @bswap_i64(i64 %a) {
1036 ; RV64I-LABEL: bswap_i64:
1037 ; RV64I:       # %bb.0:
1038 ; RV64I-NEXT:    srli a1, a0, 40
1039 ; RV64I-NEXT:    lui a2, 16
1040 ; RV64I-NEXT:    addiw a2, a2, -256
1041 ; RV64I-NEXT:    and a1, a1, a2
1042 ; RV64I-NEXT:    srli a3, a0, 56
1043 ; RV64I-NEXT:    or a1, a1, a3
1044 ; RV64I-NEXT:    srli a3, a0, 24
1045 ; RV64I-NEXT:    lui a4, 4080
1046 ; RV64I-NEXT:    and a3, a3, a4
1047 ; RV64I-NEXT:    srli a5, a0, 8
1048 ; RV64I-NEXT:    srliw a5, a5, 24
1049 ; RV64I-NEXT:    slli a5, a5, 24
1050 ; RV64I-NEXT:    or a3, a5, a3
1051 ; RV64I-NEXT:    or a1, a3, a1
1052 ; RV64I-NEXT:    and a4, a0, a4
1053 ; RV64I-NEXT:    slli a4, a4, 24
1054 ; RV64I-NEXT:    srliw a3, a0, 24
1055 ; RV64I-NEXT:    slli a3, a3, 32
1056 ; RV64I-NEXT:    or a3, a4, a3
1057 ; RV64I-NEXT:    and a2, a0, a2
1058 ; RV64I-NEXT:    slli a2, a2, 40
1059 ; RV64I-NEXT:    slli a0, a0, 56
1060 ; RV64I-NEXT:    or a0, a0, a2
1061 ; RV64I-NEXT:    or a0, a0, a3
1062 ; RV64I-NEXT:    or a0, a0, a1
1063 ; RV64I-NEXT:    ret
1065 ; RV64ZBB-LABEL: bswap_i64:
1066 ; RV64ZBB:       # %bb.0:
1067 ; RV64ZBB-NEXT:    rev8 a0, a0
1068 ; RV64ZBB-NEXT:    ret
1069   %1 = call i64 @llvm.bswap.i64(i64 %a)
1070   ret i64 %1