[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / X86 / srem-seteq.ll
blob67fe5f4c5e4470506f51f0be69a504da21cc0f64
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 ;------------------------------------------------------------------------------;
6 ; Odd divisors
7 ;------------------------------------------------------------------------------;
9 define i32 @test_srem_odd(i32 %X) nounwind {
10 ; X86-LABEL: test_srem_odd:
11 ; X86:       # %bb.0:
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
16 ; X86-NEXT:    setb %al
17 ; X86-NEXT:    retl
19 ; X64-LABEL: test_srem_odd:
20 ; X64:       # %bb.0:
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
25 ; X64-NEXT:    setb %al
26 ; X64-NEXT:    retq
27   %srem = srem i32 %X, 5
28   %cmp = icmp eq i32 %srem, 0
29   %ret = zext i1 %cmp to i32
30   ret i32 %ret
33 define i32 @test_srem_odd_25(i32 %X) nounwind {
34 ; X86-LABEL: test_srem_odd_25:
35 ; X86:       # %bb.0:
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
40 ; X86-NEXT:    setb %al
41 ; X86-NEXT:    retl
43 ; X64-LABEL: test_srem_odd_25:
44 ; X64:       # %bb.0:
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
49 ; X64-NEXT:    setb %al
50 ; X64-NEXT:    retq
51   %srem = srem i32 %X, 25
52   %cmp = icmp eq i32 %srem, 0
53   %ret = zext i1 %cmp to i32
54   ret i32 %ret
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:
60 ; X86:       # %bb.0:
61 ; X86-NEXT:    imull $1789569707, {{[0-9]+}}(%esp), %ecx # imm = 0x6AAAAAAB
62 ; X86-NEXT:    incl %ecx
63 ; X86-NEXT:    xorl %eax, %eax
64 ; X86-NEXT:    cmpl $3, %ecx
65 ; X86-NEXT:    setb %al
66 ; X86-NEXT:    retl
68 ; X64-LABEL: test_srem_odd_bit30:
69 ; X64:       # %bb.0:
70 ; X64-NEXT:    imull $1789569707, %edi, %ecx # imm = 0x6AAAAAAB
71 ; X64-NEXT:    incl %ecx
72 ; X64-NEXT:    xorl %eax, %eax
73 ; X64-NEXT:    cmpl $3, %ecx
74 ; X64-NEXT:    setb %al
75 ; X64-NEXT:    retq
76   %srem = srem i32 %X, 1073741827
77   %cmp = icmp eq i32 %srem, 0
78   %ret = zext i1 %cmp to i32
79   ret i32 %ret
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:
85 ; X86:       # %bb.0:
86 ; X86-NEXT:    imull $-715827883, {{[0-9]+}}(%esp), %ecx # imm = 0xD5555555
87 ; X86-NEXT:    incl %ecx
88 ; X86-NEXT:    xorl %eax, %eax
89 ; X86-NEXT:    cmpl $3, %ecx
90 ; X86-NEXT:    setb %al
91 ; X86-NEXT:    retl
93 ; X64-LABEL: test_srem_odd_bit31:
94 ; X64:       # %bb.0:
95 ; X64-NEXT:    imull $-715827883, %edi, %ecx # imm = 0xD5555555
96 ; X64-NEXT:    incl %ecx
97 ; X64-NEXT:    xorl %eax, %eax
98 ; X64-NEXT:    cmpl $3, %ecx
99 ; X64-NEXT:    setb %al
100 ; X64-NEXT:    retq
101   %srem = srem i32 %X, 2147483651
102   %cmp = icmp eq i32 %srem, 0
103   %ret = zext i1 %cmp to i32
104   ret i32 %ret
107 ;------------------------------------------------------------------------------;
108 ; Even divisors
109 ;------------------------------------------------------------------------------;
111 define i16 @test_srem_even(i16 %X) nounwind {
112 ; X86-LABEL: test_srem_even:
113 ; X86:       # %bb.0:
114 ; X86-NEXT:    imull $28087, {{[0-9]+}}(%esp), %eax # imm = 0x6DB7
115 ; X86-NEXT:    addl $4680, %eax # imm = 0x1248
116 ; X86-NEXT:    rorw %ax
117 ; X86-NEXT:    movzwl %ax, %ecx
118 ; X86-NEXT:    xorl %eax, %eax
119 ; X86-NEXT:    cmpl $4680, %ecx # imm = 0x1248
120 ; X86-NEXT:    seta %al
121 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
122 ; X86-NEXT:    retl
124 ; X64-LABEL: test_srem_even:
125 ; X64:       # %bb.0:
126 ; X64-NEXT:    imull $28087, %edi, %eax # imm = 0x6DB7
127 ; X64-NEXT:    addl $4680, %eax # imm = 0x1248
128 ; X64-NEXT:    rorw %ax
129 ; X64-NEXT:    movzwl %ax, %ecx
130 ; X64-NEXT:    xorl %eax, %eax
131 ; X64-NEXT:    cmpl $4680, %ecx # imm = 0x1248
132 ; X64-NEXT:    seta %al
133 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
134 ; X64-NEXT:    retq
135   %srem = srem i16 %X, 14
136   %cmp = icmp ne i16 %srem, 0
137   %ret = zext i1 %cmp to i16
138   ret i16 %ret
141 define i32 @test_srem_even_100(i32 %X) nounwind {
142 ; X86-LABEL: test_srem_even_100:
143 ; X86:       # %bb.0:
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
149 ; X86-NEXT:    setb %al
150 ; X86-NEXT:    retl
152 ; X64-LABEL: test_srem_even_100:
153 ; X64:       # %bb.0:
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
159 ; X64-NEXT:    setb %al
160 ; X64-NEXT:    retq
161   %srem = srem i32 %X, 100
162   %cmp = icmp eq i32 %srem, 0
163   %ret = zext i1 %cmp to i32
164   ret i32 %ret
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:
170 ; X86:       # %bb.0:
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
176 ; X86-NEXT:    setb %al
177 ; X86-NEXT:    retl
179 ; X64-LABEL: test_srem_even_bit30:
180 ; X64:       # %bb.0:
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
186 ; X64-NEXT:    setb %al
187 ; X64-NEXT:    retq
188   %srem = srem i32 %X, 1073741928
189   %cmp = icmp eq i32 %srem, 0
190   %ret = zext i1 %cmp to i32
191   ret i32 %ret
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:
197 ; X86:       # %bb.0:
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
203 ; X86-NEXT:    setb %al
204 ; X86-NEXT:    retl
206 ; X64-LABEL: test_srem_even_bit31:
207 ; X64:       # %bb.0:
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
213 ; X64-NEXT:    setb %al
214 ; X64-NEXT:    retq
215   %srem = srem i32 %X, 2147483750
216   %cmp = icmp eq i32 %srem, 0
217   %ret = zext i1 %cmp to i32
218   ret i32 %ret
221 ;------------------------------------------------------------------------------;
222 ; Special case
223 ;------------------------------------------------------------------------------;
225 ; 'NE' predicate is fine too.
226 define i32 @test_srem_odd_setne(i32 %X) nounwind {
227 ; X86-LABEL: test_srem_odd_setne:
228 ; X86:       # %bb.0:
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 $858993458, %ecx # imm = 0x33333332
233 ; X86-NEXT:    seta %al
234 ; X86-NEXT:    retl
236 ; X64-LABEL: test_srem_odd_setne:
237 ; X64:       # %bb.0:
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 $858993458, %ecx # imm = 0x33333332
242 ; X64-NEXT:    seta %al
243 ; X64-NEXT:    retq
244   %srem = srem i32 %X, 5
245   %cmp = icmp ne i32 %srem, 0
246   %ret = zext i1 %cmp to i32
247   ret i32 %ret
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:
253 ; X86:       # %bb.0:
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 $858993458, %ecx # imm = 0x33333332
258 ; X86-NEXT:    seta %al
259 ; X86-NEXT:    retl
261 ; X64-LABEL: test_srem_negative_odd:
262 ; X64:       # %bb.0:
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 $858993458, %ecx # imm = 0x33333332
267 ; X64-NEXT:    seta %al
268 ; X64-NEXT:    retq
269   %srem = srem i32 %X, -5
270   %cmp = icmp ne i32 %srem, 0
271   %ret = zext i1 %cmp to i32
272   ret i32 %ret
274 define i32 @test_srem_negative_even(i32 %X) nounwind {
275 ; X86-LABEL: test_srem_negative_even:
276 ; X86:       # %bb.0:
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 $306783378, %ecx # imm = 0x12492492
282 ; X86-NEXT:    seta %al
283 ; X86-NEXT:    retl
285 ; X64-LABEL: test_srem_negative_even:
286 ; X64:       # %bb.0:
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 $306783378, %ecx # imm = 0x12492492
292 ; X64-NEXT:    seta %al
293 ; X64-NEXT:    retq
294   %srem = srem i32 %X, -14
295   %cmp = icmp ne i32 %srem, 0
296   %ret = zext i1 %cmp to i32
297   ret i32 %ret
300 ;------------------------------------------------------------------------------;
301 ; Negative tests
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:
307 ; CHECK:       # %bb.0:
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
313   ret i32 %ret
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:
319 ; X86:       # %bb.0:
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
327 ; X86-NEXT:    sete %al
328 ; X86-NEXT:    retl
330 ; X64-LABEL: test_srem_pow2:
331 ; X64:       # %bb.0:
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
339 ; X64-NEXT:    sete %al
340 ; X64-NEXT:    retq
341   %srem = srem i32 %X, 16
342   %cmp = icmp eq i32 %srem, 0
343   %ret = zext i1 %cmp to i32
344   ret i32 %ret
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:
350 ; X86:       # %bb.0:
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
358 ; X86-NEXT:    sete %al
359 ; X86-NEXT:    retl
361 ; X64-LABEL: test_srem_int_min:
362 ; X64:       # %bb.0:
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
370 ; X64-NEXT:    sete %al
371 ; X64-NEXT:    retq
372   %srem = srem i32 %X, 2147483648
373   %cmp = icmp eq i32 %srem, 0
374   %ret = zext i1 %cmp to i32
375   ret i32 %ret
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:
381 ; CHECK:       # %bb.0:
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
387   ret i32 %ret