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=RV32
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefixes=RV64
7 ;Copy tests from llvm/tests/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
8 ;to test shouldFormOverflowOp on RISCV
10 define i64 @uaddo1_overflow_used(i64 %a, i64 %b) nounwind ssp {
11 ; RV32-LABEL: uaddo1_overflow_used:
13 ; RV32-NEXT: add a5, a3, a1
14 ; RV32-NEXT: add a4, a2, a0
15 ; RV32-NEXT: sltu a6, a4, a2
16 ; RV32-NEXT: add a5, a5, a6
17 ; RV32-NEXT: beq a5, a1, .LBB0_2
19 ; RV32-NEXT: sltu a0, a5, a1
20 ; RV32-NEXT: beqz a0, .LBB0_3
21 ; RV32-NEXT: j .LBB0_4
23 ; RV32-NEXT: sltu a0, a4, a0
24 ; RV32-NEXT: bnez a0, .LBB0_4
26 ; RV32-NEXT: li a2, 42
28 ; RV32-NEXT: neg a1, a0
29 ; RV32-NEXT: and a1, a1, a3
30 ; RV32-NEXT: mv a0, a2
33 ; RV64-LABEL: uaddo1_overflow_used:
35 ; RV64-NEXT: add a2, a1, a0
36 ; RV64-NEXT: bltu a2, a0, .LBB0_2
38 ; RV64-NEXT: li a1, 42
40 ; RV64-NEXT: mv a0, a1
43 %cmp = icmp ult i64 %add, %a
44 %Q = select i1 %cmp, i64 %b, i64 42
48 define i64 @uaddo1_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {
49 ; RV32-LABEL: uaddo1_math_overflow_used:
51 ; RV32-NEXT: add a5, a3, a1
52 ; RV32-NEXT: add a0, a2, a0
53 ; RV32-NEXT: sltu a1, a0, a2
54 ; RV32-NEXT: add a5, a5, a1
55 ; RV32-NEXT: beq a5, a3, .LBB1_2
57 ; RV32-NEXT: sltu a1, a5, a3
59 ; RV32-NEXT: bnez a1, .LBB1_4
61 ; RV32-NEXT: li a2, 42
63 ; RV32-NEXT: neg a1, a1
64 ; RV32-NEXT: and a1, a1, a3
65 ; RV32-NEXT: sw a0, 0(a4)
66 ; RV32-NEXT: sw a5, 4(a4)
67 ; RV32-NEXT: mv a0, a2
70 ; RV64-LABEL: uaddo1_math_overflow_used:
72 ; RV64-NEXT: add a0, a1, a0
73 ; RV64-NEXT: bltu a0, a1, .LBB1_2
75 ; RV64-NEXT: li a1, 42
77 ; RV64-NEXT: sd a0, 0(a2)
78 ; RV64-NEXT: mv a0, a1
81 %cmp = icmp ult i64 %add, %a
82 %Q = select i1 %cmp, i64 %b, i64 42
83 store i64 %add, ptr %res
87 define i64 @uaddo2_overflow_used(i64 %a, i64 %b) nounwind ssp {
88 ; RV32-LABEL: uaddo2_overflow_used:
90 ; RV32-NEXT: add a1, a3, a1
91 ; RV32-NEXT: add a0, a2, a0
92 ; RV32-NEXT: sltu a0, a0, a2
93 ; RV32-NEXT: add a1, a1, a0
94 ; RV32-NEXT: beq a1, a3, .LBB2_2
96 ; RV32-NEXT: sltu a0, a1, a3
98 ; RV32-NEXT: bnez a0, .LBB2_4
100 ; RV32-NEXT: li a2, 42
101 ; RV32-NEXT: .LBB2_4:
102 ; RV32-NEXT: neg a1, a0
103 ; RV32-NEXT: and a1, a1, a3
104 ; RV32-NEXT: mv a0, a2
107 ; RV64-LABEL: uaddo2_overflow_used:
109 ; RV64-NEXT: add a0, a1, a0
110 ; RV64-NEXT: bltu a0, a1, .LBB2_2
111 ; RV64-NEXT: # %bb.1:
112 ; RV64-NEXT: li a1, 42
113 ; RV64-NEXT: .LBB2_2:
114 ; RV64-NEXT: mv a0, a1
116 %add = add i64 %b, %a
117 %cmp = icmp ult i64 %add, %b
118 %Q = select i1 %cmp, i64 %b, i64 42
122 define i64 @uaddo2_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {
123 ; RV32-LABEL: uaddo2_math_overflow_used:
125 ; RV32-NEXT: add a5, a3, a1
126 ; RV32-NEXT: add a0, a2, a0
127 ; RV32-NEXT: sltu a1, a0, a2
128 ; RV32-NEXT: add a5, a5, a1
129 ; RV32-NEXT: beq a5, a3, .LBB3_2
130 ; RV32-NEXT: # %bb.1:
131 ; RV32-NEXT: sltu a1, a5, a3
132 ; RV32-NEXT: .LBB3_2:
133 ; RV32-NEXT: bnez a1, .LBB3_4
134 ; RV32-NEXT: # %bb.3:
135 ; RV32-NEXT: li a2, 42
136 ; RV32-NEXT: .LBB3_4:
137 ; RV32-NEXT: neg a1, a1
138 ; RV32-NEXT: and a1, a1, a3
139 ; RV32-NEXT: sw a0, 0(a4)
140 ; RV32-NEXT: sw a5, 4(a4)
141 ; RV32-NEXT: mv a0, a2
144 ; RV64-LABEL: uaddo2_math_overflow_used:
146 ; RV64-NEXT: add a0, a1, a0
147 ; RV64-NEXT: bltu a0, a1, .LBB3_2
148 ; RV64-NEXT: # %bb.1:
149 ; RV64-NEXT: li a1, 42
150 ; RV64-NEXT: .LBB3_2:
151 ; RV64-NEXT: sd a0, 0(a2)
152 ; RV64-NEXT: mv a0, a1
154 %add = add i64 %b, %a
155 %cmp = icmp ult i64 %add, %b
156 %Q = select i1 %cmp, i64 %b, i64 42
157 store i64 %add, ptr %res
161 define i64 @uaddo3_overflow_used(i64 %a, i64 %b) nounwind ssp {
162 ; RV32-LABEL: uaddo3_overflow_used:
164 ; RV32-NEXT: add a1, a3, a1
165 ; RV32-NEXT: add a0, a2, a0
166 ; RV32-NEXT: sltu a0, a0, a2
167 ; RV32-NEXT: add a1, a1, a0
168 ; RV32-NEXT: beq a3, a1, .LBB4_2
169 ; RV32-NEXT: # %bb.1:
170 ; RV32-NEXT: sltu a0, a1, a3
171 ; RV32-NEXT: .LBB4_2:
172 ; RV32-NEXT: bnez a0, .LBB4_4
173 ; RV32-NEXT: # %bb.3:
174 ; RV32-NEXT: li a2, 42
175 ; RV32-NEXT: .LBB4_4:
176 ; RV32-NEXT: neg a1, a0
177 ; RV32-NEXT: and a1, a1, a3
178 ; RV32-NEXT: mv a0, a2
181 ; RV64-LABEL: uaddo3_overflow_used:
183 ; RV64-NEXT: add a0, a1, a0
184 ; RV64-NEXT: bltu a0, a1, .LBB4_2
185 ; RV64-NEXT: # %bb.1:
186 ; RV64-NEXT: li a1, 42
187 ; RV64-NEXT: .LBB4_2:
188 ; RV64-NEXT: mv a0, a1
190 %add = add i64 %b, %a
191 %cmp = icmp ugt i64 %b, %add
192 %Q = select i1 %cmp, i64 %b, i64 42
196 define i64 @uaddo3_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {
197 ; RV32-LABEL: uaddo3_math_overflow_used:
199 ; RV32-NEXT: add a5, a3, a1
200 ; RV32-NEXT: add a0, a2, a0
201 ; RV32-NEXT: sltu a1, a0, a2
202 ; RV32-NEXT: add a5, a5, a1
203 ; RV32-NEXT: beq a5, a3, .LBB5_2
204 ; RV32-NEXT: # %bb.1:
205 ; RV32-NEXT: sltu a1, a5, a3
206 ; RV32-NEXT: .LBB5_2:
207 ; RV32-NEXT: bnez a1, .LBB5_4
208 ; RV32-NEXT: # %bb.3:
209 ; RV32-NEXT: li a2, 42
210 ; RV32-NEXT: .LBB5_4:
211 ; RV32-NEXT: neg a1, a1
212 ; RV32-NEXT: and a1, a1, a3
213 ; RV32-NEXT: sw a0, 0(a4)
214 ; RV32-NEXT: sw a5, 4(a4)
215 ; RV32-NEXT: mv a0, a2
218 ; RV64-LABEL: uaddo3_math_overflow_used:
220 ; RV64-NEXT: add a0, a1, a0
221 ; RV64-NEXT: bltu a0, a1, .LBB5_2
222 ; RV64-NEXT: # %bb.1:
223 ; RV64-NEXT: li a1, 42
224 ; RV64-NEXT: .LBB5_2:
225 ; RV64-NEXT: sd a0, 0(a2)
226 ; RV64-NEXT: mv a0, a1
228 %add = add i64 %b, %a
229 %cmp = icmp ugt i64 %b, %add
230 %Q = select i1 %cmp, i64 %b, i64 42
231 store i64 %add, ptr %res
235 ; TODO? CGP sinks the compare before we have a chance to form the overflow intrinsic.
237 define i64 @uaddo4(i64 %a, i64 %b, i1 %c) nounwind ssp {
238 ; RV32-LABEL: uaddo4:
239 ; RV32: # %bb.0: # %entry
240 ; RV32-NEXT: andi a4, a4, 1
241 ; RV32-NEXT: beqz a4, .LBB6_6
242 ; RV32-NEXT: # %bb.1: # %next
243 ; RV32-NEXT: add a1, a3, a1
244 ; RV32-NEXT: add a0, a2, a0
245 ; RV32-NEXT: sltu a0, a0, a2
246 ; RV32-NEXT: add a1, a1, a0
247 ; RV32-NEXT: beq a3, a1, .LBB6_3
248 ; RV32-NEXT: # %bb.2: # %next
249 ; RV32-NEXT: sltu a0, a1, a3
250 ; RV32-NEXT: .LBB6_3: # %next
251 ; RV32-NEXT: bnez a0, .LBB6_5
252 ; RV32-NEXT: # %bb.4: # %next
253 ; RV32-NEXT: li a2, 42
254 ; RV32-NEXT: .LBB6_5: # %next
255 ; RV32-NEXT: neg a1, a0
256 ; RV32-NEXT: and a1, a1, a3
257 ; RV32-NEXT: mv a0, a2
259 ; RV32-NEXT: .LBB6_6: # %exit
260 ; RV32-NEXT: li a0, 0
261 ; RV32-NEXT: li a1, 0
264 ; RV64-LABEL: uaddo4:
265 ; RV64: # %bb.0: # %entry
266 ; RV64-NEXT: andi a2, a2, 1
267 ; RV64-NEXT: beqz a2, .LBB6_4
268 ; RV64-NEXT: # %bb.1: # %next
269 ; RV64-NEXT: add a0, a1, a0
270 ; RV64-NEXT: bltu a0, a1, .LBB6_3
271 ; RV64-NEXT: # %bb.2: # %next
272 ; RV64-NEXT: li a1, 42
273 ; RV64-NEXT: .LBB6_3: # %next
274 ; RV64-NEXT: mv a0, a1
276 ; RV64-NEXT: .LBB6_4: # %exit
277 ; RV64-NEXT: li a0, 0
280 %add = add i64 %b, %a
281 %cmp = icmp ugt i64 %b, %add
282 br i1 %c, label %next, label %exit
285 %Q = select i1 %cmp, i64 %b, i64 42
292 define i64 @uaddo5(i64 %a, i64 %b, ptr %ptr, i1 %c) nounwind ssp {
293 ; RV32-LABEL: uaddo5:
294 ; RV32: # %bb.0: # %entry
295 ; RV32-NEXT: andi a5, a5, 1
296 ; RV32-NEXT: add a1, a3, a1
297 ; RV32-NEXT: add a6, a2, a0
298 ; RV32-NEXT: sltu a0, a6, a2
299 ; RV32-NEXT: add a1, a1, a0
300 ; RV32-NEXT: sw a6, 0(a4)
301 ; RV32-NEXT: sw a1, 4(a4)
302 ; RV32-NEXT: beqz a5, .LBB7_6
303 ; RV32-NEXT: # %bb.1: # %next
304 ; RV32-NEXT: beq a3, a1, .LBB7_3
305 ; RV32-NEXT: # %bb.2: # %next
306 ; RV32-NEXT: sltu a0, a1, a3
307 ; RV32-NEXT: .LBB7_3: # %next
308 ; RV32-NEXT: bnez a0, .LBB7_5
309 ; RV32-NEXT: # %bb.4: # %next
310 ; RV32-NEXT: li a2, 42
311 ; RV32-NEXT: .LBB7_5: # %next
312 ; RV32-NEXT: neg a1, a0
313 ; RV32-NEXT: and a1, a1, a3
314 ; RV32-NEXT: mv a0, a2
316 ; RV32-NEXT: .LBB7_6: # %exit
317 ; RV32-NEXT: li a0, 0
318 ; RV32-NEXT: li a1, 0
321 ; RV64-LABEL: uaddo5:
322 ; RV64: # %bb.0: # %entry
323 ; RV64-NEXT: andi a3, a3, 1
324 ; RV64-NEXT: add a0, a1, a0
325 ; RV64-NEXT: sd a0, 0(a2)
326 ; RV64-NEXT: beqz a3, .LBB7_4
327 ; RV64-NEXT: # %bb.1: # %next
328 ; RV64-NEXT: bltu a0, a1, .LBB7_3
329 ; RV64-NEXT: # %bb.2: # %next
330 ; RV64-NEXT: li a1, 42
331 ; RV64-NEXT: .LBB7_3: # %next
332 ; RV64-NEXT: mv a0, a1
334 ; RV64-NEXT: .LBB7_4: # %exit
335 ; RV64-NEXT: li a0, 0
338 %add = add i64 %b, %a
339 store i64 %add, ptr %ptr
340 %cmp = icmp ugt i64 %b, %add
341 br i1 %c, label %next, label %exit
344 %Q = select i1 %cmp, i64 %b, i64 42
351 ; Instcombine folds (a + b <u a) to (a ^ -1 <u b). Make sure we match this
353 define i64 @uaddo6_xor(i64 %a, i64 %b) {
354 ; RV32-LABEL: uaddo6_xor:
356 ; RV32-NEXT: not a1, a1
357 ; RV32-NEXT: beq a1, a3, .LBB8_2
358 ; RV32-NEXT: # %bb.1:
359 ; RV32-NEXT: sltu a0, a1, a3
360 ; RV32-NEXT: beqz a0, .LBB8_3
361 ; RV32-NEXT: j .LBB8_4
362 ; RV32-NEXT: .LBB8_2:
363 ; RV32-NEXT: not a0, a0
364 ; RV32-NEXT: sltu a0, a0, a2
365 ; RV32-NEXT: bnez a0, .LBB8_4
366 ; RV32-NEXT: .LBB8_3:
367 ; RV32-NEXT: li a2, 42
368 ; RV32-NEXT: .LBB8_4:
369 ; RV32-NEXT: neg a1, a0
370 ; RV32-NEXT: and a1, a1, a3
371 ; RV32-NEXT: mv a0, a2
374 ; RV64-LABEL: uaddo6_xor:
376 ; RV64-NEXT: not a2, a0
377 ; RV64-NEXT: mv a0, a1
378 ; RV64-NEXT: bltu a2, a1, .LBB8_2
379 ; RV64-NEXT: # %bb.1:
380 ; RV64-NEXT: li a0, 42
381 ; RV64-NEXT: .LBB8_2:
384 %cmp = icmp ult i64 %x, %b
385 %Q = select i1 %cmp, i64 %b, i64 42
389 define i64 @uaddo6_xor_commuted(i64 %a, i64 %b) {
390 ; RV32-LABEL: uaddo6_xor_commuted:
392 ; RV32-NEXT: not a1, a1
393 ; RV32-NEXT: beq a1, a3, .LBB9_2
394 ; RV32-NEXT: # %bb.1:
395 ; RV32-NEXT: sltu a0, a1, a3
396 ; RV32-NEXT: beqz a0, .LBB9_3
397 ; RV32-NEXT: j .LBB9_4
398 ; RV32-NEXT: .LBB9_2:
399 ; RV32-NEXT: not a0, a0
400 ; RV32-NEXT: sltu a0, a0, a2
401 ; RV32-NEXT: bnez a0, .LBB9_4
402 ; RV32-NEXT: .LBB9_3:
403 ; RV32-NEXT: li a2, 42
404 ; RV32-NEXT: .LBB9_4:
405 ; RV32-NEXT: neg a1, a0
406 ; RV32-NEXT: and a1, a1, a3
407 ; RV32-NEXT: mv a0, a2
410 ; RV64-LABEL: uaddo6_xor_commuted:
412 ; RV64-NEXT: not a2, a0
413 ; RV64-NEXT: mv a0, a1
414 ; RV64-NEXT: bltu a2, a1, .LBB9_2
415 ; RV64-NEXT: # %bb.1:
416 ; RV64-NEXT: li a0, 42
417 ; RV64-NEXT: .LBB9_2:
420 %cmp = icmp ult i64 %x, %b
421 %Q = select i1 %cmp, i64 %b, i64 42
425 declare void @use(i64)
427 define i64 @uaddo6_xor_multi_use(i64 %a, i64 %b) {
428 ; RV32-LABEL: uaddo6_xor_multi_use:
430 ; RV32-NEXT: addi sp, sp, -16
431 ; RV32-NEXT: .cfi_def_cfa_offset 16
432 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
433 ; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
434 ; RV32-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
435 ; RV32-NEXT: .cfi_offset ra, -4
436 ; RV32-NEXT: .cfi_offset s0, -8
437 ; RV32-NEXT: .cfi_offset s1, -12
438 ; RV32-NEXT: mv s0, a2
439 ; RV32-NEXT: not a1, a1
440 ; RV32-NEXT: not a0, a0
441 ; RV32-NEXT: beq a1, a3, .LBB10_2
442 ; RV32-NEXT: # %bb.1:
443 ; RV32-NEXT: sltu a2, a1, a3
444 ; RV32-NEXT: beqz a2, .LBB10_3
445 ; RV32-NEXT: j .LBB10_4
446 ; RV32-NEXT: .LBB10_2:
447 ; RV32-NEXT: sltu a2, a0, s0
448 ; RV32-NEXT: bnez a2, .LBB10_4
449 ; RV32-NEXT: .LBB10_3:
450 ; RV32-NEXT: li s0, 42
451 ; RV32-NEXT: .LBB10_4:
452 ; RV32-NEXT: neg s1, a2
453 ; RV32-NEXT: and s1, s1, a3
454 ; RV32-NEXT: call use
455 ; RV32-NEXT: mv a0, s0
456 ; RV32-NEXT: mv a1, s1
457 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
458 ; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
459 ; RV32-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
460 ; RV32-NEXT: addi sp, sp, 16
463 ; RV64-LABEL: uaddo6_xor_multi_use:
465 ; RV64-NEXT: addi sp, sp, -16
466 ; RV64-NEXT: .cfi_def_cfa_offset 16
467 ; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
468 ; RV64-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
469 ; RV64-NEXT: .cfi_offset ra, -8
470 ; RV64-NEXT: .cfi_offset s0, -16
471 ; RV64-NEXT: not a0, a0
472 ; RV64-NEXT: mv s0, a1
473 ; RV64-NEXT: bltu a0, a1, .LBB10_2
474 ; RV64-NEXT: # %bb.1:
475 ; RV64-NEXT: li s0, 42
476 ; RV64-NEXT: .LBB10_2:
477 ; RV64-NEXT: call use
478 ; RV64-NEXT: mv a0, s0
479 ; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
480 ; RV64-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
481 ; RV64-NEXT: addi sp, sp, 16
484 %cmp = icmp ult i64 %x, %b
485 %Q = select i1 %cmp, i64 %b, i64 42
486 call void @use(i64 %x)
490 ; Make sure we do not use the XOR binary operator as insert point, as it may
491 ; come before the second operand of the overflow intrinsic.
492 define i1 @uaddo6_xor_op_after_XOR(i32 %a, ptr %b.ptr) {
493 ; RV32-LABEL: uaddo6_xor_op_after_XOR:
495 ; RV32-NEXT: lw a1, 0(a1)
496 ; RV32-NEXT: not a0, a0
497 ; RV32-NEXT: sltu a0, a0, a1
498 ; RV32-NEXT: xori a0, a0, 1
501 ; RV64-LABEL: uaddo6_xor_op_after_XOR:
503 ; RV64-NEXT: lw a1, 0(a1)
504 ; RV64-NEXT: not a0, a0
505 ; RV64-NEXT: sext.w a0, a0
506 ; RV64-NEXT: sltu a0, a0, a1
507 ; RV64-NEXT: xori a0, a0, 1
510 %b = load i32, ptr %b.ptr, align 8
511 %cmp14 = icmp ugt i32 %b, %x
512 %ov = xor i1 %cmp14, true
516 ; When adding 1, the general pattern for add-overflow may be different due to icmp canonicalization.
517 ; PR31754: https://bugs.llvm.org/show_bug.cgi?id=31754
519 define i1 @uaddo_i64_increment(i64 %x, ptr %p) {
520 ; RV32-LABEL: uaddo_i64_increment:
522 ; RV32-NEXT: addi a3, a0, 1
523 ; RV32-NEXT: seqz a0, a3
524 ; RV32-NEXT: add a1, a1, a0
525 ; RV32-NEXT: or a0, a3, a1
526 ; RV32-NEXT: seqz a0, a0
527 ; RV32-NEXT: sw a3, 0(a2)
528 ; RV32-NEXT: sw a1, 4(a2)
531 ; RV64-LABEL: uaddo_i64_increment:
533 ; RV64-NEXT: addi a2, a0, 1
534 ; RV64-NEXT: seqz a0, a2
535 ; RV64-NEXT: sd a2, 0(a1)
538 %ov = icmp eq i64 %a, 0
543 define i1 @uaddo_i8_increment_noncanonical_1(i8 %x, ptr %p) {
544 ; RV32-LABEL: uaddo_i8_increment_noncanonical_1:
546 ; RV32-NEXT: addi a2, a0, 1
547 ; RV32-NEXT: andi a0, a2, 255
548 ; RV32-NEXT: seqz a0, a0
549 ; RV32-NEXT: sb a2, 0(a1)
552 ; RV64-LABEL: uaddo_i8_increment_noncanonical_1:
554 ; RV64-NEXT: addi a2, a0, 1
555 ; RV64-NEXT: andi a0, a2, 255
556 ; RV64-NEXT: seqz a0, a0
557 ; RV64-NEXT: sb a2, 0(a1)
559 %a = add i8 1, %x ; commute
560 %ov = icmp eq i8 %a, 0
565 define i1 @uaddo_i32_increment_noncanonical_2(i32 %x, ptr %p) {
566 ; RV32-LABEL: uaddo_i32_increment_noncanonical_2:
568 ; RV32-NEXT: addi a2, a0, 1
569 ; RV32-NEXT: seqz a0, a2
570 ; RV32-NEXT: sw a2, 0(a1)
573 ; RV64-LABEL: uaddo_i32_increment_noncanonical_2:
575 ; RV64-NEXT: addiw a2, a0, 1
576 ; RV64-NEXT: seqz a0, a2
577 ; RV64-NEXT: sw a2, 0(a1)
580 %ov = icmp eq i32 0, %a ; commute
585 define i1 @uaddo_i16_increment_noncanonical_3(i16 %x, ptr %p) {
586 ; RV32-LABEL: uaddo_i16_increment_noncanonical_3:
588 ; RV32-NEXT: addi a2, a0, 1
589 ; RV32-NEXT: slli a0, a2, 16
590 ; RV32-NEXT: srli a0, a0, 16
591 ; RV32-NEXT: seqz a0, a0
592 ; RV32-NEXT: sh a2, 0(a1)
595 ; RV64-LABEL: uaddo_i16_increment_noncanonical_3:
597 ; RV64-NEXT: addi a2, a0, 1
598 ; RV64-NEXT: slli a0, a2, 48
599 ; RV64-NEXT: srli a0, a0, 48
600 ; RV64-NEXT: seqz a0, a0
601 ; RV64-NEXT: sh a2, 0(a1)
603 %a = add i16 1, %x ; commute
604 %ov = icmp eq i16 0, %a ; commute
609 ; The overflow check may be against the input rather than the sum.
611 define i1 @uaddo_i64_increment_alt(i64 %x, ptr %p) {
612 ; RV32-LABEL: uaddo_i64_increment_alt:
614 ; RV32-NEXT: addi a3, a0, 1
615 ; RV32-NEXT: seqz a0, a3
616 ; RV32-NEXT: add a1, a1, a0
617 ; RV32-NEXT: or a0, a3, a1
618 ; RV32-NEXT: seqz a0, a0
619 ; RV32-NEXT: sw a3, 0(a2)
620 ; RV32-NEXT: sw a1, 4(a2)
623 ; RV64-LABEL: uaddo_i64_increment_alt:
625 ; RV64-NEXT: addi a2, a0, 1
626 ; RV64-NEXT: seqz a0, a2
627 ; RV64-NEXT: sd a2, 0(a1)
631 %ov = icmp eq i64 %x, -1
635 ; Make sure insertion is done correctly based on dominance.
637 define i1 @uaddo_i64_increment_alt_dom(i64 %x, ptr %p) {
638 ; RV32-LABEL: uaddo_i64_increment_alt_dom:
640 ; RV32-NEXT: addi a3, a0, 1
641 ; RV32-NEXT: seqz a0, a3
642 ; RV32-NEXT: add a1, a1, a0
643 ; RV32-NEXT: or a0, a3, a1
644 ; RV32-NEXT: seqz a0, a0
645 ; RV32-NEXT: sw a3, 0(a2)
646 ; RV32-NEXT: sw a1, 4(a2)
649 ; RV64-LABEL: uaddo_i64_increment_alt_dom:
651 ; RV64-NEXT: addi a2, a0, 1
652 ; RV64-NEXT: seqz a0, a2
653 ; RV64-NEXT: sd a2, 0(a1)
655 %ov = icmp eq i64 %x, -1
661 ; The overflow check may be against the input rather than the sum.
663 define i1 @uaddo_i32_decrement_alt(i32 signext %x, ptr %p) {
664 ; RV32-LABEL: uaddo_i32_decrement_alt:
666 ; RV32-NEXT: snez a2, a0
667 ; RV32-NEXT: addi a0, a0, -1
668 ; RV32-NEXT: sw a0, 0(a1)
669 ; RV32-NEXT: mv a0, a2
672 ; RV64-LABEL: uaddo_i32_decrement_alt:
674 ; RV64-NEXT: snez a2, a0
675 ; RV64-NEXT: addi a0, a0, -1
676 ; RV64-NEXT: sw a0, 0(a1)
677 ; RV64-NEXT: mv a0, a2
681 %ov = icmp ne i32 %x, 0
685 define i1 @uaddo_i64_decrement_alt(i64 %x, ptr %p) {
686 ; RV32-LABEL: uaddo_i64_decrement_alt:
688 ; RV32-NEXT: or a3, a0, a1
689 ; RV32-NEXT: snez a3, a3
690 ; RV32-NEXT: seqz a4, a0
691 ; RV32-NEXT: sub a1, a1, a4
692 ; RV32-NEXT: addi a0, a0, -1
693 ; RV32-NEXT: sw a0, 0(a2)
694 ; RV32-NEXT: sw a1, 4(a2)
695 ; RV32-NEXT: mv a0, a3
698 ; RV64-LABEL: uaddo_i64_decrement_alt:
700 ; RV64-NEXT: snez a2, a0
701 ; RV64-NEXT: addi a0, a0, -1
702 ; RV64-NEXT: sd a0, 0(a1)
703 ; RV64-NEXT: mv a0, a2
707 %ov = icmp ne i64 %x, 0
711 ; Make sure insertion is done correctly based on dominance.
713 define i1 @uaddo_i64_decrement_alt_dom(i64 %x, ptr %p) {
714 ; RV32-LABEL: uaddo_i64_decrement_alt_dom:
716 ; RV32-NEXT: or a3, a0, a1
717 ; RV32-NEXT: snez a3, a3
718 ; RV32-NEXT: seqz a4, a0
719 ; RV32-NEXT: sub a1, a1, a4
720 ; RV32-NEXT: addi a0, a0, -1
721 ; RV32-NEXT: sw a0, 0(a2)
722 ; RV32-NEXT: sw a1, 4(a2)
723 ; RV32-NEXT: mv a0, a3
726 ; RV64-LABEL: uaddo_i64_decrement_alt_dom:
728 ; RV64-NEXT: snez a2, a0
729 ; RV64-NEXT: addi a0, a0, -1
730 ; RV64-NEXT: sd a0, 0(a1)
731 ; RV64-NEXT: mv a0, a2
733 %ov = icmp ne i64 %x, 0
739 ; No transform for illegal types.
741 define i1 @uaddo_i42_increment_illegal_type(i42 %x, ptr %p) {
742 ; RV32-LABEL: uaddo_i42_increment_illegal_type:
744 ; RV32-NEXT: addi a3, a0, 1
745 ; RV32-NEXT: seqz a0, a3
746 ; RV32-NEXT: add a0, a1, a0
747 ; RV32-NEXT: andi a1, a0, 1023
748 ; RV32-NEXT: or a0, a3, a1
749 ; RV32-NEXT: seqz a0, a0
750 ; RV32-NEXT: sw a3, 0(a2)
751 ; RV32-NEXT: sh a1, 4(a2)
754 ; RV64-LABEL: uaddo_i42_increment_illegal_type:
756 ; RV64-NEXT: addi a2, a0, 1
757 ; RV64-NEXT: slli a0, a2, 22
758 ; RV64-NEXT: srli a3, a0, 22
759 ; RV64-NEXT: seqz a0, a3
760 ; RV64-NEXT: sw a2, 0(a1)
761 ; RV64-NEXT: srli a3, a3, 32
762 ; RV64-NEXT: sh a3, 4(a1)
765 %ov = icmp eq i42 %a, 0
770 define i1 @usubo_ult_i64_overflow_used(i64 %x, i64 %y, ptr %p) {
771 ; RV32-LABEL: usubo_ult_i64_overflow_used:
773 ; RV32-NEXT: beq a1, a3, .LBB22_2
774 ; RV32-NEXT: # %bb.1:
775 ; RV32-NEXT: sltu a0, a1, a3
777 ; RV32-NEXT: .LBB22_2:
778 ; RV32-NEXT: sltu a0, a0, a2
781 ; RV64-LABEL: usubo_ult_i64_overflow_used:
783 ; RV64-NEXT: sltu a0, a0, a1
786 %ov = icmp ult i64 %x, %y
790 define i1 @usubo_ult_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {
791 ; RV32-LABEL: usubo_ult_i64_math_overflow_used:
793 ; RV32-NEXT: mv a5, a0
794 ; RV32-NEXT: sltu a0, a0, a2
795 ; RV32-NEXT: sub a6, a1, a3
796 ; RV32-NEXT: sub a6, a6, a0
797 ; RV32-NEXT: sub a5, a5, a2
798 ; RV32-NEXT: sw a5, 0(a4)
799 ; RV32-NEXT: sw a6, 4(a4)
800 ; RV32-NEXT: beq a1, a3, .LBB23_2
801 ; RV32-NEXT: # %bb.1:
802 ; RV32-NEXT: sltu a0, a1, a3
803 ; RV32-NEXT: .LBB23_2:
806 ; RV64-LABEL: usubo_ult_i64_math_overflow_used:
808 ; RV64-NEXT: sub a3, a0, a1
809 ; RV64-NEXT: sltu a0, a0, a1
810 ; RV64-NEXT: sd a3, 0(a2)
814 %ov = icmp ult i64 %x, %y
818 ; Verify insertion point for single-BB. Toggle predicate.
820 define i1 @usubo_ugt_i32(i32 %x, i32 %y, ptr %p) {
821 ; RV32-LABEL: usubo_ugt_i32:
823 ; RV32-NEXT: sltu a3, a0, a1
824 ; RV32-NEXT: sub a0, a0, a1
825 ; RV32-NEXT: sw a0, 0(a2)
826 ; RV32-NEXT: mv a0, a3
829 ; RV64-LABEL: usubo_ugt_i32:
831 ; RV64-NEXT: sext.w a3, a1
832 ; RV64-NEXT: sext.w a4, a0
833 ; RV64-NEXT: sltu a3, a4, a3
834 ; RV64-NEXT: subw a0, a0, a1
835 ; RV64-NEXT: sw a0, 0(a2)
836 ; RV64-NEXT: mv a0, a3
838 %ov = icmp ugt i32 %y, %x
844 ; Constant operand should match.
846 define i1 @usubo_ugt_constant_op0_i8(i8 %x, ptr %p) {
847 ; RV32-LABEL: usubo_ugt_constant_op0_i8:
849 ; RV32-NEXT: andi a2, a0, 255
850 ; RV32-NEXT: li a3, 42
851 ; RV32-NEXT: sub a3, a3, a0
852 ; RV32-NEXT: sltiu a0, a2, 43
853 ; RV32-NEXT: xori a0, a0, 1
854 ; RV32-NEXT: sb a3, 0(a1)
857 ; RV64-LABEL: usubo_ugt_constant_op0_i8:
859 ; RV64-NEXT: andi a2, a0, 255
860 ; RV64-NEXT: li a3, 42
861 ; RV64-NEXT: subw a3, a3, a0
862 ; RV64-NEXT: sltiu a0, a2, 43
863 ; RV64-NEXT: xori a0, a0, 1
864 ; RV64-NEXT: sb a3, 0(a1)
867 %ov = icmp ugt i8 %x, 42
872 ; Compare with constant operand 0 is canonicalized by commuting, but verify match for non-canonical form.
874 define i1 @usubo_ult_constant_op0_i16(i16 %x, ptr %p) {
875 ; RV32-LABEL: usubo_ult_constant_op0_i16:
877 ; RV32-NEXT: slli a2, a0, 16
878 ; RV32-NEXT: srli a2, a2, 16
879 ; RV32-NEXT: li a3, 43
880 ; RV32-NEXT: sub a3, a3, a0
881 ; RV32-NEXT: sltiu a0, a2, 44
882 ; RV32-NEXT: xori a0, a0, 1
883 ; RV32-NEXT: sh a3, 0(a1)
886 ; RV64-LABEL: usubo_ult_constant_op0_i16:
888 ; RV64-NEXT: slli a2, a0, 48
889 ; RV64-NEXT: srli a2, a2, 48
890 ; RV64-NEXT: li a3, 43
891 ; RV64-NEXT: subw a3, a3, a0
892 ; RV64-NEXT: sltiu a0, a2, 44
893 ; RV64-NEXT: xori a0, a0, 1
894 ; RV64-NEXT: sh a3, 0(a1)
897 %ov = icmp ult i16 43, %x
902 ; Subtract with constant operand 1 is canonicalized to add.
904 define i1 @usubo_ult_constant_op1_i16(i16 %x, ptr %p) {
905 ; RV32-LABEL: usubo_ult_constant_op1_i16:
907 ; RV32-NEXT: slli a2, a0, 16
908 ; RV32-NEXT: srli a2, a2, 16
909 ; RV32-NEXT: addi a3, a0, -44
910 ; RV32-NEXT: sltiu a0, a2, 44
911 ; RV32-NEXT: sh a3, 0(a1)
914 ; RV64-LABEL: usubo_ult_constant_op1_i16:
916 ; RV64-NEXT: slli a2, a0, 48
917 ; RV64-NEXT: srli a2, a2, 48
918 ; RV64-NEXT: addi a3, a0, -44
919 ; RV64-NEXT: sltiu a0, a2, 44
920 ; RV64-NEXT: sh a3, 0(a1)
923 %ov = icmp ult i16 %x, 44
928 define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) {
929 ; RV32-LABEL: usubo_ugt_constant_op1_i8:
931 ; RV32-NEXT: andi a2, a0, 255
932 ; RV32-NEXT: sltiu a2, a2, 45
933 ; RV32-NEXT: addi a0, a0, -45
934 ; RV32-NEXT: sb a0, 0(a1)
935 ; RV32-NEXT: mv a0, a2
938 ; RV64-LABEL: usubo_ugt_constant_op1_i8:
940 ; RV64-NEXT: andi a2, a0, 255
941 ; RV64-NEXT: sltiu a2, a2, 45
942 ; RV64-NEXT: addi a0, a0, -45
943 ; RV64-NEXT: sb a0, 0(a1)
944 ; RV64-NEXT: mv a0, a2
946 %ov = icmp ugt i8 45, %x
952 ; Special-case: subtract 1 changes the compare predicate and constant.
954 define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) {
955 ; RV32-LABEL: usubo_eq_constant1_op1_i32:
957 ; RV32-NEXT: addi a2, a0, -1
958 ; RV32-NEXT: seqz a0, a0
959 ; RV32-NEXT: sw a2, 0(a1)
962 ; RV64-LABEL: usubo_eq_constant1_op1_i32:
964 ; RV64-NEXT: sext.w a2, a0
965 ; RV64-NEXT: addi a3, a0, -1
966 ; RV64-NEXT: seqz a0, a2
967 ; RV64-NEXT: sw a3, 0(a1)
970 %ov = icmp eq i32 %x, 0
975 ; Special-case: subtract from 0 (negate) changes the compare predicate.
977 define i1 @usubo_ne_constant0_op1_i32(i32 %x, ptr %p) {
978 ; RV32-LABEL: usubo_ne_constant0_op1_i32:
980 ; RV32-NEXT: neg a2, a0
981 ; RV32-NEXT: snez a0, a0
982 ; RV32-NEXT: sw a2, 0(a1)
985 ; RV64-LABEL: usubo_ne_constant0_op1_i32:
987 ; RV64-NEXT: sext.w a2, a0
988 ; RV64-NEXT: negw a3, a0
989 ; RV64-NEXT: snez a0, a2
990 ; RV64-NEXT: sw a3, 0(a1)
993 %ov = icmp ne i32 %x, 0
998 ; This used to verify insertion point for multi-BB, but now we just bail out.
1000 declare void @call(i1)
1002 define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) {
1003 ; RV32-LABEL: usubo_ult_sub_dominates_i64:
1004 ; RV32: # %bb.0: # %entry
1005 ; RV32-NEXT: andi a6, a5, 1
1006 ; RV32-NEXT: beqz a6, .LBB31_5
1007 ; RV32-NEXT: # %bb.1: # %t
1008 ; RV32-NEXT: mv a7, a0
1009 ; RV32-NEXT: sltu a0, a0, a2
1010 ; RV32-NEXT: sub t0, a1, a3
1011 ; RV32-NEXT: sub t0, t0, a0
1012 ; RV32-NEXT: sub a2, a7, a2
1013 ; RV32-NEXT: sw a2, 0(a4)
1014 ; RV32-NEXT: sw t0, 4(a4)
1015 ; RV32-NEXT: beqz a6, .LBB31_5
1016 ; RV32-NEXT: # %bb.2: # %end
1017 ; RV32-NEXT: beq a1, a3, .LBB31_4
1018 ; RV32-NEXT: # %bb.3: # %end
1019 ; RV32-NEXT: sltu a0, a1, a3
1020 ; RV32-NEXT: .LBB31_4: # %end
1022 ; RV32-NEXT: .LBB31_5: # %f
1023 ; RV32-NEXT: mv a0, a5
1026 ; RV64-LABEL: usubo_ult_sub_dominates_i64:
1027 ; RV64: # %bb.0: # %entry
1028 ; RV64-NEXT: andi a4, a3, 1
1029 ; RV64-NEXT: beqz a4, .LBB31_3
1030 ; RV64-NEXT: # %bb.1: # %t
1031 ; RV64-NEXT: sub a5, a0, a1
1032 ; RV64-NEXT: sd a5, 0(a2)
1033 ; RV64-NEXT: beqz a4, .LBB31_3
1034 ; RV64-NEXT: # %bb.2: # %end
1035 ; RV64-NEXT: sltu a0, a0, a1
1037 ; RV64-NEXT: .LBB31_3: # %f
1038 ; RV64-NEXT: mv a0, a3
1041 br i1 %cond, label %t, label %f
1045 store i64 %s, ptr %p
1046 br i1 %cond, label %end, label %f
1052 %ov = icmp ult i64 %x, %y
1056 define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) {
1057 ; RV32-LABEL: usubo_ult_cmp_dominates_i64:
1058 ; RV32: # %bb.0: # %entry
1059 ; RV32-NEXT: addi sp, sp, -32
1060 ; RV32-NEXT: .cfi_def_cfa_offset 32
1061 ; RV32-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
1062 ; RV32-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
1063 ; RV32-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
1064 ; RV32-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
1065 ; RV32-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
1066 ; RV32-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
1067 ; RV32-NEXT: sw s5, 4(sp) # 4-byte Folded Spill
1068 ; RV32-NEXT: sw s6, 0(sp) # 4-byte Folded Spill
1069 ; RV32-NEXT: .cfi_offset ra, -4
1070 ; RV32-NEXT: .cfi_offset s0, -8
1071 ; RV32-NEXT: .cfi_offset s1, -12
1072 ; RV32-NEXT: .cfi_offset s2, -16
1073 ; RV32-NEXT: .cfi_offset s3, -20
1074 ; RV32-NEXT: .cfi_offset s4, -24
1075 ; RV32-NEXT: .cfi_offset s5, -28
1076 ; RV32-NEXT: .cfi_offset s6, -32
1077 ; RV32-NEXT: mv s2, a5
1078 ; RV32-NEXT: andi a5, a5, 1
1079 ; RV32-NEXT: beqz a5, .LBB32_8
1080 ; RV32-NEXT: # %bb.1: # %t
1081 ; RV32-NEXT: mv s0, a4
1082 ; RV32-NEXT: mv s3, a3
1083 ; RV32-NEXT: mv s1, a2
1084 ; RV32-NEXT: mv s5, a1
1085 ; RV32-NEXT: mv s4, a0
1086 ; RV32-NEXT: beq a1, a3, .LBB32_3
1087 ; RV32-NEXT: # %bb.2: # %t
1088 ; RV32-NEXT: sltu s6, s5, s3
1089 ; RV32-NEXT: j .LBB32_4
1090 ; RV32-NEXT: .LBB32_3:
1091 ; RV32-NEXT: sltu s6, s4, s1
1092 ; RV32-NEXT: .LBB32_4: # %t
1093 ; RV32-NEXT: mv a0, s6
1094 ; RV32-NEXT: call call
1095 ; RV32-NEXT: beqz s6, .LBB32_8
1096 ; RV32-NEXT: # %bb.5: # %end
1097 ; RV32-NEXT: sltu a1, s4, s1
1098 ; RV32-NEXT: mv a0, a1
1099 ; RV32-NEXT: beq s5, s3, .LBB32_7
1100 ; RV32-NEXT: # %bb.6: # %end
1101 ; RV32-NEXT: sltu a0, s5, s3
1102 ; RV32-NEXT: .LBB32_7: # %end
1103 ; RV32-NEXT: sub a2, s5, s3
1104 ; RV32-NEXT: sub a2, a2, a1
1105 ; RV32-NEXT: sub a1, s4, s1
1106 ; RV32-NEXT: sw a1, 0(s0)
1107 ; RV32-NEXT: sw a2, 4(s0)
1108 ; RV32-NEXT: j .LBB32_9
1109 ; RV32-NEXT: .LBB32_8: # %f
1110 ; RV32-NEXT: mv a0, s2
1111 ; RV32-NEXT: .LBB32_9: # %f
1112 ; RV32-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1113 ; RV32-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1114 ; RV32-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
1115 ; RV32-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
1116 ; RV32-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
1117 ; RV32-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
1118 ; RV32-NEXT: lw s5, 4(sp) # 4-byte Folded Reload
1119 ; RV32-NEXT: lw s6, 0(sp) # 4-byte Folded Reload
1120 ; RV32-NEXT: addi sp, sp, 32
1123 ; RV64-LABEL: usubo_ult_cmp_dominates_i64:
1124 ; RV64: # %bb.0: # %entry
1125 ; RV64-NEXT: addi sp, sp, -48
1126 ; RV64-NEXT: .cfi_def_cfa_offset 48
1127 ; RV64-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
1128 ; RV64-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
1129 ; RV64-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
1130 ; RV64-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
1131 ; RV64-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
1132 ; RV64-NEXT: sd s4, 0(sp) # 8-byte Folded Spill
1133 ; RV64-NEXT: .cfi_offset ra, -8
1134 ; RV64-NEXT: .cfi_offset s0, -16
1135 ; RV64-NEXT: .cfi_offset s1, -24
1136 ; RV64-NEXT: .cfi_offset s2, -32
1137 ; RV64-NEXT: .cfi_offset s3, -40
1138 ; RV64-NEXT: .cfi_offset s4, -48
1139 ; RV64-NEXT: mv s0, a3
1140 ; RV64-NEXT: andi a3, a3, 1
1141 ; RV64-NEXT: beqz a3, .LBB32_3
1142 ; RV64-NEXT: # %bb.1: # %t
1143 ; RV64-NEXT: mv s1, a2
1144 ; RV64-NEXT: mv s2, a1
1145 ; RV64-NEXT: mv s3, a0
1146 ; RV64-NEXT: sltu s4, a0, a1
1147 ; RV64-NEXT: mv a0, s4
1148 ; RV64-NEXT: call call
1149 ; RV64-NEXT: bgeu s3, s2, .LBB32_3
1150 ; RV64-NEXT: # %bb.2: # %end
1151 ; RV64-NEXT: sub a0, s3, s2
1152 ; RV64-NEXT: sd a0, 0(s1)
1153 ; RV64-NEXT: mv a0, s4
1154 ; RV64-NEXT: j .LBB32_4
1155 ; RV64-NEXT: .LBB32_3: # %f
1156 ; RV64-NEXT: mv a0, s0
1157 ; RV64-NEXT: .LBB32_4: # %f
1158 ; RV64-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
1159 ; RV64-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
1160 ; RV64-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
1161 ; RV64-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
1162 ; RV64-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
1163 ; RV64-NEXT: ld s4, 0(sp) # 8-byte Folded Reload
1164 ; RV64-NEXT: addi sp, sp, 48
1167 br i1 %cond, label %t, label %f
1170 %ov = icmp ult i64 %x, %y
1171 call void @call(i1 %ov)
1172 br i1 %ov, label %end, label %f
1179 store i64 %s, ptr %p
1183 ; Verify that crazy/non-canonical code does not crash.
1185 define void @bar() {
1191 %cmp = icmp eq i64 1, -1
1192 %frombool = zext i1 %cmp to i8
1196 define void @foo() {
1202 %sub = add nsw i64 1, 1
1203 %conv = trunc i64 %sub to i32
1207 ; Similarly for usubo.
1212 ; RV32-NEXT: li a0, 0
1217 ; RV64-NEXT: li a0, 0
1219 %cmp = icmp eq i64 1, 0
1223 define i64 @foo2(ptr %p) {
1226 ; RV32-NEXT: li a0, 0
1227 ; RV32-NEXT: li a1, 0
1232 ; RV64-NEXT: li a0, 0
1234 %sub = add nsw i64 1, -1
1238 ; Avoid hoisting a math op into a dominating block which would
1239 ; increase the critical path.
1241 define void @PR41129(ptr %p64) {
1242 ; RV32-LABEL: PR41129:
1243 ; RV32: # %bb.0: # %entry
1244 ; RV32-NEXT: lw a2, 4(a0)
1245 ; RV32-NEXT: lw a1, 0(a0)
1246 ; RV32-NEXT: or a3, a1, a2
1247 ; RV32-NEXT: beqz a3, .LBB37_2
1248 ; RV32-NEXT: # %bb.1: # %false
1249 ; RV32-NEXT: andi a1, a1, 7
1250 ; RV32-NEXT: sw zero, 4(a0)
1251 ; RV32-NEXT: sw a1, 0(a0)
1253 ; RV32-NEXT: .LBB37_2: # %true
1254 ; RV32-NEXT: seqz a3, a1
1255 ; RV32-NEXT: sub a2, a2, a3
1256 ; RV32-NEXT: addi a1, a1, -1
1257 ; RV32-NEXT: sw a1, 0(a0)
1258 ; RV32-NEXT: sw a2, 4(a0)
1261 ; RV64-LABEL: PR41129:
1262 ; RV64: # %bb.0: # %entry
1263 ; RV64-NEXT: ld a1, 0(a0)
1264 ; RV64-NEXT: beqz a1, .LBB37_2
1265 ; RV64-NEXT: # %bb.1: # %false
1266 ; RV64-NEXT: andi a1, a1, 7
1267 ; RV64-NEXT: sd a1, 0(a0)
1269 ; RV64-NEXT: .LBB37_2: # %true
1270 ; RV64-NEXT: addi a1, a1, -1
1271 ; RV64-NEXT: sd a1, 0(a0)
1274 %key = load i64, ptr %p64, align 8
1275 %cond17 = icmp eq i64 %key, 0
1276 br i1 %cond17, label %true, label %false
1279 %andval = and i64 %key, 7
1280 store i64 %andval, ptr %p64
1284 %svalue = add i64 %key, -1
1285 store i64 %svalue, ptr %p64
1292 define i16 @overflow_not_used(i16 %a, i16 %b, ptr %res) {
1293 ; RV32-LABEL: overflow_not_used:
1295 ; RV32-NEXT: lui a3, 16
1296 ; RV32-NEXT: addi a3, a3, -1
1297 ; RV32-NEXT: and a4, a1, a3
1298 ; RV32-NEXT: add a0, a1, a0
1299 ; RV32-NEXT: and a3, a0, a3
1300 ; RV32-NEXT: bltu a3, a4, .LBB38_2
1301 ; RV32-NEXT: # %bb.1:
1302 ; RV32-NEXT: li a1, 42
1303 ; RV32-NEXT: .LBB38_2:
1304 ; RV32-NEXT: sh a0, 0(a2)
1305 ; RV32-NEXT: mv a0, a1
1308 ; RV64-LABEL: overflow_not_used:
1310 ; RV64-NEXT: lui a3, 16
1311 ; RV64-NEXT: addiw a3, a3, -1
1312 ; RV64-NEXT: and a4, a1, a3
1313 ; RV64-NEXT: add a0, a1, a0
1314 ; RV64-NEXT: and a3, a0, a3
1315 ; RV64-NEXT: bltu a3, a4, .LBB38_2
1316 ; RV64-NEXT: # %bb.1:
1317 ; RV64-NEXT: li a1, 42
1318 ; RV64-NEXT: .LBB38_2:
1319 ; RV64-NEXT: sh a0, 0(a2)
1320 ; RV64-NEXT: mv a0, a1
1322 %add = add i16 %b, %a
1323 %cmp = icmp ult i16 %add, %b
1324 %Q = select i1 %cmp, i16 %b, i16 42
1325 store i16 %add, ptr %res