121
|
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
3
|
|
4 ; If the (shl x, C) preserved the sign and this is a sign test,
|
|
5 ; compare the LHS operand instead
|
|
6
|
|
7 define i1 @icmp_shl_nsw_sgt(i32 %x) {
|
|
8 ; CHECK-LABEL: @icmp_shl_nsw_sgt(
|
|
9 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 %x, 0
|
|
10 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
11 ;
|
|
12 %shl = shl nsw i32 %x, 21
|
|
13 %cmp = icmp sgt i32 %shl, 0
|
|
14 ret i1 %cmp
|
|
15 }
|
|
16
|
|
17 define i1 @icmp_shl_nsw_sge0(i32 %x) {
|
|
18 ; CHECK-LABEL: @icmp_shl_nsw_sge0(
|
|
19 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 %x, -1
|
|
20 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
21 ;
|
|
22 %shl = shl nsw i32 %x, 21
|
|
23 %cmp = icmp sge i32 %shl, 0
|
|
24 ret i1 %cmp
|
|
25 }
|
|
26
|
|
27 define i1 @icmp_shl_nsw_sge1(i32 %x) {
|
|
28 ; CHECK-LABEL: @icmp_shl_nsw_sge1(
|
|
29 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 %x, 0
|
|
30 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
31 ;
|
|
32 %shl = shl nsw i32 %x, 21
|
|
33 %cmp = icmp sge i32 %shl, 1
|
|
34 ret i1 %cmp
|
|
35 }
|
|
36
|
|
37 define <2 x i1> @icmp_shl_nsw_sge1_vec(<2 x i32> %x) {
|
|
38 ; CHECK-LABEL: @icmp_shl_nsw_sge1_vec(
|
|
39 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> %x, zeroinitializer
|
|
40 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
41 ;
|
|
42 %shl = shl nsw <2 x i32> %x, <i32 21, i32 21>
|
|
43 %cmp = icmp sge <2 x i32> %shl, <i32 1, i32 1>
|
|
44 ret <2 x i1> %cmp
|
|
45 }
|
|
46
|
|
47 ; Checks for icmp (eq|ne) (shl x, C), 0
|
|
48
|
|
49 define i1 @icmp_shl_nsw_eq(i32 %x) {
|
|
50 ; CHECK-LABEL: @icmp_shl_nsw_eq(
|
|
51 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %x, 0
|
|
52 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
53 ;
|
|
54 %mul = shl nsw i32 %x, 5
|
|
55 %cmp = icmp eq i32 %mul, 0
|
|
56 ret i1 %cmp
|
|
57 }
|
|
58
|
|
59 define <2 x i1> @icmp_shl_nsw_eq_vec(<2 x i32> %x) {
|
|
60 ; CHECK-LABEL: @icmp_shl_nsw_eq_vec(
|
|
61 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> %x, zeroinitializer
|
|
62 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
63 ;
|
|
64 %mul = shl nsw <2 x i32> %x, <i32 5, i32 5>
|
|
65 %cmp = icmp eq <2 x i32> %mul, zeroinitializer
|
|
66 ret <2 x i1> %cmp
|
|
67 }
|
|
68
|
|
69 ; icmp sgt with shl nsw with a constant compare operand and constant
|
|
70 ; shift amount can always be reduced to icmp sgt alone.
|
|
71
|
|
72 ; Known bits analysis turns this into an equality predicate.
|
|
73
|
|
74 define i1 @icmp_sgt1(i8 %x) {
|
|
75 ; CHECK-LABEL: @icmp_sgt1(
|
|
76 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %x, -64
|
|
77 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
78 ;
|
|
79 %shl = shl nsw i8 %x, 1
|
|
80 %cmp = icmp sgt i8 %shl, -128
|
|
81 ret i1 %cmp
|
|
82 }
|
|
83
|
|
84 define i1 @icmp_sgt2(i8 %x) {
|
|
85 ; CHECK-LABEL: @icmp_sgt2(
|
|
86 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -64
|
|
87 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
88 ;
|
|
89 %shl = shl nsw i8 %x, 1
|
|
90 %cmp = icmp sgt i8 %shl, -127
|
|
91 ret i1 %cmp
|
|
92 }
|
|
93
|
|
94 define i1 @icmp_sgt3(i8 %x) {
|
|
95 ; CHECK-LABEL: @icmp_sgt3(
|
|
96 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -8
|
|
97 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
98 ;
|
|
99 %shl = shl nsw i8 %x, 1
|
|
100 %cmp = icmp sgt i8 %shl, -16
|
|
101 ret i1 %cmp
|
|
102 }
|
|
103
|
|
104 define i1 @icmp_sgt4(i8 %x) {
|
|
105 ; CHECK-LABEL: @icmp_sgt4(
|
|
106 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -1
|
|
107 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
108 ;
|
|
109 %shl = shl nsw i8 %x, 1
|
|
110 %cmp = icmp sgt i8 %shl, -2
|
|
111 ret i1 %cmp
|
|
112 }
|
|
113
|
|
114 ; x >s -1 is a sign bit test.
|
|
115 ; x >s 0 is a sign bit test.
|
|
116
|
|
117 define i1 @icmp_sgt5(i8 %x) {
|
|
118 ; CHECK-LABEL: @icmp_sgt5(
|
|
119 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, 0
|
|
120 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
121 ;
|
|
122 %shl = shl nsw i8 %x, 1
|
|
123 %cmp = icmp sgt i8 %shl, 1
|
|
124 ret i1 %cmp
|
|
125 }
|
|
126
|
|
127 define i1 @icmp_sgt6(i8 %x) {
|
|
128 ; CHECK-LABEL: @icmp_sgt6(
|
|
129 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, 8
|
|
130 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
131 ;
|
|
132 %shl = shl nsw i8 %x, 1
|
|
133 %cmp = icmp sgt i8 %shl, 16
|
|
134 ret i1 %cmp
|
|
135 }
|
|
136
|
|
137 define i1 @icmp_sgt7(i8 %x) {
|
|
138 ; CHECK-LABEL: @icmp_sgt7(
|
|
139 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, 62
|
|
140 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
141 ;
|
|
142 %shl = shl nsw i8 %x, 1
|
|
143 %cmp = icmp sgt i8 %shl, 124
|
|
144 ret i1 %cmp
|
|
145 }
|
|
146
|
|
147 ; Known bits analysis turns this into an equality predicate.
|
|
148
|
|
149 define i1 @icmp_sgt8(i8 %x) {
|
|
150 ; CHECK-LABEL: @icmp_sgt8(
|
|
151 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %x, 63
|
|
152 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
153 ;
|
|
154 %shl = shl nsw i8 %x, 1
|
|
155 %cmp = icmp sgt i8 %shl, 125
|
|
156 ret i1 %cmp
|
|
157 }
|
|
158
|
|
159 ; Compares with 126 and 127 are recognized as always false.
|
|
160
|
|
161 ; Known bits analysis turns this into an equality predicate.
|
|
162
|
|
163 define i1 @icmp_sgt9(i8 %x) {
|
|
164 ; CHECK-LABEL: @icmp_sgt9(
|
|
165 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %x, -1
|
|
166 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
167 ;
|
|
168 %shl = shl nsw i8 %x, 7
|
|
169 %cmp = icmp sgt i8 %shl, -128
|
|
170 ret i1 %cmp
|
|
171 }
|
|
172
|
|
173 define i1 @icmp_sgt10(i8 %x) {
|
|
174 ; CHECK-LABEL: @icmp_sgt10(
|
|
175 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -1
|
|
176 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
177 ;
|
|
178 %shl = shl nsw i8 %x, 7
|
|
179 %cmp = icmp sgt i8 %shl, -127
|
|
180 ret i1 %cmp
|
|
181 }
|
|
182
|
|
183 define i1 @icmp_sgt11(i8 %x) {
|
|
184 ; CHECK-LABEL: @icmp_sgt11(
|
|
185 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -1
|
|
186 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
187 ;
|
|
188 %shl = shl nsw i8 %x, 7
|
|
189 %cmp = icmp sgt i8 %shl, -2
|
|
190 ret i1 %cmp
|
|
191 }
|
|
192
|
|
193 ; Splat vector version should fold the same way.
|
|
194
|
|
195 define <2 x i1> @icmp_sgt11_vec(<2 x i8> %x) {
|
|
196 ; CHECK-LABEL: @icmp_sgt11_vec(
|
|
197 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>
|
|
198 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
199 ;
|
|
200 %shl = shl nsw <2 x i8> %x, <i8 7, i8 7>
|
|
201 %cmp = icmp sgt <2 x i8> %shl, <i8 -2, i8 -2>
|
|
202 ret <2 x i1> %cmp
|
|
203 }
|
|
204
|
|
205 ; Known bits analysis returns false for compares with >=0.
|
|
206
|
|
207 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
208 ;
|
|
209 ; Repeat the shl nsw + sgt tests with predicate changed to 'sle'.
|
|
210 ;
|
|
211 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
212
|
|
213 ; Known bits analysis turns this into an equality predicate.
|
|
214
|
|
215 define i1 @icmp_sle1(i8 %x) {
|
|
216 ; CHECK-LABEL: @icmp_sle1(
|
|
217 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %x, -64
|
|
218 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
219 ;
|
|
220 %shl = shl nsw i8 %x, 1
|
|
221 %cmp = icmp sle i8 %shl, -128
|
|
222 ret i1 %cmp
|
|
223 }
|
|
224
|
|
225 define i1 @icmp_sle2(i8 %x) {
|
|
226 ; CHECK-LABEL: @icmp_sle2(
|
|
227 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, -63
|
|
228 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
229 ;
|
|
230 %shl = shl nsw i8 %x, 1
|
|
231 %cmp = icmp sle i8 %shl, -127
|
|
232 ret i1 %cmp
|
|
233 }
|
|
234
|
|
235 define i1 @icmp_sle3(i8 %x) {
|
|
236 ; CHECK-LABEL: @icmp_sle3(
|
|
237 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, -7
|
|
238 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
239 ;
|
|
240 %shl = shl nsw i8 %x, 1
|
|
241 %cmp = icmp sle i8 %shl, -16
|
|
242 ret i1 %cmp
|
|
243 }
|
|
244
|
|
245 define i1 @icmp_sle4(i8 %x) {
|
|
246 ; CHECK-LABEL: @icmp_sle4(
|
|
247 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 0
|
|
248 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
249 ;
|
|
250 %shl = shl nsw i8 %x, 1
|
|
251 %cmp = icmp sle i8 %shl, -2
|
|
252 ret i1 %cmp
|
|
253 }
|
|
254
|
|
255 ; x <=s -1 is a sign bit test.
|
|
256 ; x <=s 0 is a sign bit test.
|
|
257
|
|
258 define i1 @icmp_sle5(i8 %x) {
|
|
259 ; CHECK-LABEL: @icmp_sle5(
|
|
260 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 1
|
|
261 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
262 ;
|
|
263 %shl = shl nsw i8 %x, 1
|
|
264 %cmp = icmp sle i8 %shl, 1
|
|
265 ret i1 %cmp
|
|
266 }
|
|
267
|
|
268 define i1 @icmp_sle6(i8 %x) {
|
|
269 ; CHECK-LABEL: @icmp_sle6(
|
|
270 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 9
|
|
271 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
272 ;
|
|
273 %shl = shl nsw i8 %x, 1
|
|
274 %cmp = icmp sle i8 %shl, 16
|
|
275 ret i1 %cmp
|
|
276 }
|
|
277
|
|
278 define i1 @icmp_sle7(i8 %x) {
|
|
279 ; CHECK-LABEL: @icmp_sle7(
|
|
280 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 63
|
|
281 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
282 ;
|
|
283 %shl = shl nsw i8 %x, 1
|
|
284 %cmp = icmp sle i8 %shl, 124
|
|
285 ret i1 %cmp
|
|
286 }
|
|
287
|
|
288 ; Known bits analysis turns this into an equality predicate.
|
|
289
|
|
290 define i1 @icmp_sle8(i8 %x) {
|
|
291 ; CHECK-LABEL: @icmp_sle8(
|
|
292 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %x, 63
|
|
293 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
294 ;
|
|
295 %shl = shl nsw i8 %x, 1
|
|
296 %cmp = icmp sle i8 %shl, 125
|
|
297 ret i1 %cmp
|
|
298 }
|
|
299
|
|
300 ; Compares with 126 and 127 are recognized as always true.
|
|
301
|
|
302 ; Known bits analysis turns this into an equality predicate.
|
|
303
|
|
304 define i1 @icmp_sle9(i8 %x) {
|
|
305 ; CHECK-LABEL: @icmp_sle9(
|
|
306 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %x, -1
|
|
307 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
308 ;
|
|
309 %shl = shl nsw i8 %x, 7
|
|
310 %cmp = icmp sle i8 %shl, -128
|
|
311 ret i1 %cmp
|
|
312 }
|
|
313
|
|
314 define i1 @icmp_sle10(i8 %x) {
|
|
315 ; CHECK-LABEL: @icmp_sle10(
|
|
316 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 0
|
|
317 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
318 ;
|
|
319 %shl = shl nsw i8 %x, 7
|
|
320 %cmp = icmp sle i8 %shl, -127
|
|
321 ret i1 %cmp
|
|
322 }
|
|
323
|
|
324 define i1 @icmp_sle11(i8 %x) {
|
|
325 ; CHECK-LABEL: @icmp_sle11(
|
|
326 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 0
|
|
327 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
328 ;
|
|
329 %shl = shl nsw i8 %x, 7
|
|
330 %cmp = icmp sle i8 %shl, -2
|
|
331 ret i1 %cmp
|
|
332 }
|
|
333
|
|
334 ; Some of the earlier sgt/sle tests are transformed to eq/ne, but try a couple
|
|
335 ; of those explicitly, so we know no intermediate transforms are necessary.
|
|
336
|
|
337 define i1 @icmp_eq1(i8 %x) {
|
|
338 ; CHECK-LABEL: @icmp_eq1(
|
|
339 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %x, 6
|
|
340 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
341 ;
|
|
342 %shl = shl nsw i8 %x, 1
|
|
343 %cmp = icmp eq i8 %shl, 12
|
|
344 ret i1 %cmp
|
|
345 }
|
|
346
|
|
347 define i1 @icmp_ne1(i8 %x) {
|
|
348 ; CHECK-LABEL: @icmp_ne1(
|
|
349 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %x, -2
|
|
350 ; CHECK-NEXT: ret i1 [[CMP]]
|
|
351 ;
|
|
352 %shl = shl nsw i8 %x, 6
|
|
353 %cmp = icmp ne i8 %shl, -128
|
|
354 ret i1 %cmp
|
|
355 }
|
|
356
|