[ARM] Split large truncating MVE stores
[llvm-complete.git] / test / CodeGen / RISCV / div.ll
blobe3504b92786458b8bc90f7aa05e1d5b00f4b263b
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck -check-prefix=RV32I %s
4 ; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck -check-prefix=RV32IM %s
6 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck -check-prefix=RV64I %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \
9 ; RUN:   | FileCheck -check-prefix=RV64IM %s
11 define i32 @udiv(i32 %a, i32 %b) nounwind {
12 ; RV32I-LABEL: udiv:
13 ; RV32I:       # %bb.0:
14 ; RV32I-NEXT:    addi sp, sp, -16
15 ; RV32I-NEXT:    sw ra, 12(sp)
16 ; RV32I-NEXT:    call __udivsi3
17 ; RV32I-NEXT:    lw ra, 12(sp)
18 ; RV32I-NEXT:    addi sp, sp, 16
19 ; RV32I-NEXT:    ret
21 ; RV32IM-LABEL: udiv:
22 ; RV32IM:       # %bb.0:
23 ; RV32IM-NEXT:    divu a0, a0, a1
24 ; RV32IM-NEXT:    ret
26 ; RV64I-LABEL: udiv:
27 ; RV64I:       # %bb.0:
28 ; RV64I-NEXT:    addi sp, sp, -16
29 ; RV64I-NEXT:    sd ra, 8(sp)
30 ; RV64I-NEXT:    slli a0, a0, 32
31 ; RV64I-NEXT:    srli a0, a0, 32
32 ; RV64I-NEXT:    slli a1, a1, 32
33 ; RV64I-NEXT:    srli a1, a1, 32
34 ; RV64I-NEXT:    call __udivdi3
35 ; RV64I-NEXT:    ld ra, 8(sp)
36 ; RV64I-NEXT:    addi sp, sp, 16
37 ; RV64I-NEXT:    ret
39 ; RV64IM-LABEL: udiv:
40 ; RV64IM:       # %bb.0:
41 ; RV64IM-NEXT:    divuw a0, a0, a1
42 ; RV64IM-NEXT:    ret
43   %1 = udiv i32 %a, %b
44   ret i32 %1
47 define i32 @udiv_constant(i32 %a) nounwind {
48 ; RV32I-LABEL: udiv_constant:
49 ; RV32I:       # %bb.0:
50 ; RV32I-NEXT:    addi sp, sp, -16
51 ; RV32I-NEXT:    sw ra, 12(sp)
52 ; RV32I-NEXT:    addi a1, zero, 5
53 ; RV32I-NEXT:    call __udivsi3
54 ; RV32I-NEXT:    lw ra, 12(sp)
55 ; RV32I-NEXT:    addi sp, sp, 16
56 ; RV32I-NEXT:    ret
58 ; RV32IM-LABEL: udiv_constant:
59 ; RV32IM:       # %bb.0:
60 ; RV32IM-NEXT:    lui a1, 838861
61 ; RV32IM-NEXT:    addi a1, a1, -819
62 ; RV32IM-NEXT:    mulhu a0, a0, a1
63 ; RV32IM-NEXT:    srli a0, a0, 2
64 ; RV32IM-NEXT:    ret
66 ; RV64I-LABEL: udiv_constant:
67 ; RV64I:       # %bb.0:
68 ; RV64I-NEXT:    addi sp, sp, -16
69 ; RV64I-NEXT:    sd ra, 8(sp)
70 ; RV64I-NEXT:    slli a0, a0, 32
71 ; RV64I-NEXT:    srli a0, a0, 32
72 ; RV64I-NEXT:    addi a1, zero, 5
73 ; RV64I-NEXT:    call __udivdi3
74 ; RV64I-NEXT:    ld ra, 8(sp)
75 ; RV64I-NEXT:    addi sp, sp, 16
76 ; RV64I-NEXT:    ret
78 ; RV64IM-LABEL: udiv_constant:
79 ; RV64IM:       # %bb.0:
80 ; RV64IM-NEXT:    slli a0, a0, 32
81 ; RV64IM-NEXT:    srli a0, a0, 32
82 ; RV64IM-NEXT:    lui a1, 1035469
83 ; RV64IM-NEXT:    addiw a1, a1, -819
84 ; RV64IM-NEXT:    slli a1, a1, 12
85 ; RV64IM-NEXT:    addi a1, a1, -819
86 ; RV64IM-NEXT:    slli a1, a1, 12
87 ; RV64IM-NEXT:    addi a1, a1, -819
88 ; RV64IM-NEXT:    slli a1, a1, 12
89 ; RV64IM-NEXT:    addi a1, a1, -819
90 ; RV64IM-NEXT:    mulhu a0, a0, a1
91 ; RV64IM-NEXT:    srli a0, a0, 2
92 ; RV64IM-NEXT:    ret
93   %1 = udiv i32 %a, 5
94   ret i32 %1
97 define i32 @udiv_pow2(i32 %a) nounwind {
98 ; RV32I-LABEL: udiv_pow2:
99 ; RV32I:       # %bb.0:
100 ; RV32I-NEXT:    srli a0, a0, 3
101 ; RV32I-NEXT:    ret
103 ; RV32IM-LABEL: udiv_pow2:
104 ; RV32IM:       # %bb.0:
105 ; RV32IM-NEXT:    srli a0, a0, 3
106 ; RV32IM-NEXT:    ret
108 ; RV64I-LABEL: udiv_pow2:
109 ; RV64I:       # %bb.0:
110 ; RV64I-NEXT:    srliw a0, a0, 3
111 ; RV64I-NEXT:    ret
113 ; RV64IM-LABEL: udiv_pow2:
114 ; RV64IM:       # %bb.0:
115 ; RV64IM-NEXT:    srliw a0, a0, 3
116 ; RV64IM-NEXT:    ret
117   %1 = udiv i32 %a, 8
118   ret i32 %1
121 define i64 @udiv64(i64 %a, i64 %b) nounwind {
122 ; RV32I-LABEL: udiv64:
123 ; RV32I:       # %bb.0:
124 ; RV32I-NEXT:    addi sp, sp, -16
125 ; RV32I-NEXT:    sw ra, 12(sp)
126 ; RV32I-NEXT:    call __udivdi3
127 ; RV32I-NEXT:    lw ra, 12(sp)
128 ; RV32I-NEXT:    addi sp, sp, 16
129 ; RV32I-NEXT:    ret
131 ; RV32IM-LABEL: udiv64:
132 ; RV32IM:       # %bb.0:
133 ; RV32IM-NEXT:    addi sp, sp, -16
134 ; RV32IM-NEXT:    sw ra, 12(sp)
135 ; RV32IM-NEXT:    call __udivdi3
136 ; RV32IM-NEXT:    lw ra, 12(sp)
137 ; RV32IM-NEXT:    addi sp, sp, 16
138 ; RV32IM-NEXT:    ret
140 ; RV64I-LABEL: udiv64:
141 ; RV64I:       # %bb.0:
142 ; RV64I-NEXT:    addi sp, sp, -16
143 ; RV64I-NEXT:    sd ra, 8(sp)
144 ; RV64I-NEXT:    call __udivdi3
145 ; RV64I-NEXT:    ld ra, 8(sp)
146 ; RV64I-NEXT:    addi sp, sp, 16
147 ; RV64I-NEXT:    ret
149 ; RV64IM-LABEL: udiv64:
150 ; RV64IM:       # %bb.0:
151 ; RV64IM-NEXT:    divu a0, a0, a1
152 ; RV64IM-NEXT:    ret
153   %1 = udiv i64 %a, %b
154   ret i64 %1
157 define i64 @udiv64_constant(i64 %a) nounwind {
158 ; RV32I-LABEL: udiv64_constant:
159 ; RV32I:       # %bb.0:
160 ; RV32I-NEXT:    addi sp, sp, -16
161 ; RV32I-NEXT:    sw ra, 12(sp)
162 ; RV32I-NEXT:    addi a2, zero, 5
163 ; RV32I-NEXT:    mv a3, zero
164 ; RV32I-NEXT:    call __udivdi3
165 ; RV32I-NEXT:    lw ra, 12(sp)
166 ; RV32I-NEXT:    addi sp, sp, 16
167 ; RV32I-NEXT:    ret
169 ; RV32IM-LABEL: udiv64_constant:
170 ; RV32IM:       # %bb.0:
171 ; RV32IM-NEXT:    addi sp, sp, -16
172 ; RV32IM-NEXT:    sw ra, 12(sp)
173 ; RV32IM-NEXT:    addi a2, zero, 5
174 ; RV32IM-NEXT:    mv a3, zero
175 ; RV32IM-NEXT:    call __udivdi3
176 ; RV32IM-NEXT:    lw ra, 12(sp)
177 ; RV32IM-NEXT:    addi sp, sp, 16
178 ; RV32IM-NEXT:    ret
180 ; RV64I-LABEL: udiv64_constant:
181 ; RV64I:       # %bb.0:
182 ; RV64I-NEXT:    addi sp, sp, -16
183 ; RV64I-NEXT:    sd ra, 8(sp)
184 ; RV64I-NEXT:    addi a1, zero, 5
185 ; RV64I-NEXT:    call __udivdi3
186 ; RV64I-NEXT:    ld ra, 8(sp)
187 ; RV64I-NEXT:    addi sp, sp, 16
188 ; RV64I-NEXT:    ret
190 ; RV64IM-LABEL: udiv64_constant:
191 ; RV64IM:       # %bb.0:
192 ; RV64IM-NEXT:    lui a1, 1035469
193 ; RV64IM-NEXT:    addiw a1, a1, -819
194 ; RV64IM-NEXT:    slli a1, a1, 12
195 ; RV64IM-NEXT:    addi a1, a1, -819
196 ; RV64IM-NEXT:    slli a1, a1, 12
197 ; RV64IM-NEXT:    addi a1, a1, -819
198 ; RV64IM-NEXT:    slli a1, a1, 12
199 ; RV64IM-NEXT:    addi a1, a1, -819
200 ; RV64IM-NEXT:    mulhu a0, a0, a1
201 ; RV64IM-NEXT:    srli a0, a0, 2
202 ; RV64IM-NEXT:    ret
203   %1 = udiv i64 %a, 5
204   ret i64 %1
207 define i32 @sdiv(i32 %a, i32 %b) nounwind {
208 ; RV32I-LABEL: sdiv:
209 ; RV32I:       # %bb.0:
210 ; RV32I-NEXT:    addi sp, sp, -16
211 ; RV32I-NEXT:    sw ra, 12(sp)
212 ; RV32I-NEXT:    call __divsi3
213 ; RV32I-NEXT:    lw ra, 12(sp)
214 ; RV32I-NEXT:    addi sp, sp, 16
215 ; RV32I-NEXT:    ret
217 ; RV32IM-LABEL: sdiv:
218 ; RV32IM:       # %bb.0:
219 ; RV32IM-NEXT:    div a0, a0, a1
220 ; RV32IM-NEXT:    ret
222 ; RV64I-LABEL: sdiv:
223 ; RV64I:       # %bb.0:
224 ; RV64I-NEXT:    addi sp, sp, -16
225 ; RV64I-NEXT:    sd ra, 8(sp)
226 ; RV64I-NEXT:    sext.w a0, a0
227 ; RV64I-NEXT:    sext.w a1, a1
228 ; RV64I-NEXT:    call __divdi3
229 ; RV64I-NEXT:    ld ra, 8(sp)
230 ; RV64I-NEXT:    addi sp, sp, 16
231 ; RV64I-NEXT:    ret
233 ; RV64IM-LABEL: sdiv:
234 ; RV64IM:       # %bb.0:
235 ; RV64IM-NEXT:    divw a0, a0, a1
236 ; RV64IM-NEXT:    ret
237   %1 = sdiv i32 %a, %b
238   ret i32 %1
241 define i32 @sdiv_constant(i32 %a) nounwind {
242 ; RV32I-LABEL: sdiv_constant:
243 ; RV32I:       # %bb.0:
244 ; RV32I-NEXT:    addi sp, sp, -16
245 ; RV32I-NEXT:    sw ra, 12(sp)
246 ; RV32I-NEXT:    addi a1, zero, 5
247 ; RV32I-NEXT:    call __divsi3
248 ; RV32I-NEXT:    lw ra, 12(sp)
249 ; RV32I-NEXT:    addi sp, sp, 16
250 ; RV32I-NEXT:    ret
252 ; RV32IM-LABEL: sdiv_constant:
253 ; RV32IM:       # %bb.0:
254 ; RV32IM-NEXT:    lui a1, 419430
255 ; RV32IM-NEXT:    addi a1, a1, 1639
256 ; RV32IM-NEXT:    mulh a0, a0, a1
257 ; RV32IM-NEXT:    srli a1, a0, 31
258 ; RV32IM-NEXT:    srai a0, a0, 1
259 ; RV32IM-NEXT:    add a0, a0, a1
260 ; RV32IM-NEXT:    ret
262 ; RV64I-LABEL: sdiv_constant:
263 ; RV64I:       # %bb.0:
264 ; RV64I-NEXT:    addi sp, sp, -16
265 ; RV64I-NEXT:    sd ra, 8(sp)
266 ; RV64I-NEXT:    sext.w a0, a0
267 ; RV64I-NEXT:    addi a1, zero, 5
268 ; RV64I-NEXT:    call __divdi3
269 ; RV64I-NEXT:    ld ra, 8(sp)
270 ; RV64I-NEXT:    addi sp, sp, 16
271 ; RV64I-NEXT:    ret
273 ; RV64IM-LABEL: sdiv_constant:
274 ; RV64IM:       # %bb.0:
275 ; RV64IM-NEXT:    sext.w a0, a0
276 ; RV64IM-NEXT:    lui a1, 13107
277 ; RV64IM-NEXT:    addiw a1, a1, 819
278 ; RV64IM-NEXT:    slli a1, a1, 12
279 ; RV64IM-NEXT:    addi a1, a1, 819
280 ; RV64IM-NEXT:    slli a1, a1, 12
281 ; RV64IM-NEXT:    addi a1, a1, 819
282 ; RV64IM-NEXT:    slli a1, a1, 13
283 ; RV64IM-NEXT:    addi a1, a1, 1639
284 ; RV64IM-NEXT:    mulh a0, a0, a1
285 ; RV64IM-NEXT:    srli a1, a0, 63
286 ; RV64IM-NEXT:    srai a0, a0, 1
287 ; RV64IM-NEXT:    add a0, a0, a1
288 ; RV64IM-NEXT:    ret
289   %1 = sdiv i32 %a, 5
290   ret i32 %1
293 define i32 @sdiv_pow2(i32 %a) nounwind {
294 ; RV32I-LABEL: sdiv_pow2:
295 ; RV32I:       # %bb.0:
296 ; RV32I-NEXT:    srai a1, a0, 31
297 ; RV32I-NEXT:    srli a1, a1, 29
298 ; RV32I-NEXT:    add a0, a0, a1
299 ; RV32I-NEXT:    srai a0, a0, 3
300 ; RV32I-NEXT:    ret
302 ; RV32IM-LABEL: sdiv_pow2:
303 ; RV32IM:       # %bb.0:
304 ; RV32IM-NEXT:    srai a1, a0, 31
305 ; RV32IM-NEXT:    srli a1, a1, 29
306 ; RV32IM-NEXT:    add a0, a0, a1
307 ; RV32IM-NEXT:    srai a0, a0, 3
308 ; RV32IM-NEXT:    ret
310 ; RV64I-LABEL: sdiv_pow2:
311 ; RV64I:       # %bb.0:
312 ; RV64I-NEXT:    sext.w a1, a0
313 ; RV64I-NEXT:    srli a1, a1, 60
314 ; RV64I-NEXT:    andi a1, a1, 7
315 ; RV64I-NEXT:    add a0, a0, a1
316 ; RV64I-NEXT:    sraiw a0, a0, 3
317 ; RV64I-NEXT:    ret
319 ; RV64IM-LABEL: sdiv_pow2:
320 ; RV64IM:       # %bb.0:
321 ; RV64IM-NEXT:    sext.w a1, a0
322 ; RV64IM-NEXT:    srli a1, a1, 60
323 ; RV64IM-NEXT:    andi a1, a1, 7
324 ; RV64IM-NEXT:    add a0, a0, a1
325 ; RV64IM-NEXT:    sraiw a0, a0, 3
326 ; RV64IM-NEXT:    ret
327   %1 = sdiv i32 %a, 8
328   ret i32 %1
331 define i64 @sdiv64(i64 %a, i64 %b) nounwind {
332 ; RV32I-LABEL: sdiv64:
333 ; RV32I:       # %bb.0:
334 ; RV32I-NEXT:    addi sp, sp, -16
335 ; RV32I-NEXT:    sw ra, 12(sp)
336 ; RV32I-NEXT:    call __divdi3
337 ; RV32I-NEXT:    lw ra, 12(sp)
338 ; RV32I-NEXT:    addi sp, sp, 16
339 ; RV32I-NEXT:    ret
341 ; RV32IM-LABEL: sdiv64:
342 ; RV32IM:       # %bb.0:
343 ; RV32IM-NEXT:    addi sp, sp, -16
344 ; RV32IM-NEXT:    sw ra, 12(sp)
345 ; RV32IM-NEXT:    call __divdi3
346 ; RV32IM-NEXT:    lw ra, 12(sp)
347 ; RV32IM-NEXT:    addi sp, sp, 16
348 ; RV32IM-NEXT:    ret
350 ; RV64I-LABEL: sdiv64:
351 ; RV64I:       # %bb.0:
352 ; RV64I-NEXT:    addi sp, sp, -16
353 ; RV64I-NEXT:    sd ra, 8(sp)
354 ; RV64I-NEXT:    call __divdi3
355 ; RV64I-NEXT:    ld ra, 8(sp)
356 ; RV64I-NEXT:    addi sp, sp, 16
357 ; RV64I-NEXT:    ret
359 ; RV64IM-LABEL: sdiv64:
360 ; RV64IM:       # %bb.0:
361 ; RV64IM-NEXT:    div a0, a0, a1
362 ; RV64IM-NEXT:    ret
363   %1 = sdiv i64 %a, %b
364   ret i64 %1
367 define i64 @sdiv64_constant(i64 %a) nounwind {
368 ; RV32I-LABEL: sdiv64_constant:
369 ; RV32I:       # %bb.0:
370 ; RV32I-NEXT:    addi sp, sp, -16
371 ; RV32I-NEXT:    sw ra, 12(sp)
372 ; RV32I-NEXT:    addi a2, zero, 5
373 ; RV32I-NEXT:    mv a3, zero
374 ; RV32I-NEXT:    call __divdi3
375 ; RV32I-NEXT:    lw ra, 12(sp)
376 ; RV32I-NEXT:    addi sp, sp, 16
377 ; RV32I-NEXT:    ret
379 ; RV32IM-LABEL: sdiv64_constant:
380 ; RV32IM:       # %bb.0:
381 ; RV32IM-NEXT:    addi sp, sp, -16
382 ; RV32IM-NEXT:    sw ra, 12(sp)
383 ; RV32IM-NEXT:    addi a2, zero, 5
384 ; RV32IM-NEXT:    mv a3, zero
385 ; RV32IM-NEXT:    call __divdi3
386 ; RV32IM-NEXT:    lw ra, 12(sp)
387 ; RV32IM-NEXT:    addi sp, sp, 16
388 ; RV32IM-NEXT:    ret
390 ; RV64I-LABEL: sdiv64_constant:
391 ; RV64I:       # %bb.0:
392 ; RV64I-NEXT:    addi sp, sp, -16
393 ; RV64I-NEXT:    sd ra, 8(sp)
394 ; RV64I-NEXT:    addi a1, zero, 5
395 ; RV64I-NEXT:    call __divdi3
396 ; RV64I-NEXT:    ld ra, 8(sp)
397 ; RV64I-NEXT:    addi sp, sp, 16
398 ; RV64I-NEXT:    ret
400 ; RV64IM-LABEL: sdiv64_constant:
401 ; RV64IM:       # %bb.0:
402 ; RV64IM-NEXT:    lui a1, 13107
403 ; RV64IM-NEXT:    addiw a1, a1, 819
404 ; RV64IM-NEXT:    slli a1, a1, 12
405 ; RV64IM-NEXT:    addi a1, a1, 819
406 ; RV64IM-NEXT:    slli a1, a1, 12
407 ; RV64IM-NEXT:    addi a1, a1, 819
408 ; RV64IM-NEXT:    slli a1, a1, 13
409 ; RV64IM-NEXT:    addi a1, a1, 1639
410 ; RV64IM-NEXT:    mulh a0, a0, a1
411 ; RV64IM-NEXT:    srli a1, a0, 63
412 ; RV64IM-NEXT:    srai a0, a0, 1
413 ; RV64IM-NEXT:    add a0, a0, a1
414 ; RV64IM-NEXT:    ret
415   %1 = sdiv i64 %a, 5
416   ret i64 %1
419 ; Although this sdiv has two sexti32 operands, it shouldn't compile to divw on
420 ; RV64M as that wouldn't produce the correct result for e.g. INT_MIN/-1.
422 define i64 @sdiv64_sext_operands(i32 %a, i32 %b) nounwind {
423 ; RV32I-LABEL: sdiv64_sext_operands:
424 ; RV32I:       # %bb.0:
425 ; RV32I-NEXT:    addi sp, sp, -16
426 ; RV32I-NEXT:    sw ra, 12(sp)
427 ; RV32I-NEXT:    mv a2, a1
428 ; RV32I-NEXT:    srai a1, a0, 31
429 ; RV32I-NEXT:    srai a3, a2, 31
430 ; RV32I-NEXT:    call __divdi3
431 ; RV32I-NEXT:    lw ra, 12(sp)
432 ; RV32I-NEXT:    addi sp, sp, 16
433 ; RV32I-NEXT:    ret
435 ; RV32IM-LABEL: sdiv64_sext_operands:
436 ; RV32IM:       # %bb.0:
437 ; RV32IM-NEXT:    addi sp, sp, -16
438 ; RV32IM-NEXT:    sw ra, 12(sp)
439 ; RV32IM-NEXT:    mv a2, a1
440 ; RV32IM-NEXT:    srai a1, a0, 31
441 ; RV32IM-NEXT:    srai a3, a2, 31
442 ; RV32IM-NEXT:    call __divdi3
443 ; RV32IM-NEXT:    lw ra, 12(sp)
444 ; RV32IM-NEXT:    addi sp, sp, 16
445 ; RV32IM-NEXT:    ret
447 ; RV64I-LABEL: sdiv64_sext_operands:
448 ; RV64I:       # %bb.0:
449 ; RV64I-NEXT:    addi sp, sp, -16
450 ; RV64I-NEXT:    sd ra, 8(sp)
451 ; RV64I-NEXT:    sext.w a0, a0
452 ; RV64I-NEXT:    sext.w a1, a1
453 ; RV64I-NEXT:    call __divdi3
454 ; RV64I-NEXT:    ld ra, 8(sp)
455 ; RV64I-NEXT:    addi sp, sp, 16
456 ; RV64I-NEXT:    ret
458 ; RV64IM-LABEL: sdiv64_sext_operands:
459 ; RV64IM:       # %bb.0:
460 ; RV64IM-NEXT:    sext.w a0, a0
461 ; RV64IM-NEXT:    sext.w a1, a1
462 ; RV64IM-NEXT:    div a0, a0, a1
463 ; RV64IM-NEXT:    ret
464   %1 = sext i32 %a to i64
465   %2 = sext i32 %b to i64
466   %3 = sdiv i64 %1, %2
467   ret i64 %3