[ARM] Cortex-M4 schedule additions
[llvm-complete.git] / test / CodeGen / ARM / divmod-eabi.ll
blob77ffc46e6a6914b5ab0dd2fb22d9ba24639c22f3
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
20 ; RUN: llc -mtriple armv7-apple-darwin %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=DARWIN-O0
21 ; RUN: llc -mtriple thumbv7-windows %s -o - | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-DEFAULT
22 ; RUN: llc -mtriple thumbv7-windows %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-O0
24 define signext i16 @f16(i16 signext %a, i16 signext %b) {
25 ; EABI-LABEL: f16:
26 ; DARWIN-LABEL: f16:
27 ; DARWIN-O0-LABEL: f16:
28 ; WINDOWS-LABEL: f16:
29 entry:
30   %conv = sext i16 %a to i32
31   %conv1 = sext i16 %b to i32
32   %div = sdiv i32 %conv, %conv1
33   %rem = srem i32 %conv, %conv1
34 ; EABI: __aeabi_idivmod
35 ; EABI: mov [[div:r[0-9]+]], r0
36 ; EABI: mov [[rem:r[0-9]+]], r1
37 ; DARWIN: __divmodsi4
38 ; DARWIN-O0: __divsi3
39 ; DARWIN-O0: __modsi3
40 ; WINDOWS: __rt_sdiv
41 ; WINDOWS: __rt_sdiv
42 ; WINDOWS-DEFAULT: add [[sum:r[0-9]+]], r1
43 ; WINDOWS-O0: mov [[rem:r[0-9]+]], r1
44   %rem8 = srem i32 %conv1, %conv
45 ; EABI: __aeabi_idivmod
46 ; DARWIN: __modsi3
47 ; DARWIN-O0: __modsi3
48 ; WINDOWS: __rt_sdiv
49   %add = add nsw i32 %rem, %div
50   %add13 = add nsw i32 %add, %rem8
51   %conv14 = trunc i32 %add13 to i16
52 ; EABI: add r0{{.*}}r1
53 ; EABI: sxth r0, r0
54 ; WINDOWS-DEFAULT: adds [[sum1:r[0-9]+]], [[sum]], r1
55 ; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]],
56 ; WINDOWS-O0: add [[sum1:r[0-9]+]], r1
57 ; WINDOWS: sxth [[res:r[0-9]+]], [[sum1]]
58   ret i16 %conv14
61 define i32 @f32(i32 %a, i32 %b) {
62 ; EABI-LABEL: f32:
63 ; DARWIN-LABEL: f32:
64 ; DARWIN-O0-LABEL: f32:
65 ; WINDOWS-LABEL: f32:
66 entry:
67   %div = sdiv i32 %a, %b
68   %rem = srem i32 %a, %b
69 ; EABI: __aeabi_idivmod
70 ; EABI: mov [[div:r[0-9]+]], r0
71 ; EABI: mov [[rem:r[0-9]+]], r1
72 ; DARWIN: ___divmodsi4
73 ; DARWIN-O0: __divsi3
74 ; DARWIN-O0: __modsi3
75 ; WINDOWS: __rt_sdiv
76 ; WINDOWS: mov [[div:r[0-9]+]], r0
77 ; WINDOWS: __rt_sdiv
78 ; WINDOWS-DEFAULT: add [[div]], r1
79   %rem1 = srem i32 %b, %a
80 ; EABI: __aeabi_idivmod
81 ; DARWIN: __modsi3
82 ; DARWIN-O0: __modsi3
83 ; WINDOWS: __rt_sdiv
84   %add = add nsw i32 %rem, %div
85   %add2 = add nsw i32 %add, %rem1
86 ; EABI: add r0{{.*}}r1
87 ; WINDOWS-DEFAULT: adds r0, [[div]], r1
88 ; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
89 ; WINDOWS-O0: add [[sum]], r1
90   ret i32 %add2
93 define i32 @uf(i32 %a, i32 %b) {
94 ; EABI-LABEL: uf:
95 ; DARWIN-LABEL: uf:
96 ; DARWIN-O0-LABEL: uf:
97 ; WINDOWS-LABEL: uf:
98 entry:
99   %div = udiv i32 %a, %b
100   %rem = urem i32 %a, %b
101 ; EABI: __aeabi_uidivmod
102 ; DARWIN: __udivmodsi4
103 ; DARWIN-O0: __udivsi3
104 ; DARWIN-O0: __umodsi3
105 ; WINDOWS: __rt_udiv
106 ; WINDOWS: mov [[div:r[0-9]+]], r0
107 ; WINDOWS: __rt_udiv
108 ; WINDOWS-DEFAULT: add [[div]], r1
109   %rem1 = urem i32 %b, %a
110 ; EABI: __aeabi_uidivmod
111 ; DARWIN: __umodsi3
112 ; DARWIN-O0: __umodsi3
113 ; WINDOWS: __rt_udiv
114   %add = add nuw i32 %rem, %div
115   %add2 = add nuw i32 %add, %rem1
116 ; EABI: add r0{{.*}}r1
117 ; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[div]], r1
118 ; WINDOWS-O0: adds [[sum:r[0-9]+]],
119 ; WINDOWS-O0: add [[sum]], r1
120   ret i32 %add2
123 define i64 @longf(i64 %a, i64 %b) {
124 ; EABI-LABEL: longf:
125 ; DARWIN-LABEL: longf:
126 ; DARWIN-O0-LABEL: longf:
127 ; WINDOWS-LABEL: longf:
128 entry:
129   %div = sdiv i64 %a, %b
130   %rem = srem i64 %a, %b
131 ; EABI: __aeabi_ldivmod
132 ; EABI-NEXT: adds r0
133 ; EABI-NEXT: adc r1
134 ; EABI-NOT: __aeabi_ldivmod
135 ; DARWIN: ___divdi3
136 ; DARWIN: mov [[div1:r[0-9]+]], r0
137 ; DARWIN: mov [[div2:r[0-9]+]], r1
138 ; DARWIN: __moddi3
139 ; DARWIN-O0: __divdi3
140 ; DARWIN-O0: __moddi3
141 ; WINDOWS: __rt_sdiv64
142   %add = add nsw i64 %rem, %div
143 ; DARWIN: adds r0{{.*}}[[div1]]
144 ; DARWIN: adc r1{{.*}}[[div2]]
145 ; WINDOWS: adds r0, r0, r2
146 ; WINDOWS: adcs r1, r3
147   ret i64 %add
150 define i16 @shortf(i16 %a, i16 %b) {
151 ; EABI-LABEL: shortf:
152 ; DARWIN-LABEL: shortf:
153 ; DARWIN-O0-LABEL: shortf:
154 ; WINDOWS-LABEL: shortf:
155 entry:
156   %div = sdiv i16 %a, %b
157   %rem = srem i16 %a, %b
158 ; EABI: __aeabi_idivmod
159 ; DARWIN: ___divmodsi4
160 ; DARWIN-O0: __divmodsi4
161 ; WINDOWS: __rt_sdiv
162 ; WINDOWS: mov [[div:r[0-9]+]], r0
163 ; WINDOWS: __rt_sdiv
164   %add = add nsw i16 %rem, %div
165 ; EABI: add r0, r1
166 ; WINDOWS: adds r0, r1, [[div]]
167   ret i16 %add
170 define i32 @g1(i32 %a, i32 %b) {
171 ; EABI-LABEL: g1:
172 ; DARWIN-LABEL: g1:
173 ; DARWIN-O0-LABEL: g1:
174 ; WINDOWS-LABEL: g1:
175 entry:
176   %div = sdiv i32 %a, %b
177   %rem = srem i32 %a, %b
178 ; EABI: __aeabi_idivmod
179 ; DARWIN: ___divmodsi4
180 ; DARWIN-O0: __divsi3
181 ; DARWIN-O0: __modsi3
182 ; WINDOWS: __rt_sdiv
183 ; WINDOWS: mov [[div:r[0-9]+]], r0
184 ; WINDOWS: __rt_sdiv
185   %add = add nsw i32 %rem, %div
186 ; EABI: add     r0{{.*}}r1
187 ; WINDOWS: adds r0, r1, [[div]]
188   ret i32 %add
191 ; On both Darwin and Gnu, this is just a call to __modsi3
192 define i32 @g2(i32 %a, i32 %b) {
193 ; EABI-LABEL: g2:
194 ; DARWIN-LABEL: g2:
195 ; DARWIN-O0-LABEL: g2:
196 ; WINDOWS-LABEL: g2:
197 entry:
198   %rem = srem i32 %a, %b
199 ; EABI: __aeabi_idivmod
200 ; DARWIN: __modsi3
201 ; DARWIN-O0: __modsi3
202 ; WINDOWS: __rt_sdiv
203   ret i32 %rem
204 ; EABI: mov     r0, r1
205 ; WINDOWS: mov  r0, r1
208 define i32 @g3(i32 %a, i32 %b) {
209 ; EABI-LABEL: g3:
210 ; DARWIN-LABEL: g3:
211 ; DARWIN-O0-LABEL: g3:
212 ; WINDOWS-LABEL: g3:
213 entry:
214   %rem = srem i32 %a, %b
215 ; EABI: __aeabi_idivmod
216 ; EABI: mov [[mod:r[0-9]+]], r1
217 ; DARWIN: __modsi3
218 ; DARWIN: mov [[sum:r[0-9]+]], r0
219 ; DARWIN-O0: __modsi3
220 ; WINDOWS: __rt_sdiv
221 ; WINDOWS: mov [[rem:r[0-9]+]], r1
222   %rem1 = srem i32 %b, %rem
223 ; EABI: __aeabi_idivmod
224 ; DARWIN: __modsi3
225 ; DARWIN-O0: __modsi3
226 ; WINDOWS: __rt_sdiv
227   %add = add nsw i32 %rem1, %rem
228 ; EABI: add r0, r1, [[mod]]
229 ; DARWIN: add r0{{.*}}[[sum]]
230 ; WINDOWS: adds r0, r1, [[rem]]
231   ret i32 %add
234 define i32 @g4(i32 %a, i32 %b) {
235 ; EABI-LABEL: g4:
236 ; DARWIN-LABEL: g4:
237 ; DARWIN-O0-LABEL: g4:
238 ; WINDOWS-LABEL: g4:
239 entry:
240   %div = sdiv i32 %a, %b
241 ; EABI: __aeabi_idiv{{$}}
242 ; EABI: mov [[div:r[0-9]+]], r0
243 ; DARWIN: ___divsi3
244 ; DARWIN: mov [[sum:r[0-9]+]], r0
245 ; DARWIN-O0: __divsi3
246 ; WINDOWS: __rt_sdiv
247 ; WINDOWS: mov [[div:r[0-9]+]], r0
248   %rem = srem i32 %b, %div
249 ; EABI: __aeabi_idivmod
250 ; DARWIN: __modsi3
251 ; DARWIN-O0: __modsi3
252 ; WINDOWS: __rt_sdiv
253   %add = add nsw i32 %rem, %div
254 ; EABI: add r0, r1, [[div]]
255 ; DARWIN: add r0{{.*}}[[sum]]
256 ; WINDOWS: adds r0, r1, [[div]]
257   ret i32 %add