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
10
11define 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
20;
21; RV32IM-LABEL: udiv:
22; RV32IM:       # %bb.0:
23; RV32IM-NEXT:    divu a0, a0, a1
24; RV32IM-NEXT:    ret
25;
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
38;
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
45}
46
47define 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
57;
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
65;
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
77;
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
95}
96
97define 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
102;
103; RV32IM-LABEL: udiv_pow2:
104; RV32IM:       # %bb.0:
105; RV32IM-NEXT:    srli a0, a0, 3
106; RV32IM-NEXT:    ret
107;
108; RV64I-LABEL: udiv_pow2:
109; RV64I:       # %bb.0:
110; RV64I-NEXT:    srliw a0, a0, 3
111; RV64I-NEXT:    ret
112;
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
119}
120
121define 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
130;
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
139;
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
148;
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
155}
156
157define 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
168;
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
179;
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
189;
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
205}
206
207define 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
216;
217; RV32IM-LABEL: sdiv:
218; RV32IM:       # %bb.0:
219; RV32IM-NEXT:    div a0, a0, a1
220; RV32IM-NEXT:    ret
221;
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
232;
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
239}
240
241define 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
251;
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
261;
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
272;
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
291}
292
293define 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
301;
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
309;
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
318;
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
329}
330
331define 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
340;
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
349;
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
358;
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
365}
366
367define 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
378;
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
389;
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
399;
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
417}
418
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.
421
422define 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
434;
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
446;
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
457;
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
468}
469