xref: /llvm-project/llvm/test/CodeGen/ARM/divmod-eabi.ll (revision 04864f45b2f24e1268640cbde9203a7f769b6a79)
1; We run the tests with both the default optimization level and O0, to make sure
2; we don't have any ABI differences between them. In principle, the ABI checks
3; should be the same for both optimization levels (there could be exceptions
4; from this when a div and a mod with the same operands are not coallesced into
5; the same divmod, but luckily this doesn't occur in practice even at O0).
6; Sometimes the checks that the correct registers are used after the libcalls
7; are different between optimization levels, so we have to separate them.
8; RUN: llc -mtriple armv7-none-eabi %s -o - | FileCheck %s --check-prefix=EABI
9; RUN: llc -mtriple armv7-none-eabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
10; RUN: llc -mtriple armv7-none-eabihf %s -o - | FileCheck %s --check-prefix=EABI
11; RUN: llc -mtriple armv7-none-eabihf %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
12; All "eabi" (Bare, GNU and Android) must lower SREM/UREM to __aeabi_{u,i}divmod
13; RUN: llc -mtriple armv7-linux-androideabi %s -o - | FileCheck %s --check-prefix=EABI
14; RUN: llc -mtriple armv7-linux-androideabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
15; RUN: llc -mtriple armv7-linux-gnueabi %s -o - | FileCheck %s --check-prefix=EABI
16; RUN: llc -mtriple armv7-linux-gnueabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
17; RUN: llc -mtriple armv7-linux-musleabi %s -o - | FileCheck %s --check-prefix=EABI
18; RUN: llc -mtriple armv7-linux-musleabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
19; RUN: llc -mtriple armv7-apple-darwin %s -o - | FileCheck %s --check-prefixes=DARWIN,DARWIN-DEFAULT
20; RUN: llc -mtriple armv7-apple-darwin %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=DARWIN,DARWIN-O0
21; FIXME: long-term, we will use "-apple-macho" and won't need this exception:
22; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - | FileCheck %s --check-prefixes=DARWIN,DARWIN-DEFAULT
23; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=DARWIN,DARWIN-O0
24; RUN: llc -mtriple thumbv7-windows %s -o - | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-DEFAULT
25; RUN: llc -mtriple thumbv7-windows %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-O0
26
27define signext i16 @f16(i16 signext %a, i16 signext %b) {
28; EABI-LABEL: f16:
29; DARWIN-LABEL: f16:
30; WINDOWS-LABEL: f16:
31entry:
32  %conv = sext i16 %a to i32
33  %conv1 = sext i16 %b to i32
34  %div = sdiv i32 %conv, %conv1
35  %rem = srem i32 %conv, %conv1
36; EABI: __aeabi_idivmod
37; EABI: mov [[div:r[0-9]+]], r0
38; EABI: mov [[rem:r[0-9]+]], r1
39; DARWIN: ___divsi3
40; DARWIN: mov [[div:r[0-9]+]], r0
41; DARWIN: __modsi3
42; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
43; DARWIN-O0: mov [[rem:r[0-9]+]], r0
44; WINDOWS: __rt_sdiv
45; WINDOWS: __rt_sdiv
46; WINDOWS-DEFAULT: add [[sum:r[0-9]+]], r1
47; WINDOWS-O0: mov [[rem:r[0-9]+]], r1
48  %rem8 = srem i32 %conv1, %conv
49; EABI: __aeabi_idivmod
50; DARWIN: __modsi3
51; WINDOWS: __rt_sdiv
52  %add = add nsw i32 %rem, %div
53  %add13 = add nsw i32 %add, %rem8
54  %conv14 = trunc i32 %add13 to i16
55; EABI: add r0{{.*}}r1
56; EABI: sxth r0, r0
57; DARWIN-DEFAULT: add [[res:r[0-9]+]], [[sum]], r0
58; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
59; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
60; DARWIN: sxth r0, [[res]]
61; WINDOWS-DEFAULT: adds [[sum1:r[0-9]+]], [[sum]], r1
62; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]],
63; WINDOWS-O0: add [[sum1:r[0-9]+]], r1
64; WINDOWS: sxth [[res:r[0-9]+]], [[sum1]]
65  ret i16 %conv14
66}
67
68define i32 @f32(i32 %a, i32 %b) {
69; EABI-LABEL: f32:
70; DARWIN-LABEL: f32:
71; WINDOWS-LABEL: f32:
72entry:
73  %div = sdiv i32 %a, %b
74  %rem = srem i32 %a, %b
75; EABI: __aeabi_idivmod
76; EABI: mov [[div:r[0-9]+]], r0
77; EABI: mov [[rem:r[0-9]+]], r1
78; DARWIN: ___divsi3
79; DARWIN: mov [[div:r[0-9]+]], r0
80; DARWIN: __modsi3
81; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
82; DARWIN-O0: mov [[rem:r[0-9]+]], r0
83; WINDOWS: __rt_sdiv
84; WINDOWS: mov [[div:r[0-9]+]], r0
85; WINDOWS: __rt_sdiv
86; WINDOWS-DEFAULT: add [[div]], r1
87  %rem1 = srem i32 %b, %a
88; EABI: __aeabi_idivmod
89; DARWIN: __modsi3
90; WINDOWS: __rt_sdiv
91  %add = add nsw i32 %rem, %div
92  %add2 = add nsw i32 %add, %rem1
93; EABI: add r0{{.*}}r1
94; DARWIN-DEFAULT: add r0, [[sum]], r0
95; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
96; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
97; WINDOWS-DEFAULT: adds r0, [[div]], r1
98; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
99; WINDOWS-O0: add [[sum]], r1
100  ret i32 %add2
101}
102
103define i32 @uf(i32 %a, i32 %b) {
104; EABI-LABEL: uf:
105; DARWIN-LABEL: uf:
106; WINDOWS-LABEL: uf:
107entry:
108  %div = udiv i32 %a, %b
109  %rem = urem i32 %a, %b
110; EABI: __aeabi_uidivmod
111; DARWIN: ___udivsi3
112; DARWIN: mov [[div:r[0-9]+]], r0
113; DARWIN: __umodsi3
114; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
115; DARWIN-O0: mov [[rem:r[0-9]+]], r0
116; WINDOWS: __rt_udiv
117; WINDOWS: mov [[div:r[0-9]+]], r0
118; WINDOWS: __rt_udiv
119; WINDOWS-DEFAULT: add [[div]], r1
120  %rem1 = urem i32 %b, %a
121; EABI: __aeabi_uidivmod
122; DARWIN: __umodsi3
123; WINDOWS: __rt_udiv
124  %add = add nuw i32 %rem, %div
125  %add2 = add nuw i32 %add, %rem1
126; EABI: add r0{{.*}}r1
127; DARWIN-DEFAULT: add r0, [[sum]], r0
128; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
129; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
130; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[div]], r1
131; WINDOWS-O0: adds [[sum:r[0-9]+]],
132; WINDOWS-O0: add [[sum]], r1
133  ret i32 %add2
134}
135
136define i64 @longf(i64 %a, i64 %b) {
137; EABI-LABEL: longf:
138; DARWIN-LABEL: longf:
139; WINDOWS-LABEL: longf:
140entry:
141  %div = sdiv i64 %a, %b
142  %rem = srem i64 %a, %b
143; EABI: __aeabi_ldivmod
144; EABI-NEXT: adds r0
145; EABI-NEXT: adc r1
146; EABI-NOT: __aeabi_ldivmod
147; DARWIN: ___divdi3
148; DARWIN: mov [[div1:r[0-9]+]], r0
149; DARWIN: mov [[div2:r[0-9]+]], r1
150; DARWIN: __moddi3
151; WINDOWS: __rt_sdiv64
152  %add = add nsw i64 %rem, %div
153; DARWIN: adds r0{{.*}}[[div1]]
154; DARWIN: adc r1{{.*}}[[div2]]
155; WINDOWS: adds r0, r0, r2
156; WINDOWS: adcs r1, r3
157  ret i64 %add
158}
159
160define i16 @shortf(i16 %a, i16 %b) {
161; EABI-LABEL: shortf:
162; DARWIN-LABEL: shortf:
163; WINDOWS-LABEL: shortf:
164entry:
165  %div = sdiv i16 %a, %b
166  %rem = srem i16 %a, %b
167; EABI: __aeabi_idivmod
168; DARWIN: ___divsi3
169; DARWIN: mov [[div1:r[0-9]+]], r0
170; DARWIN: __modsi3
171; WINDOWS: __rt_sdiv
172; WINDOWS: mov [[div:r[0-9]+]], r0
173; WINDOWS: __rt_sdiv
174  %add = add nsw i16 %rem, %div
175; EABI: add r0, r1
176; DARWIN: add r0{{.*}}[[div1]]
177; WINDOWS: adds r0, r1, [[div]]
178  ret i16 %add
179}
180
181define i32 @g1(i32 %a, i32 %b) {
182; EABI-LABEL: g1:
183; DARWIN-LABEL: g1:
184; WINDOWS-LABEL: g1:
185entry:
186  %div = sdiv i32 %a, %b
187  %rem = srem i32 %a, %b
188; EABI: __aeabi_idivmod
189; DARWIN: ___divsi3
190; DARWIN: mov [[sum:r[0-9]+]], r0
191; DARWIN: __modsi3
192; WINDOWS: __rt_sdiv
193; WINDOWS: mov [[div:r[0-9]+]], r0
194; WINDOWS: __rt_sdiv
195  %add = add nsw i32 %rem, %div
196; EABI:	add	r0{{.*}}r1
197; DARWIN: add r0{{.*}}[[sum]]
198; WINDOWS: adds r0, r1, [[div]]
199  ret i32 %add
200}
201
202; On both Darwin and Gnu, this is just a call to __modsi3
203define i32 @g2(i32 %a, i32 %b) {
204; EABI-LABEL: g2:
205; DARWIN-LABEL: g2:
206; WINDOWS-LABEL: g2:
207entry:
208  %rem = srem i32 %a, %b
209; EABI: __aeabi_idivmod
210; DARWIN: __modsi3
211; WINDOWS: __rt_sdiv
212  ret i32 %rem
213; EABI:	mov	r0, r1
214; WINDOWS: mov  r0, r1
215}
216
217define i32 @g3(i32 %a, i32 %b) {
218; EABI-LABEL: g3:
219; DARWIN-LABEL: g3:
220; WINDOWS-LABEL: g3:
221entry:
222  %rem = srem i32 %a, %b
223; EABI: __aeabi_idivmod
224; EABI: mov [[mod:r[0-9]+]], r1
225; DARWIN: __modsi3
226; DARWIN: mov [[sum:r[0-9]+]], r0
227; WINDOWS: __rt_sdiv
228; WINDOWS: mov [[rem:r[0-9]+]], r1
229  %rem1 = srem i32 %b, %rem
230; EABI: __aeabi_idivmod
231; DARWIN: __modsi3
232; WINDOWS: __rt_sdiv
233  %add = add nsw i32 %rem1, %rem
234; EABI: add r0, r1, [[mod]]
235; DARWIN: add r0{{.*}}[[sum]]
236; WINDOWS: adds r0, r1, [[rem]]
237  ret i32 %add
238}
239
240define i32 @g4(i32 %a, i32 %b) {
241; EABI-LABEL: g4:
242; DARWIN-LABEL: g4:
243; WINDOWS-LABEL: g4:
244entry:
245  %div = sdiv i32 %a, %b
246; EABI: __aeabi_idiv{{$}}
247; EABI: mov [[div:r[0-9]+]], r0
248; DARWIN: ___divsi3
249; DARWIN: mov [[sum:r[0-9]+]], r0
250; WINDOWS: __rt_sdiv
251; WINDOWS: mov [[div:r[0-9]+]], r0
252  %rem = srem i32 %b, %div
253; EABI: __aeabi_idivmod
254; DARWIN: __modsi3
255; WINDOWS: __rt_sdiv
256  %add = add nsw i32 %rem, %div
257; EABI: add r0, r1, [[div]]
258; DARWIN: add r0{{.*}}[[sum]]
259; WINDOWS: adds r0, r1, [[div]]
260  ret i32 %add
261}
262