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 // =0xcccd
12 ; CHECK-NEXT: mov w9, #13108 // =0x3334
13 ; CHECK-NEXT: movk w8, #52428, lsl #16
14 ; CHECK-NEXT: movk w9, #13107, lsl #16
15 ; CHECK-NEXT: mul w8, w0, w8
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 // =0x5c29
29 ; CHECK-NEXT: mov w9, #28836 // =0x70a4
30 ; CHECK-NEXT: movk w8, #49807, lsl #16
31 ; CHECK-NEXT: movk w9, #2621, lsl #16
32 ; CHECK-NEXT: mul w8, w0, w8
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 // =0xaaab
47 ; CHECK-NEXT: movk w8, #27306, lsl #16
48 ; CHECK-NEXT: mul w8, w0, w8
49 ; CHECK-NEXT: cmp w8, #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 // =0xaaab
63 ; CHECK-NEXT: movk w8, #10922, lsl #16
64 ; CHECK-NEXT: mul w8, w0, w8
65 ; CHECK-NEXT: cmp w8, #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 w8, #28087 // =0x6db7
82 ; CHECK-NEXT: mul w8, w0, w8
83 ; CHECK-NEXT: and w9, w8, #0xfffc
84 ; CHECK-NEXT: lsr w9, w9, #1
85 ; CHECK-NEXT: orr w8, w9, w8, lsl #15
86 ; CHECK-NEXT: ubfx w8, w8, #1, #15
87 ; CHECK-NEXT: cmp w8, #2340
88 ; CHECK-NEXT: cset w0, hi
90 %urem = urem i16 %X, 14
91 %cmp = icmp ne i16 %urem, 0
92 %ret = zext i1 %cmp to i16
96 define i32 @test_urem_even_100(i32 %X) nounwind {
97 ; CHECK-LABEL: test_urem_even_100:
99 ; CHECK-NEXT: mov w8, #23593 // =0x5c29
100 ; CHECK-NEXT: mov w9, #23593 // =0x5c29
101 ; CHECK-NEXT: movk w8, #49807, lsl #16
102 ; CHECK-NEXT: movk w9, #655, lsl #16
103 ; CHECK-NEXT: mul w8, w0, w8
104 ; CHECK-NEXT: ror w8, w8, #2
105 ; CHECK-NEXT: cmp w8, w9
106 ; CHECK-NEXT: cset w0, lo
108 %urem = urem i32 %X, 100
109 %cmp = icmp eq i32 %urem, 0
110 %ret = zext i1 %cmp to i32
114 ; This is like test_urem_even, except the divisor has bit 30 set.
115 define i32 @test_urem_even_bit30(i32 %X) nounwind {
116 ; CHECK-LABEL: test_urem_even_bit30:
118 ; CHECK-NEXT: mov w8, #20165 // =0x4ec5
119 ; CHECK-NEXT: movk w8, #64748, lsl #16
120 ; CHECK-NEXT: mul w8, w0, w8
121 ; CHECK-NEXT: ror w8, w8, #3
122 ; CHECK-NEXT: cmp w8, #4
123 ; CHECK-NEXT: cset w0, lo
125 %urem = urem i32 %X, 1073741928
126 %cmp = icmp eq i32 %urem, 0
127 %ret = zext i1 %cmp to i32
131 ; This is like test_urem_odd, except the divisor has bit 31 set.
132 define i32 @test_urem_even_bit31(i32 %X) nounwind {
133 ; CHECK-LABEL: test_urem_even_bit31:
135 ; CHECK-NEXT: mov w8, #64251 // =0xfafb
136 ; CHECK-NEXT: movk w8, #47866, lsl #16
137 ; CHECK-NEXT: mul w8, w0, w8
138 ; CHECK-NEXT: ror w8, w8, #1
139 ; CHECK-NEXT: cmp w8, #2
140 ; CHECK-NEXT: cset w0, lo
142 %urem = urem i32 %X, 2147483750
143 %cmp = icmp eq i32 %urem, 0
144 %ret = zext i1 %cmp to i32
148 ;------------------------------------------------------------------------------;
150 ;------------------------------------------------------------------------------;
152 ; 'NE' predicate is fine too.
153 define i32 @test_urem_odd_setne(i32 %X) nounwind {
154 ; CHECK-LABEL: test_urem_odd_setne:
156 ; CHECK-NEXT: mov w8, #52429 // =0xcccd
157 ; CHECK-NEXT: mov w9, #858993459 // =0x33333333
158 ; CHECK-NEXT: movk w8, #52428, lsl #16
159 ; CHECK-NEXT: mul w8, w0, w8
160 ; CHECK-NEXT: cmp w8, w9
161 ; CHECK-NEXT: cset w0, hi
163 %urem = urem i32 %X, 5
164 %cmp = icmp ne i32 %urem, 0
165 %ret = zext i1 %cmp to i32
169 ; The fold is only valid for positive divisors, negative-ones should be negated.
170 define i32 @test_urem_negative_odd(i32 %X) nounwind {
171 ; CHECK-LABEL: test_urem_negative_odd:
173 ; CHECK-NEXT: mov w8, #858993459 // =0x33333333
174 ; CHECK-NEXT: mul w8, w0, w8
175 ; CHECK-NEXT: cmp w8, #1
176 ; CHECK-NEXT: cset w0, hi
178 %urem = urem i32 %X, -5
179 %cmp = icmp ne i32 %urem, 0
180 %ret = zext i1 %cmp to i32
183 define i32 @test_urem_negative_even(i32 %X) nounwind {
184 ; CHECK-LABEL: test_urem_negative_even:
186 ; CHECK-NEXT: mov w8, #37449 // =0x9249
187 ; CHECK-NEXT: movk w8, #51492, lsl #16
188 ; CHECK-NEXT: mul w8, w0, w8
189 ; CHECK-NEXT: ror w8, w8, #1
190 ; CHECK-NEXT: cmp w8, #1
191 ; CHECK-NEXT: cset w0, hi
193 %urem = urem i32 %X, -14
194 %cmp = icmp ne i32 %urem, 0
195 %ret = zext i1 %cmp to i32
199 ;------------------------------------------------------------------------------;
201 ;------------------------------------------------------------------------------;
203 ; We can lower remainder of division by one much better elsewhere.
204 define i32 @test_urem_one(i32 %X) nounwind {
205 ; CHECK-LABEL: test_urem_one:
207 ; CHECK-NEXT: mov w0, #1 // =0x1
209 %urem = urem i32 %X, 1
210 %cmp = icmp eq i32 %urem, 0
211 %ret = zext i1 %cmp to i32
215 ; We can lower remainder of division by powers of two much better elsewhere.
216 define i32 @test_urem_pow2(i32 %X) nounwind {
217 ; CHECK-LABEL: test_urem_pow2:
219 ; CHECK-NEXT: tst w0, #0xf
220 ; CHECK-NEXT: cset w0, eq
222 %urem = urem i32 %X, 16
223 %cmp = icmp eq i32 %urem, 0
224 %ret = zext i1 %cmp to i32
228 ; The fold is only valid for positive divisors, and we can't negate INT_MIN.
229 define i32 @test_urem_int_min(i32 %X) nounwind {
230 ; CHECK-LABEL: test_urem_int_min:
232 ; CHECK-NEXT: tst w0, #0x7fffffff
233 ; CHECK-NEXT: cset w0, eq
235 %urem = urem i32 %X, 2147483648
236 %cmp = icmp eq i32 %urem, 0
237 %ret = zext i1 %cmp to i32
241 ; We can lower remainder of division by all-ones much better elsewhere.
242 define i32 @test_urem_allones(i32 %X) nounwind {
243 ; CHECK-LABEL: test_urem_allones:
245 ; CHECK-NEXT: neg w8, w0
246 ; CHECK-NEXT: cmp w8, #2
247 ; CHECK-NEXT: cset w0, lo
249 %urem = urem i32 %X, 4294967295
250 %cmp = icmp eq i32 %urem, 0
251 %ret = zext i1 %cmp to i32