xref: /llvm-project/llvm/test/CodeGen/RISCV/div-pow2.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
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=RV32I
4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
5; RUN:   | FileCheck %s -check-prefixes=RV64I
6
7define i32 @sdiv32_pow2_2(i32 %a) {
8; RV32I-LABEL: sdiv32_pow2_2:
9; RV32I:       # %bb.0: # %entry
10; RV32I-NEXT:    srli a1, a0, 31
11; RV32I-NEXT:    add a0, a0, a1
12; RV32I-NEXT:    srai a0, a0, 1
13; RV32I-NEXT:    ret
14;
15; RV64I-LABEL: sdiv32_pow2_2:
16; RV64I:       # %bb.0: # %entry
17; RV64I-NEXT:    srliw a1, a0, 31
18; RV64I-NEXT:    add a0, a0, a1
19; RV64I-NEXT:    sraiw a0, a0, 1
20; RV64I-NEXT:    ret
21entry:
22  %div = sdiv i32 %a, 2
23  ret i32 %div
24}
25
26define i32 @sdiv32_pow2_negative_2(i32 %a) {
27; RV32I-LABEL: sdiv32_pow2_negative_2:
28; RV32I:       # %bb.0: # %entry
29; RV32I-NEXT:    srli a1, a0, 31
30; RV32I-NEXT:    add a0, a0, a1
31; RV32I-NEXT:    srai a0, a0, 1
32; RV32I-NEXT:    neg a0, a0
33; RV32I-NEXT:    ret
34;
35; RV64I-LABEL: sdiv32_pow2_negative_2:
36; RV64I:       # %bb.0: # %entry
37; RV64I-NEXT:    srliw a1, a0, 31
38; RV64I-NEXT:    add a0, a0, a1
39; RV64I-NEXT:    sraiw a0, a0, 1
40; RV64I-NEXT:    neg a0, a0
41; RV64I-NEXT:    ret
42entry:
43  %div = sdiv i32 %a, -2
44  ret i32 %div
45}
46
47define i32 @sdiv32_pow2_2048(i32 %a) {
48; RV32I-LABEL: sdiv32_pow2_2048:
49; RV32I:       # %bb.0: # %entry
50; RV32I-NEXT:    srai a1, a0, 31
51; RV32I-NEXT:    srli a1, a1, 21
52; RV32I-NEXT:    add a0, a0, a1
53; RV32I-NEXT:    srai a0, a0, 11
54; RV32I-NEXT:    ret
55;
56; RV64I-LABEL: sdiv32_pow2_2048:
57; RV64I:       # %bb.0: # %entry
58; RV64I-NEXT:    sraiw a1, a0, 31
59; RV64I-NEXT:    srliw a1, a1, 21
60; RV64I-NEXT:    add a0, a0, a1
61; RV64I-NEXT:    sraiw a0, a0, 11
62; RV64I-NEXT:    ret
63entry:
64  %div = sdiv i32 %a, 2048
65  ret i32 %div
66}
67
68define i32 @sdiv32_pow2_negative_2048(i32 %a) {
69; RV32I-LABEL: sdiv32_pow2_negative_2048:
70; RV32I:       # %bb.0: # %entry
71; RV32I-NEXT:    srai a1, a0, 31
72; RV32I-NEXT:    srli a1, a1, 21
73; RV32I-NEXT:    add a0, a0, a1
74; RV32I-NEXT:    srai a0, a0, 11
75; RV32I-NEXT:    neg a0, a0
76; RV32I-NEXT:    ret
77;
78; RV64I-LABEL: sdiv32_pow2_negative_2048:
79; RV64I:       # %bb.0: # %entry
80; RV64I-NEXT:    sraiw a1, a0, 31
81; RV64I-NEXT:    srliw a1, a1, 21
82; RV64I-NEXT:    add a0, a0, a1
83; RV64I-NEXT:    sraiw a0, a0, 11
84; RV64I-NEXT:    neg a0, a0
85; RV64I-NEXT:    ret
86entry:
87  %div = sdiv i32 %a, -2048
88  ret i32 %div
89}
90
91define i32 @sdiv32_pow2_4096(i32 %a) {
92; RV32I-LABEL: sdiv32_pow2_4096:
93; RV32I:       # %bb.0: # %entry
94; RV32I-NEXT:    srai a1, a0, 31
95; RV32I-NEXT:    srli a1, a1, 20
96; RV32I-NEXT:    add a0, a0, a1
97; RV32I-NEXT:    srai a0, a0, 12
98; RV32I-NEXT:    ret
99;
100; RV64I-LABEL: sdiv32_pow2_4096:
101; RV64I:       # %bb.0: # %entry
102; RV64I-NEXT:    sraiw a1, a0, 31
103; RV64I-NEXT:    srliw a1, a1, 20
104; RV64I-NEXT:    add a0, a0, a1
105; RV64I-NEXT:    sraiw a0, a0, 12
106; RV64I-NEXT:    ret
107entry:
108  %div = sdiv i32 %a, 4096
109  ret i32 %div
110}
111
112define i32 @sdiv32_pow2_negative_4096(i32 %a) {
113; RV32I-LABEL: sdiv32_pow2_negative_4096:
114; RV32I:       # %bb.0: # %entry
115; RV32I-NEXT:    srai a1, a0, 31
116; RV32I-NEXT:    srli a1, a1, 20
117; RV32I-NEXT:    add a0, a0, a1
118; RV32I-NEXT:    srai a0, a0, 12
119; RV32I-NEXT:    neg a0, a0
120; RV32I-NEXT:    ret
121;
122; RV64I-LABEL: sdiv32_pow2_negative_4096:
123; RV64I:       # %bb.0: # %entry
124; RV64I-NEXT:    sraiw a1, a0, 31
125; RV64I-NEXT:    srliw a1, a1, 20
126; RV64I-NEXT:    add a0, a0, a1
127; RV64I-NEXT:    sraiw a0, a0, 12
128; RV64I-NEXT:    neg a0, a0
129; RV64I-NEXT:    ret
130entry:
131  %div = sdiv i32 %a, -4096
132  ret i32 %div
133}
134
135define i32 @sdiv32_pow2_65536(i32 %a) {
136; RV32I-LABEL: sdiv32_pow2_65536:
137; RV32I:       # %bb.0: # %entry
138; RV32I-NEXT:    srai a1, a0, 31
139; RV32I-NEXT:    srli a1, a1, 16
140; RV32I-NEXT:    add a0, a0, a1
141; RV32I-NEXT:    srai a0, a0, 16
142; RV32I-NEXT:    ret
143;
144; RV64I-LABEL: sdiv32_pow2_65536:
145; RV64I:       # %bb.0: # %entry
146; RV64I-NEXT:    sraiw a1, a0, 31
147; RV64I-NEXT:    srliw a1, a1, 16
148; RV64I-NEXT:    add a0, a0, a1
149; RV64I-NEXT:    sraiw a0, a0, 16
150; RV64I-NEXT:    ret
151entry:
152  %div = sdiv i32 %a, 65536
153  ret i32 %div
154}
155
156define i32 @sdiv32_pow2_negative_65536(i32 %a) {
157; RV32I-LABEL: sdiv32_pow2_negative_65536:
158; RV32I:       # %bb.0: # %entry
159; RV32I-NEXT:    srai a1, a0, 31
160; RV32I-NEXT:    srli a1, a1, 16
161; RV32I-NEXT:    add a0, a0, a1
162; RV32I-NEXT:    srai a0, a0, 16
163; RV32I-NEXT:    neg a0, a0
164; RV32I-NEXT:    ret
165;
166; RV64I-LABEL: sdiv32_pow2_negative_65536:
167; RV64I:       # %bb.0: # %entry
168; RV64I-NEXT:    sraiw a1, a0, 31
169; RV64I-NEXT:    srliw a1, a1, 16
170; RV64I-NEXT:    add a0, a0, a1
171; RV64I-NEXT:    sraiw a0, a0, 16
172; RV64I-NEXT:    neg a0, a0
173; RV64I-NEXT:    ret
174entry:
175  %div = sdiv i32 %a, -65536
176  ret i32 %div
177}
178
179define i64 @sdiv64_pow2_2(i64 %a) {
180; RV32I-LABEL: sdiv64_pow2_2:
181; RV32I:       # %bb.0: # %entry
182; RV32I-NEXT:    srli a2, a1, 31
183; RV32I-NEXT:    add a2, a0, a2
184; RV32I-NEXT:    srli a3, a2, 1
185; RV32I-NEXT:    sltu a0, a2, a0
186; RV32I-NEXT:    add a1, a1, a0
187; RV32I-NEXT:    slli a0, a1, 31
188; RV32I-NEXT:    or a0, a3, a0
189; RV32I-NEXT:    srai a1, a1, 1
190; RV32I-NEXT:    ret
191;
192; RV64I-LABEL: sdiv64_pow2_2:
193; RV64I:       # %bb.0: # %entry
194; RV64I-NEXT:    srli a1, a0, 63
195; RV64I-NEXT:    add a0, a0, a1
196; RV64I-NEXT:    srai a0, a0, 1
197; RV64I-NEXT:    ret
198entry:
199  %div = sdiv i64 %a, 2
200  ret i64 %div
201}
202
203define i64 @sdiv64_pow2_negative_2(i64 %a) {
204; RV32I-LABEL: sdiv64_pow2_negative_2:
205; RV32I:       # %bb.0: # %entry
206; RV32I-NEXT:    srli a2, a1, 31
207; RV32I-NEXT:    add a2, a0, a2
208; RV32I-NEXT:    srli a3, a2, 1
209; RV32I-NEXT:    sltu a0, a2, a0
210; RV32I-NEXT:    add a0, a1, a0
211; RV32I-NEXT:    slli a1, a0, 31
212; RV32I-NEXT:    srai a2, a0, 1
213; RV32I-NEXT:    or a1, a3, a1
214; RV32I-NEXT:    neg a0, a1
215; RV32I-NEXT:    snez a1, a1
216; RV32I-NEXT:    neg a2, a2
217; RV32I-NEXT:    sub a1, a2, a1
218; RV32I-NEXT:    ret
219;
220; RV64I-LABEL: sdiv64_pow2_negative_2:
221; RV64I:       # %bb.0: # %entry
222; RV64I-NEXT:    srli a1, a0, 63
223; RV64I-NEXT:    add a0, a0, a1
224; RV64I-NEXT:    srai a0, a0, 1
225; RV64I-NEXT:    neg a0, a0
226; RV64I-NEXT:    ret
227entry:
228  %div = sdiv i64 %a, -2
229  ret i64 %div
230}
231
232define i64 @sdiv64_pow2_2048(i64 %a) {
233; RV32I-LABEL: sdiv64_pow2_2048:
234; RV32I:       # %bb.0: # %entry
235; RV32I-NEXT:    srai a2, a1, 31
236; RV32I-NEXT:    srli a2, a2, 21
237; RV32I-NEXT:    add a2, a0, a2
238; RV32I-NEXT:    srli a3, a2, 11
239; RV32I-NEXT:    sltu a0, a2, a0
240; RV32I-NEXT:    add a1, a1, a0
241; RV32I-NEXT:    slli a0, a1, 21
242; RV32I-NEXT:    or a0, a3, a0
243; RV32I-NEXT:    srai a1, a1, 11
244; RV32I-NEXT:    ret
245;
246; RV64I-LABEL: sdiv64_pow2_2048:
247; RV64I:       # %bb.0: # %entry
248; RV64I-NEXT:    srai a1, a0, 63
249; RV64I-NEXT:    srli a1, a1, 53
250; RV64I-NEXT:    add a0, a0, a1
251; RV64I-NEXT:    srai a0, a0, 11
252; RV64I-NEXT:    ret
253entry:
254  %div = sdiv i64 %a, 2048
255  ret i64 %div
256}
257
258define i64 @sdiv64_pow2_negative_2048(i64 %a) {
259; RV32I-LABEL: sdiv64_pow2_negative_2048:
260; RV32I:       # %bb.0: # %entry
261; RV32I-NEXT:    srai a2, a1, 31
262; RV32I-NEXT:    srli a2, a2, 21
263; RV32I-NEXT:    add a2, a0, a2
264; RV32I-NEXT:    srli a3, a2, 11
265; RV32I-NEXT:    sltu a0, a2, a0
266; RV32I-NEXT:    add a0, a1, a0
267; RV32I-NEXT:    slli a1, a0, 21
268; RV32I-NEXT:    srai a2, a0, 11
269; RV32I-NEXT:    or a1, a3, a1
270; RV32I-NEXT:    neg a0, a1
271; RV32I-NEXT:    snez a1, a1
272; RV32I-NEXT:    neg a2, a2
273; RV32I-NEXT:    sub a1, a2, a1
274; RV32I-NEXT:    ret
275;
276; RV64I-LABEL: sdiv64_pow2_negative_2048:
277; RV64I:       # %bb.0: # %entry
278; RV64I-NEXT:    srai a1, a0, 63
279; RV64I-NEXT:    srli a1, a1, 53
280; RV64I-NEXT:    add a0, a0, a1
281; RV64I-NEXT:    srai a0, a0, 11
282; RV64I-NEXT:    neg a0, a0
283; RV64I-NEXT:    ret
284entry:
285  %div = sdiv i64 %a, -2048
286  ret i64 %div
287}
288
289define i64 @sdiv64_pow2_4096(i64 %a) {
290; RV32I-LABEL: sdiv64_pow2_4096:
291; RV32I:       # %bb.0: # %entry
292; RV32I-NEXT:    srai a2, a1, 31
293; RV32I-NEXT:    srli a2, a2, 20
294; RV32I-NEXT:    add a2, a0, a2
295; RV32I-NEXT:    srli a3, a2, 12
296; RV32I-NEXT:    sltu a0, a2, a0
297; RV32I-NEXT:    add a1, a1, a0
298; RV32I-NEXT:    slli a0, a1, 20
299; RV32I-NEXT:    or a0, a3, a0
300; RV32I-NEXT:    srai a1, a1, 12
301; RV32I-NEXT:    ret
302;
303; RV64I-LABEL: sdiv64_pow2_4096:
304; RV64I:       # %bb.0: # %entry
305; RV64I-NEXT:    srai a1, a0, 63
306; RV64I-NEXT:    srli a1, a1, 52
307; RV64I-NEXT:    add a0, a0, a1
308; RV64I-NEXT:    srai a0, a0, 12
309; RV64I-NEXT:    ret
310entry:
311  %div = sdiv i64 %a, 4096
312  ret i64 %div
313}
314
315define i64 @sdiv64_pow2_negative_4096(i64 %a) {
316; RV32I-LABEL: sdiv64_pow2_negative_4096:
317; RV32I:       # %bb.0: # %entry
318; RV32I-NEXT:    srai a2, a1, 31
319; RV32I-NEXT:    srli a2, a2, 20
320; RV32I-NEXT:    add a2, a0, a2
321; RV32I-NEXT:    srli a3, a2, 12
322; RV32I-NEXT:    sltu a0, a2, a0
323; RV32I-NEXT:    add a0, a1, a0
324; RV32I-NEXT:    slli a1, a0, 20
325; RV32I-NEXT:    srai a2, a0, 12
326; RV32I-NEXT:    or a1, a3, a1
327; RV32I-NEXT:    neg a0, a1
328; RV32I-NEXT:    snez a1, a1
329; RV32I-NEXT:    neg a2, a2
330; RV32I-NEXT:    sub a1, a2, a1
331; RV32I-NEXT:    ret
332;
333; RV64I-LABEL: sdiv64_pow2_negative_4096:
334; RV64I:       # %bb.0: # %entry
335; RV64I-NEXT:    srai a1, a0, 63
336; RV64I-NEXT:    srli a1, a1, 52
337; RV64I-NEXT:    add a0, a0, a1
338; RV64I-NEXT:    srai a0, a0, 12
339; RV64I-NEXT:    neg a0, a0
340; RV64I-NEXT:    ret
341entry:
342  %div = sdiv i64 %a, -4096
343  ret i64 %div
344}
345
346define i64 @sdiv64_pow2_65536(i64 %a) {
347; RV32I-LABEL: sdiv64_pow2_65536:
348; RV32I:       # %bb.0: # %entry
349; RV32I-NEXT:    srai a2, a1, 31
350; RV32I-NEXT:    srli a2, a2, 16
351; RV32I-NEXT:    add a2, a0, a2
352; RV32I-NEXT:    srli a3, a2, 16
353; RV32I-NEXT:    sltu a0, a2, a0
354; RV32I-NEXT:    add a1, a1, a0
355; RV32I-NEXT:    slli a0, a1, 16
356; RV32I-NEXT:    or a0, a3, a0
357; RV32I-NEXT:    srai a1, a1, 16
358; RV32I-NEXT:    ret
359;
360; RV64I-LABEL: sdiv64_pow2_65536:
361; RV64I:       # %bb.0: # %entry
362; RV64I-NEXT:    srai a1, a0, 63
363; RV64I-NEXT:    srli a1, a1, 48
364; RV64I-NEXT:    add a0, a0, a1
365; RV64I-NEXT:    srai a0, a0, 16
366; RV64I-NEXT:    ret
367entry:
368  %div = sdiv i64 %a, 65536
369  ret i64 %div
370}
371
372define i64 @sdiv64_pow2_negative_65536(i64 %a) {
373; RV32I-LABEL: sdiv64_pow2_negative_65536:
374; RV32I:       # %bb.0: # %entry
375; RV32I-NEXT:    srai a2, a1, 31
376; RV32I-NEXT:    srli a2, a2, 16
377; RV32I-NEXT:    add a2, a0, a2
378; RV32I-NEXT:    srli a3, a2, 16
379; RV32I-NEXT:    sltu a0, a2, a0
380; RV32I-NEXT:    add a0, a1, a0
381; RV32I-NEXT:    slli a1, a0, 16
382; RV32I-NEXT:    srai a2, a0, 16
383; RV32I-NEXT:    or a1, a3, a1
384; RV32I-NEXT:    neg a0, a1
385; RV32I-NEXT:    snez a1, a1
386; RV32I-NEXT:    neg a2, a2
387; RV32I-NEXT:    sub a1, a2, a1
388; RV32I-NEXT:    ret
389;
390; RV64I-LABEL: sdiv64_pow2_negative_65536:
391; RV64I:       # %bb.0: # %entry
392; RV64I-NEXT:    srai a1, a0, 63
393; RV64I-NEXT:    srli a1, a1, 48
394; RV64I-NEXT:    add a0, a0, a1
395; RV64I-NEXT:    srai a0, a0, 16
396; RV64I-NEXT:    neg a0, a0
397; RV64I-NEXT:    ret
398entry:
399  %div = sdiv i64 %a, -65536
400  ret i64 %div
401}
402
403define i64 @sdiv64_pow2_8589934592(i64 %a) {
404; RV32I-LABEL: sdiv64_pow2_8589934592:
405; RV32I:       # %bb.0: # %entry
406; RV32I-NEXT:    srli a2, a1, 31
407; RV32I-NEXT:    add a2, a1, a2
408; RV32I-NEXT:    srai a1, a1, 31
409; RV32I-NEXT:    add a1, a0, a1
410; RV32I-NEXT:    sltu a0, a1, a0
411; RV32I-NEXT:    add a1, a2, a0
412; RV32I-NEXT:    srai a0, a1, 1
413; RV32I-NEXT:    srai a1, a1, 31
414; RV32I-NEXT:    ret
415;
416; RV64I-LABEL: sdiv64_pow2_8589934592:
417; RV64I:       # %bb.0: # %entry
418; RV64I-NEXT:    srai a1, a0, 63
419; RV64I-NEXT:    srli a1, a1, 31
420; RV64I-NEXT:    add a0, a0, a1
421; RV64I-NEXT:    srai a0, a0, 33
422; RV64I-NEXT:    ret
423entry:
424  %div = sdiv i64 %a, 8589934592 ; 2^33
425  ret i64 %div
426}
427
428define i64 @sdiv64_pow2_negative_8589934592(i64 %a) {
429; RV32I-LABEL: sdiv64_pow2_negative_8589934592:
430; RV32I:       # %bb.0: # %entry
431; RV32I-NEXT:    srli a2, a1, 31
432; RV32I-NEXT:    add a2, a1, a2
433; RV32I-NEXT:    srai a1, a1, 31
434; RV32I-NEXT:    add a1, a0, a1
435; RV32I-NEXT:    sltu a0, a1, a0
436; RV32I-NEXT:    add a0, a2, a0
437; RV32I-NEXT:    srai a1, a0, 31
438; RV32I-NEXT:    srai a0, a0, 1
439; RV32I-NEXT:    snez a2, a0
440; RV32I-NEXT:    neg a1, a1
441; RV32I-NEXT:    sub a1, a1, a2
442; RV32I-NEXT:    neg a0, a0
443; RV32I-NEXT:    ret
444;
445; RV64I-LABEL: sdiv64_pow2_negative_8589934592:
446; RV64I:       # %bb.0: # %entry
447; RV64I-NEXT:    srai a1, a0, 63
448; RV64I-NEXT:    srli a1, a1, 31
449; RV64I-NEXT:    add a0, a0, a1
450; RV64I-NEXT:    srai a0, a0, 33
451; RV64I-NEXT:    neg a0, a0
452; RV64I-NEXT:    ret
453entry:
454  %div = sdiv i64 %a, -8589934592 ; -2^33
455  ret i64 %div
456}
457