[ARM] Fixup the creation of VPT blocks
[llvm-core.git] / test / CodeGen / AArch64 / srem-seteq.ll
blobe7557d0ea9f86d8dfb159c21e54b38743080f67b
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
4 ;------------------------------------------------------------------------------;
5 ; Odd divisors
6 ;------------------------------------------------------------------------------;
8 define i32 @test_srem_odd(i32 %X) nounwind {
9 ; CHECK-LABEL: test_srem_odd:
10 ; CHECK:       // %bb.0:
11 ; CHECK-NEXT:    mov w8, #52429
12 ; CHECK-NEXT:    mov w9, #39321
13 ; CHECK-NEXT:    movk w8, #52428, lsl #16
14 ; CHECK-NEXT:    movk w9, #6553, lsl #16
15 ; CHECK-NEXT:    madd w8, w0, w8, w9
16 ; CHECK-NEXT:    mov w9, #858993459
17 ; CHECK-NEXT:    cmp w8, w9
18 ; CHECK-NEXT:    cset w0, lo
19 ; CHECK-NEXT:    ret
20   %srem = srem i32 %X, 5
21   %cmp = icmp eq i32 %srem, 0
22   %ret = zext i1 %cmp to i32
23   ret i32 %ret
26 define i32 @test_srem_odd_25(i32 %X) nounwind {
27 ; CHECK-LABEL: test_srem_odd_25:
28 ; CHECK:       // %bb.0:
29 ; CHECK-NEXT:    mov w8, #23593
30 ; CHECK-NEXT:    mov w9, #47185
31 ; CHECK-NEXT:    movk w8, #49807, lsl #16
32 ; CHECK-NEXT:    movk w9, #1310, lsl #16
33 ; CHECK-NEXT:    madd w8, w0, w8, w9
34 ; CHECK-NEXT:    mov w9, #28835
35 ; CHECK-NEXT:    movk w9, #2621, lsl #16
36 ; CHECK-NEXT:    cmp w8, w9
37 ; CHECK-NEXT:    cset w0, lo
38 ; CHECK-NEXT:    ret
39   %srem = srem i32 %X, 25
40   %cmp = icmp eq i32 %srem, 0
41   %ret = zext i1 %cmp to i32
42   ret i32 %ret
45 ; This is like test_srem_odd, except the divisor has bit 30 set.
46 define i32 @test_srem_odd_bit30(i32 %X) nounwind {
47 ; CHECK-LABEL: test_srem_odd_bit30:
48 ; CHECK:       // %bb.0:
49 ; CHECK-NEXT:    mov w8, #43691
50 ; CHECK-NEXT:    movk w8, #27306, lsl #16
51 ; CHECK-NEXT:    orr w9, wzr, #0x1
52 ; CHECK-NEXT:    madd w8, w0, w8, w9
53 ; CHECK-NEXT:    cmp w8, #3 // =3
54 ; CHECK-NEXT:    cset w0, lo
55 ; CHECK-NEXT:    ret
56   %srem = srem i32 %X, 1073741827
57   %cmp = icmp eq i32 %srem, 0
58   %ret = zext i1 %cmp to i32
59   ret i32 %ret
62 ; This is like test_srem_odd, except the divisor has bit 31 set.
63 define i32 @test_srem_odd_bit31(i32 %X) nounwind {
64 ; CHECK-LABEL: test_srem_odd_bit31:
65 ; CHECK:       // %bb.0:
66 ; CHECK-NEXT:    mov w8, #21845
67 ; CHECK-NEXT:    movk w8, #54613, lsl #16
68 ; CHECK-NEXT:    orr w9, wzr, #0x1
69 ; CHECK-NEXT:    madd w8, w0, w8, w9
70 ; CHECK-NEXT:    cmp w8, #3 // =3
71 ; CHECK-NEXT:    cset w0, lo
72 ; CHECK-NEXT:    ret
73   %srem = srem i32 %X, 2147483651
74   %cmp = icmp eq i32 %srem, 0
75   %ret = zext i1 %cmp to i32
76   ret i32 %ret
79 ;------------------------------------------------------------------------------;
80 ; Even divisors
81 ;------------------------------------------------------------------------------;
83 define i16 @test_srem_even(i16 %X) nounwind {
84 ; CHECK-LABEL: test_srem_even:
85 ; CHECK:       // %bb.0:
86 ; CHECK-NEXT:    mov w9, #9363
87 ; CHECK-NEXT:    sxth w8, w0
88 ; CHECK-NEXT:    movk w9, #37449, lsl #16
89 ; CHECK-NEXT:    smull x9, w8, w9
90 ; CHECK-NEXT:    lsr x9, x9, #32
91 ; CHECK-NEXT:    add w8, w9, w8
92 ; CHECK-NEXT:    asr w9, w8, #3
93 ; CHECK-NEXT:    add w8, w9, w8, lsr #31
94 ; CHECK-NEXT:    mov w9, #14
95 ; CHECK-NEXT:    msub w8, w8, w9, w0
96 ; CHECK-NEXT:    tst w8, #0xffff
97 ; CHECK-NEXT:    cset w0, ne
98 ; CHECK-NEXT:    ret
99   %srem = srem i16 %X, 14
100   %cmp = icmp ne i16 %srem, 0
101   %ret = zext i1 %cmp to i16
102   ret i16 %ret
105 define i32 @test_srem_even_100(i32 %X) nounwind {
106 ; CHECK-LABEL: test_srem_even_100:
107 ; CHECK:       // %bb.0:
108 ; CHECK-NEXT:    mov w8, #23593
109 ; CHECK-NEXT:    mov w9, #47184
110 ; CHECK-NEXT:    movk w8, #49807, lsl #16
111 ; CHECK-NEXT:    movk w9, #1310, lsl #16
112 ; CHECK-NEXT:    madd w8, w0, w8, w9
113 ; CHECK-NEXT:    mov w9, #23593
114 ; CHECK-NEXT:    ror w8, w8, #2
115 ; CHECK-NEXT:    movk w9, #655, lsl #16
116 ; CHECK-NEXT:    cmp w8, w9
117 ; CHECK-NEXT:    cset w0, lo
118 ; CHECK-NEXT:    ret
119   %srem = srem i32 %X, 100
120   %cmp = icmp eq i32 %srem, 0
121   %ret = zext i1 %cmp to i32
122   ret i32 %ret
125 ; This is like test_srem_even, except the divisor has bit 30 set.
126 define i32 @test_srem_even_bit30(i32 %X) nounwind {
127 ; CHECK-LABEL: test_srem_even_bit30:
128 ; CHECK:       // %bb.0:
129 ; CHECK-NEXT:    mov w8, #20165
130 ; CHECK-NEXT:    movk w8, #64748, lsl #16
131 ; CHECK-NEXT:    orr w9, wzr, #0x8
132 ; CHECK-NEXT:    madd w8, w0, w8, w9
133 ; CHECK-NEXT:    ror w8, w8, #3
134 ; CHECK-NEXT:    cmp w8, #3 // =3
135 ; CHECK-NEXT:    cset w0, lo
136 ; CHECK-NEXT:    ret
137   %srem = srem i32 %X, 1073741928
138   %cmp = icmp eq i32 %srem, 0
139   %ret = zext i1 %cmp to i32
140   ret i32 %ret
143 ; This is like test_srem_odd, except the divisor has bit 31 set.
144 define i32 @test_srem_even_bit31(i32 %X) nounwind {
145 ; CHECK-LABEL: test_srem_even_bit31:
146 ; CHECK:       // %bb.0:
147 ; CHECK-NEXT:    mov w8, #1285
148 ; CHECK-NEXT:    movk w8, #50437, lsl #16
149 ; CHECK-NEXT:    orr w9, wzr, #0x2
150 ; CHECK-NEXT:    madd w8, w0, w8, w9
151 ; CHECK-NEXT:    ror w8, w8, #1
152 ; CHECK-NEXT:    cmp w8, #3 // =3
153 ; CHECK-NEXT:    cset w0, lo
154 ; CHECK-NEXT:    ret
155   %srem = srem i32 %X, 2147483750
156   %cmp = icmp eq i32 %srem, 0
157   %ret = zext i1 %cmp to i32
158   ret i32 %ret
161 ;------------------------------------------------------------------------------;
162 ; Special case
163 ;------------------------------------------------------------------------------;
165 ; 'NE' predicate is fine too.
166 define i32 @test_srem_odd_setne(i32 %X) nounwind {
167 ; CHECK-LABEL: test_srem_odd_setne:
168 ; CHECK:       // %bb.0:
169 ; CHECK-NEXT:    mov w8, #52429
170 ; CHECK-NEXT:    mov w9, #39321
171 ; CHECK-NEXT:    movk w8, #52428, lsl #16
172 ; CHECK-NEXT:    movk w9, #6553, lsl #16
173 ; CHECK-NEXT:    madd w8, w0, w8, w9
174 ; CHECK-NEXT:    mov w9, #13106
175 ; CHECK-NEXT:    movk w9, #13107, lsl #16
176 ; CHECK-NEXT:    cmp w8, w9
177 ; CHECK-NEXT:    cset w0, hi
178 ; CHECK-NEXT:    ret
179   %srem = srem i32 %X, 5
180   %cmp = icmp ne i32 %srem, 0
181   %ret = zext i1 %cmp to i32
182   ret i32 %ret
185 ; The fold is only valid for positive divisors, negative-ones should be negated.
186 define i32 @test_srem_negative_odd(i32 %X) nounwind {
187 ; CHECK-LABEL: test_srem_negative_odd:
188 ; CHECK:       // %bb.0:
189 ; CHECK-NEXT:    mov w8, #52429
190 ; CHECK-NEXT:    mov w9, #39321
191 ; CHECK-NEXT:    movk w8, #52428, lsl #16
192 ; CHECK-NEXT:    movk w9, #6553, lsl #16
193 ; CHECK-NEXT:    madd w8, w0, w8, w9
194 ; CHECK-NEXT:    mov w9, #13106
195 ; CHECK-NEXT:    movk w9, #13107, lsl #16
196 ; CHECK-NEXT:    cmp w8, w9
197 ; CHECK-NEXT:    cset w0, hi
198 ; CHECK-NEXT:    ret
199   %srem = srem i32 %X, -5
200   %cmp = icmp ne i32 %srem, 0
201   %ret = zext i1 %cmp to i32
202   ret i32 %ret
204 define i32 @test_srem_negative_even(i32 %X) nounwind {
205 ; CHECK-LABEL: test_srem_negative_even:
206 ; CHECK:       // %bb.0:
207 ; CHECK-NEXT:    mov w8, #28087
208 ; CHECK-NEXT:    mov w9, #9362
209 ; CHECK-NEXT:    movk w8, #46811, lsl #16
210 ; CHECK-NEXT:    movk w9, #4681, lsl #16
211 ; CHECK-NEXT:    madd w8, w0, w8, w9
212 ; CHECK-NEXT:    ror w8, w8, #1
213 ; CHECK-NEXT:    cmp w8, w9
214 ; CHECK-NEXT:    cset w0, hi
215 ; CHECK-NEXT:    ret
216   %srem = srem i32 %X, -14
217   %cmp = icmp ne i32 %srem, 0
218   %ret = zext i1 %cmp to i32
219   ret i32 %ret
222 ;------------------------------------------------------------------------------;
223 ; Negative tests
224 ;------------------------------------------------------------------------------;
226 ; We can lower remainder of division by one much better elsewhere.
227 define i32 @test_srem_one(i32 %X) nounwind {
228 ; CHECK-LABEL: test_srem_one:
229 ; CHECK:       // %bb.0:
230 ; CHECK-NEXT:    mov w0, #1
231 ; CHECK-NEXT:    ret
232   %srem = srem i32 %X, 1
233   %cmp = icmp eq i32 %srem, 0
234   %ret = zext i1 %cmp to i32
235   ret i32 %ret
238 ; We can lower remainder of division by powers of two much better elsewhere.
239 define i32 @test_srem_pow2(i32 %X) nounwind {
240 ; CHECK-LABEL: test_srem_pow2:
241 ; CHECK:       // %bb.0:
242 ; CHECK-NEXT:    add w8, w0, #15 // =15
243 ; CHECK-NEXT:    cmp w0, #0 // =0
244 ; CHECK-NEXT:    csel w8, w8, w0, lt
245 ; CHECK-NEXT:    and w8, w8, #0xfffffff0
246 ; CHECK-NEXT:    cmp w0, w8
247 ; CHECK-NEXT:    cset w0, eq
248 ; CHECK-NEXT:    ret
249   %srem = srem i32 %X, 16
250   %cmp = icmp eq i32 %srem, 0
251   %ret = zext i1 %cmp to i32
252   ret i32 %ret
255 ; The fold is only valid for positive divisors, and we can't negate INT_MIN.
256 define i32 @test_srem_int_min(i32 %X) nounwind {
257 ; CHECK-LABEL: test_srem_int_min:
258 ; CHECK:       // %bb.0:
259 ; CHECK-NEXT:    mov w8, #2147483647
260 ; CHECK-NEXT:    add w8, w0, w8
261 ; CHECK-NEXT:    cmp w0, #0 // =0
262 ; CHECK-NEXT:    csel w8, w8, w0, lt
263 ; CHECK-NEXT:    and w8, w8, #0x80000000
264 ; CHECK-NEXT:    cmn w0, w8
265 ; CHECK-NEXT:    cset w0, eq
266 ; CHECK-NEXT:    ret
267   %srem = srem i32 %X, 2147483648
268   %cmp = icmp eq i32 %srem, 0
269   %ret = zext i1 %cmp to i32
270   ret i32 %ret
273 ; We can lower remainder of division by all-ones much better elsewhere.
274 define i32 @test_srem_allones(i32 %X) nounwind {
275 ; CHECK-LABEL: test_srem_allones:
276 ; CHECK:       // %bb.0:
277 ; CHECK-NEXT:    cmp w0, #0 // =0
278 ; CHECK-NEXT:    csel w8, w0, w0, lt
279 ; CHECK-NEXT:    cmp w0, w8
280 ; CHECK-NEXT:    cset w0, eq
281 ; CHECK-NEXT:    ret
282   %srem = srem i32 %X, 4294967295
283   %cmp = icmp eq i32 %srem, 0
284   %ret = zext i1 %cmp to i32
285   ret i32 %ret