ARM: improve RTABI 4.2 conformance on Linux
[oota-llvm.git] / test / CodeGen / ARM / divmod-eabi.ll
1 ; RUN: llc -mtriple armv7-none-eabi %s -o - | FileCheck %s --check-prefix=EABI
2 ; RUN: llc -mtriple armv7-none-eabihf %s -o - | FileCheck %s --check-prefix=EABI
3 ; RUN: llc -mtriple armv7-linux-gnueabi %s -o - | FileCheck %s --check-prefix=GNU
4 ; RUN: llc -mtriple armv7-apple-darwin %s -o - | FileCheck %s --check-prefix=DARWIN
5 ; FIXME: long-term, we will use "-apple-macho" and won't need this exception:
6 ; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - | FileCheck %s --check-prefix=DARWIN
7
8 define signext i16 @f16(i16 signext %a, i16 signext %b) {
9 ; EABI-LABEL: f16:
10 ; GNU-LABEL: f16:
11 ; DARWIN-LABEL: f16:
12 entry:
13   %conv = sext i16 %a to i32
14   %conv1 = sext i16 %b to i32
15   %div = sdiv i32 %conv, %conv1
16   %rem = srem i32 %conv, %conv1
17 ; EABI: __aeabi_idivmod
18 ; EABI: mov [[div:r[0-9]+]], r0
19 ; EABI: mov [[rem:r[0-9]+]], r1
20 ; GNU: __aeabi_idivmod
21 ; DARWIN: ___divsi3
22 ; DARWIN: mov [[sum:r[0-9]+]], r0
23 ; DARWIN: __modsi3
24 ; DARWIN: add [[sum]]{{.*}}r0
25   %rem8 = srem i32 %conv1, %conv
26 ; EABI: __aeabi_idivmod
27 ; GNU: __modsi3
28 ; DARWIN: __modsi3
29   %add = add nsw i32 %rem, %div
30   %add13 = add nsw i32 %add, %rem8
31   %conv14 = trunc i32 %add13 to i16
32 ; EABI: add r0{{.*}}r1
33 ; EABI: sxth r0, r0
34 ; GNU: add r0{{.*}}
35 ; GNU: sxth r0, r0
36 ; DARWIN: add r0{{.*}}[[sum]]
37 ; DARWIN: sxth r0, r0
38   ret i16 %conv14
39 }
40
41 define i32 @f32(i32 %a, i32 %b) {
42 ; EABI-LABEL: f32:
43 ; GNU-LABEL: f32:
44 ; DARWIN-LABEL: f32:
45 entry:
46   %div = sdiv i32 %a, %b
47   %rem = srem i32 %a, %b
48 ; EABI: __aeabi_idivmod
49 ; EABI: mov [[div:r[0-9]+]], r0
50 ; EABI: mov [[rem:r[0-9]+]], r1
51 ; GNU: __aeabi_idivmod
52 ; DARWIN: ___divsi3
53 ; DARWIN: mov [[sum:r[0-9]+]], r0
54 ; DARWIN: __modsi3
55 ; DARWIN: add [[sum]]{{.*}}r0
56   %rem1 = srem i32 %b, %a
57 ; EABI: __aeabi_idivmod
58 ; GNU: __modsi3
59 ; DARWIN: __modsi3
60   %add = add nsw i32 %rem, %div
61   %add2 = add nsw i32 %add, %rem1
62 ; EABI: add r0{{.*}}r1
63 ; GNU: add r0{{.*}}
64 ; DARWIN: add r0{{.*}}[[sum]]
65   ret i32 %add2
66 }
67
68 define i32 @uf(i32 %a, i32 %b) {
69 ; EABI-LABEL: uf:
70 ; GNU-LABEL: uf:
71 ; DARWIN-LABEL: uf:
72 entry:
73   %div = udiv i32 %a, %b
74   %rem = urem i32 %a, %b
75 ; EABI: __aeabi_uidivmod
76 ; GNU: __aeabi_uidivmod
77 ; DARWIN: ___udivsi3
78 ; DARWIN: mov [[sum:r[0-9]+]], r0
79 ; DARWIN: __umodsi3
80 ; DARWIN: add [[sum]]{{.*}}r0
81   %rem1 = urem i32 %b, %a
82 ; EABI: __aeabi_uidivmod
83 ; GNU: __umodsi3
84 ; DARWIN: __umodsi3
85   %add = add nuw i32 %rem, %div
86   %add2 = add nuw i32 %add, %rem1
87 ; EABI: add r0{{.*}}r1
88 ; GNU: add r0{{.*}}
89 ; DARWIN: add r0{{.*}}[[sum]]
90   ret i32 %add2
91 }
92
93 ; FIXME: AEABI is not lowering long u/srem into u/ldivmod
94 define i64 @longf(i64 %a, i64 %b) {
95 ; EABI-LABEL: longf:
96 ; GNU-LABEL: longf:
97 ; DARWIN-LABEL: longf:
98 entry:
99   %div = sdiv i64 %a, %b
100   %rem = srem i64 %a, %b
101 ; EABI: __aeabi_ldivmod
102 ; GNU: __aeabi_ldivmod
103 ; GNU: mov [[div1:r[0-9]+]], r0
104 ; GNU: mov [[div2:r[0-9]+]], r1
105 ; DARWIN: ___divdi3
106 ; DARWIN: mov [[div1:r[0-9]+]], r0
107 ; DARWIN: mov [[div2:r[0-9]+]], r1
108 ; DARWIN: __moddi3
109   %add = add nsw i64 %rem, %div
110 ; GNU: adds r0{{.*}}[[div1]]
111 ; GNU: adc r1{{.*}}[[div2]]
112 ; DARWIN: adds r0{{.*}}[[div1]]
113 ; DARWIN: adc r1{{.*}}[[div2]]
114   ret i64 %add
115 }
116
117 define i32 @g1(i32 %a, i32 %b) {
118 ; EABI-LABEL: g1:
119 ; GNU-LABEL: g1:
120 ; DARWIN-LABEL: g1:
121 entry:
122   %div = sdiv i32 %a, %b
123   %rem = srem i32 %a, %b
124 ; EABI: __aeabi_idivmod
125 ; GNU: __aeabi_idivmod
126 ; DARWIN: ___divsi3
127 ; DARWIN: mov [[sum:r[0-9]+]], r0
128 ; DARWIN: __modsi3
129   %add = add nsw i32 %rem, %div
130 ; EABI: add r0{{.*}}r1
131 ; GNU: add r0{{.*}}r1
132 ; DARWIN: add r0{{.*}}[[sum]]
133   ret i32 %add
134 }
135
136 ; On both Darwin and Gnu, this is just a call to __modsi3
137 define i32 @g2(i32 %a, i32 %b) {
138 ; EABI-LABEL: g2:
139 ; GNU-LABEL: g2:
140 ; DARWIN-LABEL: g2:
141 entry:
142   %rem = srem i32 %a, %b
143 ; EABI: __aeabi_idivmod
144 ; GNU: __modsi3
145 ; DARWIN: __modsi3
146   ret i32 %rem
147 ; EABI: mov     r0, r1
148 }
149
150 define i32 @g3(i32 %a, i32 %b) {
151 ; EABI-LABEL: g3:
152 ; GNU-LABEL: g3:
153 ; DARWIN-LABEL: g3:
154 entry:
155   %rem = srem i32 %a, %b
156 ; EABI: __aeabi_idivmod
157 ; EABI: mov [[mod:r[0-9]+]], r1
158 ; GNU: __modsi3
159 ; GNU: mov [[sum:r[0-9]+]], r0
160 ; DARWIN: __modsi3
161 ; DARWIN: mov [[sum:r[0-9]+]], r0
162   %rem1 = srem i32 %b, %rem
163 ; EABI: __aeabi_idivmod
164 ; GNU: __modsi3
165 ; DARWIN: __modsi3
166   %add = add nsw i32 %rem1, %rem
167 ; EABI: add r0, r1, [[mod]]
168 ; GNU: add r0{{.*}}[[sum]]
169 ; DARWIN: add r0{{.*}}[[sum]]
170   ret i32 %add
171 }
172
173 define i32 @g4(i32 %a, i32 %b) {
174 ; EABI-LABEL: g4:
175 ; GNU-LABEL: g4:
176 ; DARWIN-LABEL: g4:
177 entry:
178   %div = sdiv i32 %a, %b
179 ; EABI: __aeabi_idivmod
180 ; EABI: mov [[div:r[0-9]+]], r0
181 ; GNU: __aeabi_idiv
182 ; GNU: mov [[sum:r[0-9]+]], r0
183 ; DARWIN: ___divsi3
184 ; DARWIN: mov [[sum:r[0-9]+]], r0
185   %rem = srem i32 %b, %div
186 ; EABI: __aeabi_idivmod
187 ; GNU: __modsi3
188 ; DARWIN: __modsi3
189   %add = add nsw i32 %rem, %div
190 ; EABI: add r0, r1, [[div]]
191 ; GNU: add r0{{.*}}[[sum]]
192 ; DARWIN: add r0{{.*}}[[sum]]
193   ret i32 %add
194 }