xref: /llvm-project/llvm/test/CodeGen/ARM/divmod-eabi.ll (revision 774d157a5d1a2a03d7d6c724b987588b5c3bb279)
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-DEFAULT: mls [[rem:r[0-9]+]], r0,
46; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[rem]], r0
47; WINDOWS-O0: mov [[div:r[0-9]+]], r0
48; WINDOWS-O0: mls [[rem:r[0-9]+]], [[div]],
49  %rem8 = srem i32 %conv1, %conv
50; EABI: __aeabi_idivmod
51; DARWIN: __modsi3
52; WINDOWS: __rt_sdiv
53; WINDOWS: mls [[rem1:r[0-9]+]], r0,
54  %add = add nsw i32 %rem, %div
55  %add13 = add nsw i32 %add, %rem8
56  %conv14 = trunc i32 %add13 to i16
57; EABI: add r0{{.*}}r1
58; EABI: sxth r0, r0
59; DARWIN-DEFAULT: add [[res:r[0-9]+]], [[sum]], r0
60; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
61; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
62; DARWIN: sxth r0, [[res]]
63; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
64; WINDOWS: add [[rem1]], [[sum]]
65; WINDOWS: sxth [[res:r[0-9]+]], [[rem1]]
66  ret i16 %conv14
67}
68
69define i32 @f32(i32 %a, i32 %b) {
70; EABI-LABEL: f32:
71; DARWIN-LABEL: f32:
72; WINDOWS-LABEL: f32:
73entry:
74  %div = sdiv i32 %a, %b
75  %rem = srem i32 %a, %b
76; EABI: __aeabi_idivmod
77; EABI: mov [[div:r[0-9]+]], r0
78; EABI: mov [[rem:r[0-9]+]], r1
79; DARWIN: ___divsi3
80; DARWIN: mov [[div:r[0-9]+]], r0
81; DARWIN: __modsi3
82; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
83; DARWIN-O0: mov [[rem:r[0-9]+]], r0
84; WINDOWS: __rt_sdiv
85; WINDOWS: mov [[div:r[0-9]+]], r0
86; WINDOWS: __rt_sdiv
87; WINDOWS: mls [[rem:r[0-9]+]], r0,
88; WINDOWS-DEFAULT: add [[div]], [[rem]]
89  %rem1 = srem i32 %b, %a
90; EABI: __aeabi_idivmod
91; DARWIN: __modsi3
92; WINDOWS: __rt_sdiv
93; WINDOWS: mls [[rem1:r[0-9]+]], r0,
94  %add = add nsw i32 %rem, %div
95  %add2 = add nsw i32 %add, %rem1
96; EABI: add r0{{.*}}r1
97; DARWIN-DEFAULT: add r0, [[sum]], r0
98; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
99; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
100; WINDOWS-DEFAULT: add [[rem1]], [[div]]
101; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
102; WINDOWS-O0: add [[rem1]], [[sum]]
103  ret i32 %add2
104}
105
106define i32 @uf(i32 %a, i32 %b) {
107; EABI-LABEL: uf:
108; DARWIN-LABEL: uf:
109; WINDOWS-LABEL: uf:
110entry:
111  %div = udiv i32 %a, %b
112  %rem = urem i32 %a, %b
113; EABI: __aeabi_uidivmod
114; DARWIN: ___udivsi3
115; DARWIN: mov [[div:r[0-9]+]], r0
116; DARWIN: __umodsi3
117; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
118; DARWIN-O0: mov [[rem:r[0-9]+]], r0
119; WINDOWS: __rt_udiv
120; WINDOWS: mov [[div:r[0-9]+]], r0
121; WINDOWS: __rt_udiv
122; WINDOWS: mls [[rem:r[0-9]+]], r0,
123; WINDOWS-DEFAULT: add [[div]], [[rem]]
124  %rem1 = urem i32 %b, %a
125; EABI: __aeabi_uidivmod
126; DARWIN: __umodsi3
127; WINDOWS: __rt_udiv
128; WINDOWS: mls [[rem1:r[0-9]+]], r0,
129  %add = add nuw i32 %rem, %div
130  %add2 = add nuw i32 %add, %rem1
131; EABI: add r0{{.*}}r1
132; DARWIN-DEFAULT: add r0, [[sum]], r0
133; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
134; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
135; WINDOWS-DEFAULT: add [[rem1]], [[div]]
136; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
137; WINDOWS-O0: add [[rem1]], [[sum]]
138  ret i32 %add2
139}
140
141define i64 @longf(i64 %a, i64 %b) {
142; EABI-LABEL: longf:
143; DARWIN-LABEL: longf:
144; WINDOWS-LABEL: longf:
145entry:
146  %div = sdiv i64 %a, %b
147  %rem = srem i64 %a, %b
148; EABI: __aeabi_ldivmod
149; EABI-NEXT: adds r0
150; EABI-NEXT: adc r1
151; EABI-NOT: __aeabi_ldivmod
152; DARWIN: ___divdi3
153; DARWIN: mov [[div1:r[0-9]+]], r0
154; DARWIN: mov [[div2:r[0-9]+]], r1
155; DARWIN: __moddi3
156; WINDOWS: __rt_sdiv64
157; WINDOWS: mov [[div1:r[0-9]+]], r0
158; WINDOWS: mov [[div2:r[0-9]+]], r1
159; WINDOWS: __moddi3
160  %add = add nsw i64 %rem, %div
161; DARWIN: adds r0{{.*}}[[div1]]
162; DARWIN: adc r1{{.*}}[[div2]]
163; WINDOWS: adds.w r0, r0, [[div1]]
164; WINDOWS: adc.w r1, r1, [[div2]]
165  ret i64 %add
166}
167
168define i16 @shortf(i16 %a, i16 %b) {
169; EABI-LABEL: shortf:
170; DARWIN-LABEL: shortf:
171; WINDOWS-LABEL: shortf:
172entry:
173  %div = sdiv i16 %a, %b
174  %rem = srem i16 %a, %b
175; EABI: __aeabi_idivmod
176; DARWIN: ___divsi3
177; DARWIN: mov [[div1:r[0-9]+]], r0
178; DARWIN: __modsi3
179; WINDOWS: __rt_sdiv
180; WINDOWS: mov [[div:r[0-9]+]], r0
181; WINDOWS: __rt_sdiv
182; WINDOWS: mls [[rem:r[0-9]+]], r0,
183  %add = add nsw i16 %rem, %div
184; EABI: add r0, r1
185; DARWIN: add r0{{.*}}[[div1]]
186; WINDOWS: add [[rem]], [[div]]
187  ret i16 %add
188}
189
190define i32 @g1(i32 %a, i32 %b) {
191; EABI-LABEL: g1:
192; DARWIN-LABEL: g1:
193; WINDOWS-LABEL: g1:
194entry:
195  %div = sdiv i32 %a, %b
196  %rem = srem i32 %a, %b
197; EABI: __aeabi_idivmod
198; DARWIN: ___divsi3
199; DARWIN: mov [[sum:r[0-9]+]], r0
200; DARWIN: __modsi3
201; WINDOWS: __rt_sdiv
202; WINDOWS: mov [[div:r[0-9]+]], r0
203; WINDOWS: __rt_sdiv
204; WINDOWS: mls [[rem:r[0-9]+]], r0,
205  %add = add nsw i32 %rem, %div
206; EABI:	add	r0{{.*}}r1
207; DARWIN: add r0{{.*}}[[sum]]
208; WINDOWS: add [[rem]], [[div]]
209  ret i32 %add
210}
211
212; On both Darwin and Gnu, this is just a call to __modsi3
213define i32 @g2(i32 %a, i32 %b) {
214; EABI-LABEL: g2:
215; DARWIN-LABEL: g2:
216; WINDOWS-LABEL: g2:
217entry:
218  %rem = srem i32 %a, %b
219; EABI: __aeabi_idivmod
220; DARWIN: __modsi3
221; WINDOWS: __rt_sdiv
222  ret i32 %rem
223; EABI:	mov	r0, r1
224; WINDOWS: mls r0, r0,
225}
226
227define i32 @g3(i32 %a, i32 %b) {
228; EABI-LABEL: g3:
229; DARWIN-LABEL: g3:
230; WINDOWS-LABEL: g3:
231entry:
232  %rem = srem i32 %a, %b
233; EABI: __aeabi_idivmod
234; EABI: mov [[mod:r[0-9]+]], r1
235; DARWIN: __modsi3
236; DARWIN: mov [[sum:r[0-9]+]], r0
237; WINDOWS: __rt_sdiv
238; WINDOWS: mls [[rem:r[0-9]+]], r0,
239  %rem1 = srem i32 %b, %rem
240; EABI: __aeabi_idivmod
241; DARWIN: __modsi3
242; WINDOWS: __rt_sdiv
243; WINDOWS: mls [[rem1:r[0-9]+]], r0,
244  %add = add nsw i32 %rem1, %rem
245; EABI: add r0, r1, [[mod]]
246; DARWIN: add r0{{.*}}[[sum]]
247; WINDOWS: add [[rem1]], [[rem]]
248  ret i32 %add
249}
250
251define i32 @g4(i32 %a, i32 %b) {
252; EABI-LABEL: g4:
253; DARWIN-LABEL: g4:
254; WINDOWS-LABEL: g4:
255entry:
256  %div = sdiv i32 %a, %b
257; EABI: __aeabi_idiv{{$}}
258; EABI: mov [[div:r[0-9]+]], r0
259; DARWIN: ___divsi3
260; DARWIN: mov [[sum:r[0-9]+]], r0
261; WINDOWS: __rt_sdiv
262; WINDOWS: mov [[div:r[0-9]+]], r0
263  %rem = srem i32 %b, %div
264; EABI: __aeabi_idivmod
265; DARWIN: __modsi3
266; WINDOWS: __rt_sdiv
267; WINDOWS: mls [[rem:r[0-9]+]], r0,
268  %add = add nsw i32 %rem, %div
269; EABI: add r0, r1, [[div]]
270; DARWIN: add r0{{.*}}[[sum]]
271; WINDOWS: add [[rem]], [[div]]
272  ret i32 %add
273}
274