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) {
27 ; DARWIN-O0-LABEL: f16:
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
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
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
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]]
61 define i32 @f32(i32 %a, i32 %b) {
64 ; DARWIN-O0-LABEL: f32:
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
76 ; WINDOWS: mov [[div:r[0-9]+]], r0
78 ; WINDOWS-DEFAULT: add [[div]], r1
79 %rem1 = srem i32 %b, %a
80 ; EABI: __aeabi_idivmod
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
93 define i32 @uf(i32 %a, i32 %b) {
96 ; DARWIN-O0-LABEL: uf:
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
106 ; WINDOWS: mov [[div:r[0-9]+]], r0
108 ; WINDOWS-DEFAULT: add [[div]], r1
109 %rem1 = urem i32 %b, %a
110 ; EABI: __aeabi_uidivmod
112 ; DARWIN-O0: __umodsi3
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
123 define i64 @longf(i64 %a, i64 %b) {
125 ; DARWIN-LABEL: longf:
126 ; DARWIN-O0-LABEL: longf:
127 ; WINDOWS-LABEL: longf:
129 %div = sdiv i64 %a, %b
130 %rem = srem i64 %a, %b
131 ; EABI: __aeabi_ldivmod
134 ; EABI-NOT: __aeabi_ldivmod
136 ; DARWIN: mov [[div1:r[0-9]+]], r0
137 ; DARWIN: mov [[div2:r[0-9]+]], r1
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
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:
156 %div = sdiv i16 %a, %b
157 %rem = srem i16 %a, %b
158 ; EABI: __aeabi_idivmod
159 ; DARWIN: ___divmodsi4
160 ; DARWIN-O0: __divmodsi4
162 ; WINDOWS: mov [[div:r[0-9]+]], r0
164 %add = add nsw i16 %rem, %div
166 ; WINDOWS: adds r0, r1, [[div]]
170 define i32 @g1(i32 %a, i32 %b) {
173 ; DARWIN-O0-LABEL: g1:
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
183 ; WINDOWS: mov [[div:r[0-9]+]], r0
185 %add = add nsw i32 %rem, %div
186 ; EABI: add r0{{.*}}r1
187 ; WINDOWS: adds r0, r1, [[div]]
191 ; On both Darwin and Gnu, this is just a call to __modsi3
192 define i32 @g2(i32 %a, i32 %b) {
195 ; DARWIN-O0-LABEL: g2:
198 %rem = srem i32 %a, %b
199 ; EABI: __aeabi_idivmod
201 ; DARWIN-O0: __modsi3
205 ; WINDOWS: mov r0, r1
208 define i32 @g3(i32 %a, i32 %b) {
211 ; DARWIN-O0-LABEL: g3:
214 %rem = srem i32 %a, %b
215 ; EABI: __aeabi_idivmod
216 ; EABI: mov [[mod:r[0-9]+]], r1
218 ; DARWIN: mov [[sum:r[0-9]+]], r0
219 ; DARWIN-O0: __modsi3
221 ; WINDOWS: mov [[rem:r[0-9]+]], r1
222 %rem1 = srem i32 %b, %rem
223 ; EABI: __aeabi_idivmod
225 ; DARWIN-O0: __modsi3
227 %add = add nsw i32 %rem1, %rem
228 ; EABI: add r0, r1, [[mod]]
229 ; DARWIN: add r0{{.*}}[[sum]]
230 ; WINDOWS: adds r0, r1, [[rem]]
234 define i32 @g4(i32 %a, i32 %b) {
237 ; DARWIN-O0-LABEL: g4:
240 %div = sdiv i32 %a, %b
241 ; EABI: __aeabi_idiv{{$}}
242 ; EABI: mov [[div:r[0-9]+]], r0
244 ; DARWIN: mov [[sum:r[0-9]+]], r0
245 ; DARWIN-O0: __divsi3
247 ; WINDOWS: mov [[div:r[0-9]+]], r0
248 %rem = srem i32 %b, %div
249 ; EABI: __aeabi_idivmod
251 ; DARWIN-O0: __modsi3
253 %add = add nsw i32 %rem, %div
254 ; EABI: add r0, r1, [[div]]
255 ; DARWIN: add r0{{.*}}[[sum]]
256 ; WINDOWS: adds r0, r1, [[div]]