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 ;------------------------------------------------------------------------------;
6 ;------------------------------------------------------------------------------;
8 define i32 @test_urem_odd(i32 %X) nounwind {
9 ; CHECK-LABEL: test_urem_odd:
11 ; CHECK-NEXT: mov w8, #52429
12 ; CHECK-NEXT: movk w8, #52428, lsl #16
13 ; CHECK-NEXT: mov w9, #13108
14 ; CHECK-NEXT: mul w8, w0, w8
15 ; CHECK-NEXT: movk w9, #13107, lsl #16
16 ; CHECK-NEXT: cmp w8, w9
17 ; CHECK-NEXT: cset w0, lo
19 %urem = urem i32 %X, 5
20 %cmp = icmp eq i32 %urem, 0
21 %ret = zext i1 %cmp to i32
25 define i32 @test_urem_odd_25(i32 %X) nounwind {
26 ; CHECK-LABEL: test_urem_odd_25:
28 ; CHECK-NEXT: mov w8, #23593
29 ; CHECK-NEXT: movk w8, #49807, lsl #16
30 ; CHECK-NEXT: mov w9, #28836
31 ; CHECK-NEXT: mul w8, w0, w8
32 ; CHECK-NEXT: movk w9, #2621, lsl #16
33 ; CHECK-NEXT: cmp w8, w9
34 ; CHECK-NEXT: cset w0, lo
36 %urem = urem i32 %X, 25
37 %cmp = icmp eq i32 %urem, 0
38 %ret = zext i1 %cmp to i32
42 ; This is like test_urem_odd, except the divisor has bit 30 set.
43 define i32 @test_urem_odd_bit30(i32 %X) nounwind {
44 ; CHECK-LABEL: test_urem_odd_bit30:
46 ; CHECK-NEXT: mov w8, #43691
47 ; CHECK-NEXT: movk w8, #27306, lsl #16
48 ; CHECK-NEXT: mul w8, w0, w8
49 ; CHECK-NEXT: cmp w8, #4 // =4
50 ; CHECK-NEXT: cset w0, lo
52 %urem = urem i32 %X, 1073741827
53 %cmp = icmp eq i32 %urem, 0
54 %ret = zext i1 %cmp to i32
58 ; This is like test_urem_odd, except the divisor has bit 31 set.
59 define i32 @test_urem_odd_bit31(i32 %X) nounwind {
60 ; CHECK-LABEL: test_urem_odd_bit31:
62 ; CHECK-NEXT: mov w8, #43691
63 ; CHECK-NEXT: movk w8, #10922, lsl #16
64 ; CHECK-NEXT: mul w8, w0, w8
65 ; CHECK-NEXT: cmp w8, #2 // =2
66 ; CHECK-NEXT: cset w0, lo
68 %urem = urem i32 %X, 2147483651
69 %cmp = icmp eq i32 %urem, 0
70 %ret = zext i1 %cmp to i32
74 ;------------------------------------------------------------------------------;
76 ;------------------------------------------------------------------------------;
78 define i16 @test_urem_even(i16 %X) nounwind {
79 ; CHECK-LABEL: test_urem_even:
81 ; CHECK-NEXT: mov w9, #28087
82 ; CHECK-NEXT: and w8, w0, #0xffff
83 ; CHECK-NEXT: movk w9, #46811, lsl #16
84 ; CHECK-NEXT: mul w8, w8, w9
85 ; CHECK-NEXT: mov w9, #9362
86 ; CHECK-NEXT: ror w8, w8, #1
87 ; CHECK-NEXT: movk w9, #4681, lsl #16
88 ; CHECK-NEXT: cmp w8, w9
89 ; CHECK-NEXT: cset w0, hi
91 %urem = urem i16 %X, 14
92 %cmp = icmp ne i16 %urem, 0
93 %ret = zext i1 %cmp to i16
97 define i32 @test_urem_even_100(i32 %X) nounwind {
98 ; CHECK-LABEL: test_urem_even_100:
100 ; CHECK-NEXT: mov w8, #23593
101 ; CHECK-NEXT: movk w8, #49807, lsl #16
102 ; CHECK-NEXT: mul w8, w0, w8
103 ; CHECK-NEXT: mov w9, #23593
104 ; CHECK-NEXT: ror w8, w8, #2
105 ; CHECK-NEXT: movk w9, #655, lsl #16
106 ; CHECK-NEXT: cmp w8, w9
107 ; CHECK-NEXT: cset w0, lo
109 %urem = urem i32 %X, 100
110 %cmp = icmp eq i32 %urem, 0
111 %ret = zext i1 %cmp to i32
115 ; This is like test_urem_even, except the divisor has bit 30 set.
116 define i32 @test_urem_even_bit30(i32 %X) nounwind {
117 ; CHECK-LABEL: test_urem_even_bit30:
119 ; CHECK-NEXT: mov w8, #20165
120 ; CHECK-NEXT: movk w8, #64748, lsl #16
121 ; CHECK-NEXT: mul w8, w0, w8
122 ; CHECK-NEXT: ror w8, w8, #3
123 ; CHECK-NEXT: cmp w8, #4 // =4
124 ; CHECK-NEXT: cset w0, lo
126 %urem = urem i32 %X, 1073741928
127 %cmp = icmp eq i32 %urem, 0
128 %ret = zext i1 %cmp to i32
132 ; This is like test_urem_odd, except the divisor has bit 31 set.
133 define i32 @test_urem_even_bit31(i32 %X) nounwind {
134 ; CHECK-LABEL: test_urem_even_bit31:
136 ; CHECK-NEXT: mov w8, #64251
137 ; CHECK-NEXT: movk w8, #47866, lsl #16
138 ; CHECK-NEXT: mul w8, w0, w8
139 ; CHECK-NEXT: ror w8, w8, #1
140 ; CHECK-NEXT: cmp w8, #2 // =2
141 ; CHECK-NEXT: cset w0, lo
143 %urem = urem i32 %X, 2147483750
144 %cmp = icmp eq i32 %urem, 0
145 %ret = zext i1 %cmp to i32
149 ;------------------------------------------------------------------------------;
151 ;------------------------------------------------------------------------------;
153 ; 'NE' predicate is fine too.
154 define i32 @test_urem_odd_setne(i32 %X) nounwind {
155 ; CHECK-LABEL: test_urem_odd_setne:
157 ; CHECK-NEXT: mov w8, #52429
158 ; CHECK-NEXT: movk w8, #52428, lsl #16
159 ; CHECK-NEXT: mul w8, w0, w8
160 ; CHECK-NEXT: mov w9, #858993459
161 ; CHECK-NEXT: cmp w8, w9
162 ; CHECK-NEXT: cset w0, hi
164 %urem = urem i32 %X, 5
165 %cmp = icmp ne i32 %urem, 0
166 %ret = zext i1 %cmp to i32
170 ; The fold is only valid for positive divisors, negative-ones should be negated.
171 define i32 @test_urem_negative_odd(i32 %X) nounwind {
172 ; CHECK-LABEL: test_urem_negative_odd:
174 ; CHECK-NEXT: mov w8, #858993459
175 ; CHECK-NEXT: mul w8, w0, w8
176 ; CHECK-NEXT: cmp w8, #1 // =1
177 ; CHECK-NEXT: cset w0, hi
179 %urem = urem i32 %X, -5
180 %cmp = icmp ne i32 %urem, 0
181 %ret = zext i1 %cmp to i32
184 define i32 @test_urem_negative_even(i32 %X) nounwind {
185 ; CHECK-LABEL: test_urem_negative_even:
187 ; CHECK-NEXT: mov w8, #37449
188 ; CHECK-NEXT: movk w8, #51492, lsl #16
189 ; CHECK-NEXT: mul w8, w0, w8
190 ; CHECK-NEXT: ror w8, w8, #1
191 ; CHECK-NEXT: cmp w8, #1 // =1
192 ; CHECK-NEXT: cset w0, hi
194 %urem = urem i32 %X, -14
195 %cmp = icmp ne i32 %urem, 0
196 %ret = zext i1 %cmp to i32
200 ;------------------------------------------------------------------------------;
202 ;------------------------------------------------------------------------------;
204 ; We can lower remainder of division by one much better elsewhere.
205 define i32 @test_urem_one(i32 %X) nounwind {
206 ; CHECK-LABEL: test_urem_one:
208 ; CHECK-NEXT: mov w0, #1
210 %urem = urem i32 %X, 1
211 %cmp = icmp eq i32 %urem, 0
212 %ret = zext i1 %cmp to i32
216 ; We can lower remainder of division by powers of two much better elsewhere.
217 define i32 @test_urem_pow2(i32 %X) nounwind {
218 ; CHECK-LABEL: test_urem_pow2:
220 ; CHECK-NEXT: tst w0, #0xf
221 ; CHECK-NEXT: cset w0, eq
223 %urem = urem i32 %X, 16
224 %cmp = icmp eq i32 %urem, 0
225 %ret = zext i1 %cmp to i32
229 ; The fold is only valid for positive divisors, and we can't negate INT_MIN.
230 define i32 @test_urem_int_min(i32 %X) nounwind {
231 ; CHECK-LABEL: test_urem_int_min:
233 ; CHECK-NEXT: tst w0, #0x7fffffff
234 ; CHECK-NEXT: cset w0, eq
236 %urem = urem i32 %X, 2147483648
237 %cmp = icmp eq i32 %urem, 0
238 %ret = zext i1 %cmp to i32
242 ; We can lower remainder of division by all-ones much better elsewhere.
243 define i32 @test_urem_allones(i32 %X) nounwind {
244 ; CHECK-LABEL: test_urem_allones:
246 ; CHECK-NEXT: neg w8, w0
247 ; CHECK-NEXT: cmp w8, #2 // =2
248 ; CHECK-NEXT: cset w0, lo
250 %urem = urem i32 %X, 4294967295
251 %cmp = icmp eq i32 %urem, 0
252 %ret = zext i1 %cmp to i32