1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov < %s | FileCheck %s --check-prefixes=CHECK,X86
3 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,X64
5 ;------------------------------------------------------------------------------;
7 ;------------------------------------------------------------------------------;
9 define i32 @test_srem_odd(i32 %X) nounwind {
10 ; X86-LABEL: test_srem_odd:
12 ; X86-NEXT: imull $-858993459, {{[0-9]+}}(%esp), %ecx # imm = 0xCCCCCCCD
13 ; X86-NEXT: addl $429496729, %ecx # imm = 0x19999999
14 ; X86-NEXT: xorl %eax, %eax
15 ; X86-NEXT: cmpl $858993459, %ecx # imm = 0x33333333
19 ; X64-LABEL: test_srem_odd:
21 ; X64-NEXT: imull $-858993459, %edi, %ecx # imm = 0xCCCCCCCD
22 ; X64-NEXT: addl $429496729, %ecx # imm = 0x19999999
23 ; X64-NEXT: xorl %eax, %eax
24 ; X64-NEXT: cmpl $858993459, %ecx # imm = 0x33333333
27 %srem = srem i32 %X, 5
28 %cmp = icmp eq i32 %srem, 0
29 %ret = zext i1 %cmp to i32
33 define i32 @test_srem_odd_25(i32 %X) nounwind {
34 ; X86-LABEL: test_srem_odd_25:
36 ; X86-NEXT: imull $-1030792151, {{[0-9]+}}(%esp), %ecx # imm = 0xC28F5C29
37 ; X86-NEXT: addl $85899345, %ecx # imm = 0x51EB851
38 ; X86-NEXT: xorl %eax, %eax
39 ; X86-NEXT: cmpl $171798691, %ecx # imm = 0xA3D70A3
43 ; X64-LABEL: test_srem_odd_25:
45 ; X64-NEXT: imull $-1030792151, %edi, %ecx # imm = 0xC28F5C29
46 ; X64-NEXT: addl $85899345, %ecx # imm = 0x51EB851
47 ; X64-NEXT: xorl %eax, %eax
48 ; X64-NEXT: cmpl $171798691, %ecx # imm = 0xA3D70A3
51 %srem = srem i32 %X, 25
52 %cmp = icmp eq i32 %srem, 0
53 %ret = zext i1 %cmp to i32
57 ; This is like test_srem_odd, except the divisor has bit 30 set.
58 define i32 @test_srem_odd_bit30(i32 %X) nounwind {
59 ; X86-LABEL: test_srem_odd_bit30:
61 ; X86-NEXT: imull $1789569707, {{[0-9]+}}(%esp), %ecx # imm = 0x6AAAAAAB
63 ; X86-NEXT: xorl %eax, %eax
64 ; X86-NEXT: cmpl $3, %ecx
68 ; X64-LABEL: test_srem_odd_bit30:
70 ; X64-NEXT: imull $1789569707, %edi, %ecx # imm = 0x6AAAAAAB
72 ; X64-NEXT: xorl %eax, %eax
73 ; X64-NEXT: cmpl $3, %ecx
76 %srem = srem i32 %X, 1073741827
77 %cmp = icmp eq i32 %srem, 0
78 %ret = zext i1 %cmp to i32
82 ; This is like test_srem_odd, except the divisor has bit 31 set.
83 define i32 @test_srem_odd_bit31(i32 %X) nounwind {
84 ; X86-LABEL: test_srem_odd_bit31:
86 ; X86-NEXT: imull $-715827883, {{[0-9]+}}(%esp), %ecx # imm = 0xD5555555
88 ; X86-NEXT: xorl %eax, %eax
89 ; X86-NEXT: cmpl $3, %ecx
93 ; X64-LABEL: test_srem_odd_bit31:
95 ; X64-NEXT: imull $-715827883, %edi, %ecx # imm = 0xD5555555
97 ; X64-NEXT: xorl %eax, %eax
98 ; X64-NEXT: cmpl $3, %ecx
101 %srem = srem i32 %X, 2147483651
102 %cmp = icmp eq i32 %srem, 0
103 %ret = zext i1 %cmp to i32
107 ;------------------------------------------------------------------------------;
109 ;------------------------------------------------------------------------------;
111 define i16 @test_srem_even(i16 %X) nounwind {
112 ; X86-LABEL: test_srem_even:
114 ; X86-NEXT: imull $28087, {{[0-9]+}}(%esp), %eax # imm = 0x6DB7
115 ; X86-NEXT: addl $4680, %eax # imm = 0x1248
117 ; X86-NEXT: movzwl %ax, %ecx
118 ; X86-NEXT: xorl %eax, %eax
119 ; X86-NEXT: cmpl $4681, %ecx # imm = 0x1249
120 ; X86-NEXT: setae %al
121 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
124 ; X64-LABEL: test_srem_even:
126 ; X64-NEXT: imull $28087, %edi, %eax # imm = 0x6DB7
127 ; X64-NEXT: addl $4680, %eax # imm = 0x1248
129 ; X64-NEXT: movzwl %ax, %ecx
130 ; X64-NEXT: xorl %eax, %eax
131 ; X64-NEXT: cmpl $4681, %ecx # imm = 0x1249
132 ; X64-NEXT: setae %al
133 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
135 %srem = srem i16 %X, 14
136 %cmp = icmp ne i16 %srem, 0
137 %ret = zext i1 %cmp to i16
141 define i32 @test_srem_even_100(i32 %X) nounwind {
142 ; X86-LABEL: test_srem_even_100:
144 ; X86-NEXT: imull $-1030792151, {{[0-9]+}}(%esp), %ecx # imm = 0xC28F5C29
145 ; X86-NEXT: addl $85899344, %ecx # imm = 0x51EB850
146 ; X86-NEXT: rorl $2, %ecx
147 ; X86-NEXT: xorl %eax, %eax
148 ; X86-NEXT: cmpl $42949673, %ecx # imm = 0x28F5C29
152 ; X64-LABEL: test_srem_even_100:
154 ; X64-NEXT: imull $-1030792151, %edi, %ecx # imm = 0xC28F5C29
155 ; X64-NEXT: addl $85899344, %ecx # imm = 0x51EB850
156 ; X64-NEXT: rorl $2, %ecx
157 ; X64-NEXT: xorl %eax, %eax
158 ; X64-NEXT: cmpl $42949673, %ecx # imm = 0x28F5C29
161 %srem = srem i32 %X, 100
162 %cmp = icmp eq i32 %srem, 0
163 %ret = zext i1 %cmp to i32
167 ; This is like test_srem_even, except the divisor has bit 30 set.
168 define i32 @test_srem_even_bit30(i32 %X) nounwind {
169 ; X86-LABEL: test_srem_even_bit30:
171 ; X86-NEXT: imull $-51622203, {{[0-9]+}}(%esp), %ecx # imm = 0xFCEC4EC5
172 ; X86-NEXT: addl $8, %ecx
173 ; X86-NEXT: rorl $3, %ecx
174 ; X86-NEXT: xorl %eax, %eax
175 ; X86-NEXT: cmpl $3, %ecx
179 ; X64-LABEL: test_srem_even_bit30:
181 ; X64-NEXT: imull $-51622203, %edi, %ecx # imm = 0xFCEC4EC5
182 ; X64-NEXT: addl $8, %ecx
183 ; X64-NEXT: rorl $3, %ecx
184 ; X64-NEXT: xorl %eax, %eax
185 ; X64-NEXT: cmpl $3, %ecx
188 %srem = srem i32 %X, 1073741928
189 %cmp = icmp eq i32 %srem, 0
190 %ret = zext i1 %cmp to i32
194 ; This is like test_srem_odd, except the divisor has bit 31 set.
195 define i32 @test_srem_even_bit31(i32 %X) nounwind {
196 ; X86-LABEL: test_srem_even_bit31:
198 ; X86-NEXT: imull $-989526779, {{[0-9]+}}(%esp), %ecx # imm = 0xC5050505
199 ; X86-NEXT: addl $2, %ecx
200 ; X86-NEXT: rorl %ecx
201 ; X86-NEXT: xorl %eax, %eax
202 ; X86-NEXT: cmpl $3, %ecx
206 ; X64-LABEL: test_srem_even_bit31:
208 ; X64-NEXT: imull $-989526779, %edi, %ecx # imm = 0xC5050505
209 ; X64-NEXT: addl $2, %ecx
210 ; X64-NEXT: rorl %ecx
211 ; X64-NEXT: xorl %eax, %eax
212 ; X64-NEXT: cmpl $3, %ecx
215 %srem = srem i32 %X, 2147483750
216 %cmp = icmp eq i32 %srem, 0
217 %ret = zext i1 %cmp to i32
221 ;------------------------------------------------------------------------------;
223 ;------------------------------------------------------------------------------;
225 ; 'NE' predicate is fine too.
226 define i32 @test_srem_odd_setne(i32 %X) nounwind {
227 ; X86-LABEL: test_srem_odd_setne:
229 ; X86-NEXT: imull $-858993459, {{[0-9]+}}(%esp), %ecx # imm = 0xCCCCCCCD
230 ; X86-NEXT: addl $429496729, %ecx # imm = 0x19999999
231 ; X86-NEXT: xorl %eax, %eax
232 ; X86-NEXT: cmpl $858993459, %ecx # imm = 0x33333333
233 ; X86-NEXT: setae %al
236 ; X64-LABEL: test_srem_odd_setne:
238 ; X64-NEXT: imull $-858993459, %edi, %ecx # imm = 0xCCCCCCCD
239 ; X64-NEXT: addl $429496729, %ecx # imm = 0x19999999
240 ; X64-NEXT: xorl %eax, %eax
241 ; X64-NEXT: cmpl $858993459, %ecx # imm = 0x33333333
242 ; X64-NEXT: setae %al
244 %srem = srem i32 %X, 5
245 %cmp = icmp ne i32 %srem, 0
246 %ret = zext i1 %cmp to i32
250 ; The fold is only valid for positive divisors, negative-ones should be negated.
251 define i32 @test_srem_negative_odd(i32 %X) nounwind {
252 ; X86-LABEL: test_srem_negative_odd:
254 ; X86-NEXT: imull $-858993459, {{[0-9]+}}(%esp), %ecx # imm = 0xCCCCCCCD
255 ; X86-NEXT: addl $429496729, %ecx # imm = 0x19999999
256 ; X86-NEXT: xorl %eax, %eax
257 ; X86-NEXT: cmpl $858993459, %ecx # imm = 0x33333333
258 ; X86-NEXT: setae %al
261 ; X64-LABEL: test_srem_negative_odd:
263 ; X64-NEXT: imull $-858993459, %edi, %ecx # imm = 0xCCCCCCCD
264 ; X64-NEXT: addl $429496729, %ecx # imm = 0x19999999
265 ; X64-NEXT: xorl %eax, %eax
266 ; X64-NEXT: cmpl $858993459, %ecx # imm = 0x33333333
267 ; X64-NEXT: setae %al
269 %srem = srem i32 %X, -5
270 %cmp = icmp ne i32 %srem, 0
271 %ret = zext i1 %cmp to i32
274 define i32 @test_srem_negative_even(i32 %X) nounwind {
275 ; X86-LABEL: test_srem_negative_even:
277 ; X86-NEXT: imull $-1227133513, {{[0-9]+}}(%esp), %ecx # imm = 0xB6DB6DB7
278 ; X86-NEXT: addl $306783378, %ecx # imm = 0x12492492
279 ; X86-NEXT: rorl %ecx
280 ; X86-NEXT: xorl %eax, %eax
281 ; X86-NEXT: cmpl $306783379, %ecx # imm = 0x12492493
282 ; X86-NEXT: setae %al
285 ; X64-LABEL: test_srem_negative_even:
287 ; X64-NEXT: imull $-1227133513, %edi, %ecx # imm = 0xB6DB6DB7
288 ; X64-NEXT: addl $306783378, %ecx # imm = 0x12492492
289 ; X64-NEXT: rorl %ecx
290 ; X64-NEXT: xorl %eax, %eax
291 ; X64-NEXT: cmpl $306783379, %ecx # imm = 0x12492493
292 ; X64-NEXT: setae %al
294 %srem = srem i32 %X, -14
295 %cmp = icmp ne i32 %srem, 0
296 %ret = zext i1 %cmp to i32
300 ;------------------------------------------------------------------------------;
302 ;------------------------------------------------------------------------------;
304 ; We can lower remainder of division by one much better elsewhere.
305 define i32 @test_srem_one(i32 %X) nounwind {
306 ; CHECK-LABEL: test_srem_one:
308 ; CHECK-NEXT: movl $1, %eax
309 ; CHECK-NEXT: ret{{[l|q]}}
310 %srem = srem i32 %X, 1
311 %cmp = icmp eq i32 %srem, 0
312 %ret = zext i1 %cmp to i32
316 ; We can lower remainder of division by powers of two much better elsewhere.
317 define i32 @test_srem_pow2(i32 %X) nounwind {
318 ; X86-LABEL: test_srem_pow2:
320 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
321 ; X86-NEXT: leal 15(%ecx), %edx
322 ; X86-NEXT: testl %ecx, %ecx
323 ; X86-NEXT: cmovnsl %ecx, %edx
324 ; X86-NEXT: andl $-16, %edx
325 ; X86-NEXT: xorl %eax, %eax
326 ; X86-NEXT: cmpl %edx, %ecx
330 ; X64-LABEL: test_srem_pow2:
332 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
333 ; X64-NEXT: leal 15(%rdi), %ecx
334 ; X64-NEXT: testl %edi, %edi
335 ; X64-NEXT: cmovnsl %edi, %ecx
336 ; X64-NEXT: andl $-16, %ecx
337 ; X64-NEXT: xorl %eax, %eax
338 ; X64-NEXT: cmpl %ecx, %edi
341 %srem = srem i32 %X, 16
342 %cmp = icmp eq i32 %srem, 0
343 %ret = zext i1 %cmp to i32
347 ; The fold is only valid for positive divisors, and we can't negate INT_MIN.
348 define i32 @test_srem_int_min(i32 %X) nounwind {
349 ; X86-LABEL: test_srem_int_min:
351 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
352 ; X86-NEXT: leal 2147483647(%ecx), %edx
353 ; X86-NEXT: testl %ecx, %ecx
354 ; X86-NEXT: cmovnsl %ecx, %edx
355 ; X86-NEXT: andl $-2147483648, %edx # imm = 0x80000000
356 ; X86-NEXT: xorl %eax, %eax
357 ; X86-NEXT: addl %ecx, %edx
361 ; X64-LABEL: test_srem_int_min:
363 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
364 ; X64-NEXT: leal 2147483647(%rdi), %ecx
365 ; X64-NEXT: testl %edi, %edi
366 ; X64-NEXT: cmovnsl %edi, %ecx
367 ; X64-NEXT: andl $-2147483648, %ecx # imm = 0x80000000
368 ; X64-NEXT: xorl %eax, %eax
369 ; X64-NEXT: addl %edi, %ecx
372 %srem = srem i32 %X, 2147483648
373 %cmp = icmp eq i32 %srem, 0
374 %ret = zext i1 %cmp to i32
378 ; We can lower remainder of division by all-ones much better elsewhere.
379 define i32 @test_srem_allones(i32 %X) nounwind {
380 ; CHECK-LABEL: test_srem_allones:
382 ; CHECK-NEXT: movl $1, %eax
383 ; CHECK-NEXT: ret{{[l|q]}}
384 %srem = srem i32 %X, 4294967295
385 %cmp = icmp eq i32 %srem, 0
386 %ret = zext i1 %cmp to i32