1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
7 ; Where Y is checking that all the high bits (covered by a mask 4294967168)
8 ; are uniform, i.e. %arg & 4294967168 can be either 4294967168 or 0
9 ; Pattern can be one of:
10 ; %t = add i32 %arg, 128
11 ; %r = icmp ult i32 %t, 256
13 ; %t0 = shl i32 %arg, 24
14 ; %t1 = ashr i32 %t0, 24
15 ; %r = icmp eq i32 %t1, %arg
17 ; %t0 = trunc i32 %arg to i8
18 ; %t1 = sext i8 %t0 to i32
19 ; %r = icmp eq i32 %t1, %arg
20 ; This pattern is a signed truncation check.
22 ; And X is checking that some bit in that same mask is zero.
24 ; %r = icmp sgt i32 %arg, -1
26 ; %t = and i32 %arg, 2147483648
27 ; %r = icmp eq i32 %t, 0
29 ; Since we are checking that all the bits in that mask are the same,
30 ; and a particular bit is zero, what we are really checking is that all the
31 ; masked bits are zero.
32 ; So this should be transformed to:
33 ; %r = icmp ult i32 %arg, 128
35 ; ============================================================================ ;
37 ; ============================================================================ ;
39 define i1 @positive_with_signbit(i32 %arg) {
40 ; CHECK-LABEL: @positive_with_signbit(
41 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
42 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
44 %t1 = icmp sgt i32 %arg, -1
45 %t2 = add i32 %arg, 128
46 %t3 = icmp ult i32 %t2, 256
51 define i1 @positive_with_signbit_logical(i32 %arg) {
52 ; CHECK-LABEL: @positive_with_signbit_logical(
53 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
54 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
56 %t1 = icmp sgt i32 %arg, -1
57 %t2 = add i32 %arg, 128
58 %t3 = icmp ult i32 %t2, 256
59 %t4 = select i1 %t1, i1 %t3, i1 false
63 define i1 @positive_with_mask(i32 %arg) {
64 ; CHECK-LABEL: @positive_with_mask(
65 ; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
66 ; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]
68 %t1 = and i32 %arg, 1107296256
69 %t2 = icmp eq i32 %t1, 0
70 %t3 = add i32 %arg, 128
71 %t4 = icmp ult i32 %t3, 256
76 define i1 @positive_with_mask_logical(i32 %arg) {
77 ; CHECK-LABEL: @positive_with_mask_logical(
78 ; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
79 ; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]
81 %t1 = and i32 %arg, 1107296256
82 %t2 = icmp eq i32 %t1, 0
83 %t3 = add i32 %arg, 128
84 %t4 = icmp ult i32 %t3, 256
85 %t5 = select i1 %t2, i1 %t4, i1 false
89 define i1 @positive_with_icmp(i32 %arg) {
90 ; CHECK-LABEL: @positive_with_icmp(
91 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
92 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
94 %t1 = icmp ult i32 %arg, 512
95 %t2 = add i32 %arg, 128
96 %t3 = icmp ult i32 %t2, 256
101 define i1 @positive_with_icmp_logical(i32 %arg) {
102 ; CHECK-LABEL: @positive_with_icmp_logical(
103 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
104 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
106 %t1 = icmp ult i32 %arg, 512
107 %t2 = add i32 %arg, 128
108 %t3 = icmp ult i32 %t2, 256
109 %t4 = select i1 %t1, i1 %t3, i1 false
114 define i1 @positive_with_aggressive_icmp(i32 %arg) {
115 ; CHECK-LABEL: @positive_with_aggressive_icmp(
116 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
117 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
119 %t1 = icmp ult i32 %arg, 128
120 %t2 = add i32 %arg, 256
121 %t3 = icmp ult i32 %t2, 512
122 %t4 = and i1 %t1, %t3
126 define i1 @positive_with_aggressive_icmp_logical(i32 %arg) {
127 ; CHECK-LABEL: @positive_with_aggressive_icmp_logical(
128 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
129 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
131 %t1 = icmp ult i32 %arg, 128
132 %t2 = add i32 %arg, 256
133 %t3 = icmp ult i32 %t2, 512
134 %t4 = select i1 %t1, i1 %t3, i1 false
138 ; I'm sure there is a bunch more patterns possible :/
140 ; This used to trigger an assert, because the icmp's are not direct
141 ; operands of the and.
142 define i1 @positive_with_extra_and(i32 %arg, i1 %z) {
143 ; CHECK-LABEL: @positive_with_extra_and(
144 ; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
145 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[T5_SIMPLIFIED]], [[Z:%.*]]
146 ; CHECK-NEXT: ret i1 [[TMP1]]
148 %t1 = icmp sgt i32 %arg, -1
149 %t2 = add i32 %arg, 128
150 %t3 = icmp ult i32 %t2, 256
152 %t5 = and i1 %t3, %t4
156 define i1 @positive_with_extra_and_logical(i32 %arg, i1 %z) {
157 ; CHECK-LABEL: @positive_with_extra_and_logical(
158 ; CHECK-NEXT: [[DOTSIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
159 ; CHECK-NEXT: [[T5:%.*]] = select i1 [[DOTSIMPLIFIED]], i1 [[Z:%.*]], i1 false
160 ; CHECK-NEXT: ret i1 [[T5]]
162 %t1 = icmp sgt i32 %arg, -1
163 %t2 = add i32 %arg, 128
164 %t3 = icmp ult i32 %t2, 256
165 %t4 = select i1 %t1, i1 %z, i1 false
166 %t5 = select i1 %t3, i1 %t4, i1 false
170 ; ============================================================================ ;
172 ; ============================================================================ ;
174 define <2 x i1> @positive_vec_splat(<2 x i32> %arg) {
175 ; CHECK-LABEL: @positive_vec_splat(
176 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <2 x i32> [[ARG:%.*]], <i32 128, i32 128>
177 ; CHECK-NEXT: ret <2 x i1> [[T4_SIMPLIFIED]]
179 %t1 = icmp sgt <2 x i32> %arg, <i32 -1, i32 -1>
180 %t2 = add <2 x i32> %arg, <i32 128, i32 128>
181 %t3 = icmp ult <2 x i32> %t2, <i32 256, i32 256>
182 %t4 = and <2 x i1> %t1, %t3
186 define <2 x i1> @positive_vec_nonsplat(<2 x i32> %arg) {
187 ; CHECK-LABEL: @positive_vec_nonsplat(
188 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt <2 x i32> [[ARG:%.*]], <i32 -1, i32 -1>
189 ; CHECK-NEXT: [[T2:%.*]] = add <2 x i32> [[ARG]], <i32 128, i32 256>
190 ; CHECK-NEXT: [[T3:%.*]] = icmp ult <2 x i32> [[T2]], <i32 256, i32 512>
191 ; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T1]], [[T3]]
192 ; CHECK-NEXT: ret <2 x i1> [[T4]]
194 %t1 = icmp sgt <2 x i32> %arg, <i32 -1, i32 -1>
195 %t2 = add <2 x i32> %arg, <i32 128, i32 256>
196 %t3 = icmp ult <2 x i32> %t2, <i32 256, i32 512>
197 %t4 = and <2 x i1> %t1, %t3
201 define <3 x i1> @positive_vec_undef0(<3 x i32> %arg) {
202 ; CHECK-LABEL: @positive_vec_undef0(
203 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 undef, i32 -1>
204 ; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 128, i32 128>
205 ; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 256, i32 256>
206 ; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
207 ; CHECK-NEXT: ret <3 x i1> [[T4]]
209 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 undef, i32 -1>
210 %t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
211 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 256, i32 256>
212 %t4 = and <3 x i1> %t1, %t3
216 define <3 x i1> @positive_vec_undef1(<3 x i32> %arg) {
217 ; CHECK-LABEL: @positive_vec_undef1(
218 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 -1, i32 -1>
219 ; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 undef, i32 128>
220 ; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 256, i32 256>
221 ; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
222 ; CHECK-NEXT: ret <3 x i1> [[T4]]
224 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
225 %t2 = add <3 x i32> %arg, <i32 128, i32 undef, i32 128>
226 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 256, i32 256>
227 %t4 = and <3 x i1> %t1, %t3
231 define <3 x i1> @positive_vec_undef2(<3 x i32> %arg) {
232 ; CHECK-LABEL: @positive_vec_undef2(
233 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 -1, i32 -1>
234 ; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 128, i32 128>
235 ; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 undef, i32 256>
236 ; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
237 ; CHECK-NEXT: ret <3 x i1> [[T4]]
239 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
240 %t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
241 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 undef, i32 256>
242 %t4 = and <3 x i1> %t1, %t3
246 define <3 x i1> @positive_vec_undef3(<3 x i32> %arg) {
247 ; CHECK-LABEL: @positive_vec_undef3(
248 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 undef, i32 -1>
249 ; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 undef, i32 128>
250 ; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 256, i32 256>
251 ; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
252 ; CHECK-NEXT: ret <3 x i1> [[T4]]
254 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 undef, i32 -1>
255 %t2 = add <3 x i32> %arg, <i32 128, i32 undef, i32 128>
256 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 256, i32 256>
257 %t4 = and <3 x i1> %t1, %t3
261 define <3 x i1> @positive_vec_undef4(<3 x i32> %arg) {
262 ; CHECK-LABEL: @positive_vec_undef4(
263 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 undef, i32 -1>
264 ; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 128, i32 128>
265 ; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 undef, i32 256>
266 ; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
267 ; CHECK-NEXT: ret <3 x i1> [[T4]]
269 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 undef, i32 -1>
270 %t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
271 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 undef, i32 256>
272 %t4 = and <3 x i1> %t1, %t3
276 define <3 x i1> @positive_vec_undef5(<3 x i32> %arg) {
277 ; CHECK-LABEL: @positive_vec_undef5(
278 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 -1, i32 -1>
279 ; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 undef, i32 128>
280 ; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 undef, i32 256>
281 ; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
282 ; CHECK-NEXT: ret <3 x i1> [[T4]]
284 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
285 %t2 = add <3 x i32> %arg, <i32 128, i32 undef, i32 128>
286 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 undef, i32 256>
287 %t4 = and <3 x i1> %t1, %t3
291 define <3 x i1> @positive_vec_undef6(<3 x i32> %arg) {
292 ; CHECK-LABEL: @positive_vec_undef6(
293 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 undef, i32 -1>
294 ; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 undef, i32 128>
295 ; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 undef, i32 256>
296 ; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
297 ; CHECK-NEXT: ret <3 x i1> [[T4]]
299 %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 undef, i32 -1>
300 %t2 = add <3 x i32> %arg, <i32 128, i32 undef, i32 128>
301 %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 undef, i32 256>
302 %t4 = and <3 x i1> %t1, %t3
306 ; ============================================================================ ;
307 ; Commutativity tests.
308 ; ============================================================================ ;
312 define i1 @commutative() {
313 ; CHECK-LABEL: @commutative(
314 ; CHECK-NEXT: [[ARG:%.*]] = call i32 @gen32()
315 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
316 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
318 %arg = call i32 @gen32()
319 %t1 = icmp sgt i32 %arg, -1
320 %t2 = add i32 %arg, 128
321 %t3 = icmp ult i32 %t2, 256
322 %t4 = and i1 %t3, %t1 ; swapped order
326 define i1 @commutative_logical() {
327 ; CHECK-LABEL: @commutative_logical(
328 ; CHECK-NEXT: [[ARG:%.*]] = call i32 @gen32()
329 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
330 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
332 %arg = call i32 @gen32()
333 %t1 = icmp sgt i32 %arg, -1
334 %t2 = add i32 %arg, 128
335 %t3 = icmp ult i32 %t2, 256
336 %t4 = select i1 %t3, i1 %t1, i1 false ; swapped order
340 define i1 @commutative_with_icmp() {
341 ; CHECK-LABEL: @commutative_with_icmp(
342 ; CHECK-NEXT: [[ARG:%.*]] = call i32 @gen32()
343 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
344 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
346 %arg = call i32 @gen32()
347 %t1 = icmp ult i32 %arg, 512
348 %t2 = add i32 %arg, 128
349 %t3 = icmp ult i32 %t2, 256
350 %t4 = and i1 %t3, %t1 ; swapped order
354 define i1 @commutative_with_icmp_logical() {
355 ; CHECK-LABEL: @commutative_with_icmp_logical(
356 ; CHECK-NEXT: [[ARG:%.*]] = call i32 @gen32()
357 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
358 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
360 %arg = call i32 @gen32()
361 %t1 = icmp ult i32 %arg, 512
362 %t2 = add i32 %arg, 128
363 %t3 = icmp ult i32 %t2, 256
364 %t4 = select i1 %t3, i1 %t1, i1 false ; swapped order
368 ; ============================================================================ ;
370 ; ============================================================================ ;
372 define i1 @positive_trunc_signbit(i32 %arg) {
373 ; CHECK-LABEL: @positive_trunc_signbit(
374 ; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
375 ; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]
377 %t1 = trunc i32 %arg to i8
378 %t2 = icmp sgt i8 %t1, -1
379 %t3 = add i32 %arg, 128
380 %t4 = icmp ult i32 %t3, 256
381 %t5 = and i1 %t2, %t4
385 define i1 @positive_trunc_signbit_logical(i32 %arg) {
386 ; CHECK-LABEL: @positive_trunc_signbit_logical(
387 ; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
388 ; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]
390 %t1 = trunc i32 %arg to i8
391 %t2 = icmp sgt i8 %t1, -1
392 %t3 = add i32 %arg, 128
393 %t4 = icmp ult i32 %t3, 256
394 %t5 = select i1 %t2, i1 %t4, i1 false
398 define i1 @positive_trunc_base(i32 %arg) {
399 ; CHECK-LABEL: @positive_trunc_base(
400 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i16
401 ; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i16 [[T1]], 128
402 ; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]
404 %t1 = trunc i32 %arg to i16
405 %t2 = icmp sgt i16 %t1, -1
406 %t3 = add i16 %t1, 128
407 %t4 = icmp ult i16 %t3, 256
408 %t5 = and i1 %t2, %t4
412 define i1 @positive_trunc_base_logical(i32 %arg) {
413 ; CHECK-LABEL: @positive_trunc_base_logical(
414 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i16
415 ; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i16 [[T1]], 128
416 ; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]
418 %t1 = trunc i32 %arg to i16
419 %t2 = icmp sgt i16 %t1, -1
420 %t3 = add i16 %t1, 128
421 %t4 = icmp ult i16 %t3, 256
422 %t5 = select i1 %t2, i1 %t4, i1 false
426 define i1 @positive_different_trunc_both(i32 %arg) {
427 ; CHECK-LABEL: @positive_different_trunc_both(
428 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i15
429 ; CHECK-NEXT: [[T2:%.*]] = icmp sgt i15 [[T1]], -1
430 ; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[ARG]] to i16
431 ; CHECK-NEXT: [[T4:%.*]] = add i16 [[T3]], 128
432 ; CHECK-NEXT: [[T5:%.*]] = icmp ult i16 [[T4]], 256
433 ; CHECK-NEXT: [[T6:%.*]] = and i1 [[T2]], [[T5]]
434 ; CHECK-NEXT: ret i1 [[T6]]
436 %t1 = trunc i32 %arg to i15
437 %t2 = icmp sgt i15 %t1, -1
438 %t3 = trunc i32 %arg to i16
439 %t4 = add i16 %t3, 128
440 %t5 = icmp ult i16 %t4, 256
441 %t6 = and i1 %t2, %t5
445 define i1 @positive_different_trunc_both_logical(i32 %arg) {
446 ; CHECK-LABEL: @positive_different_trunc_both_logical(
447 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i15
448 ; CHECK-NEXT: [[T2:%.*]] = icmp sgt i15 [[T1]], -1
449 ; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[ARG]] to i16
450 ; CHECK-NEXT: [[T4:%.*]] = add i16 [[T3]], 128
451 ; CHECK-NEXT: [[T5:%.*]] = icmp ult i16 [[T4]], 256
452 ; CHECK-NEXT: [[T6:%.*]] = select i1 [[T2]], i1 [[T5]], i1 false
453 ; CHECK-NEXT: ret i1 [[T6]]
455 %t1 = trunc i32 %arg to i15
456 %t2 = icmp sgt i15 %t1, -1
457 %t3 = trunc i32 %arg to i16
458 %t4 = add i16 %t3, 128
459 %t5 = icmp ult i16 %t4, 256
460 %t6 = select i1 %t2, i1 %t5, i1 false
464 ; ============================================================================ ;
467 ; We will only produce one instruction, so we do not care about one-use.
468 ; But, we *could* handle more patterns that we weren't able to canonicalize
469 ; because of extra-uses.
470 ; ============================================================================ ;
472 declare void @use32(i32)
473 declare void @use8(i8)
474 declare void @use1(i1)
476 define i1 @oneuse_with_signbit(i32 %arg) {
477 ; CHECK-LABEL: @oneuse_with_signbit(
478 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
479 ; CHECK-NEXT: call void @use1(i1 [[T1]])
480 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG]], 128
481 ; CHECK-NEXT: call void @use32(i32 [[T2]])
482 ; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256
483 ; CHECK-NEXT: call void @use1(i1 [[T3]])
484 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
485 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
487 %t1 = icmp sgt i32 %arg, -1
488 call void @use1(i1 %t1)
489 %t2 = add i32 %arg, 128
490 call void @use32(i32 %t2)
491 %t3 = icmp ult i32 %t2, 256
492 call void @use1(i1 %t3)
493 %t4 = and i1 %t1, %t3
497 define i1 @oneuse_with_signbit_logical(i32 %arg) {
498 ; CHECK-LABEL: @oneuse_with_signbit_logical(
499 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
500 ; CHECK-NEXT: call void @use1(i1 [[T1]])
501 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG]], 128
502 ; CHECK-NEXT: call void @use32(i32 [[T2]])
503 ; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256
504 ; CHECK-NEXT: call void @use1(i1 [[T3]])
505 ; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
506 ; CHECK-NEXT: ret i1 [[T4_SIMPLIFIED]]
508 %t1 = icmp sgt i32 %arg, -1
509 call void @use1(i1 %t1)
510 %t2 = add i32 %arg, 128
511 call void @use32(i32 %t2)
512 %t3 = icmp ult i32 %t2, 256
513 call void @use1(i1 %t3)
514 %t4 = select i1 %t1, i1 %t3, i1 false
518 define i1 @oneuse_with_mask(i32 %arg) {
519 ; CHECK-LABEL: @oneuse_with_mask(
520 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 603979776
521 ; CHECK-NEXT: call void @use32(i32 [[T1]])
522 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
523 ; CHECK-NEXT: call void @use1(i1 [[T2]])
524 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
525 ; CHECK-NEXT: call void @use32(i32 [[T3]])
526 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
527 ; CHECK-NEXT: call void @use1(i1 [[T4]])
528 ; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
529 ; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]
531 %t1 = and i32 %arg, 603979776 ; some bit within the target 4294967168 mask.
532 call void @use32(i32 %t1)
533 %t2 = icmp eq i32 %t1, 0
534 call void @use1(i1 %t2)
535 %t3 = add i32 %arg, 128
536 call void @use32(i32 %t3)
537 %t4 = icmp ult i32 %t3, 256
538 call void @use1(i1 %t4)
539 %t5 = and i1 %t2, %t4
543 define i1 @oneuse_with_mask_logical(i32 %arg) {
544 ; CHECK-LABEL: @oneuse_with_mask_logical(
545 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 603979776
546 ; CHECK-NEXT: call void @use32(i32 [[T1]])
547 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
548 ; CHECK-NEXT: call void @use1(i1 [[T2]])
549 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
550 ; CHECK-NEXT: call void @use32(i32 [[T3]])
551 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
552 ; CHECK-NEXT: call void @use1(i1 [[T4]])
553 ; CHECK-NEXT: [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
554 ; CHECK-NEXT: ret i1 [[T5_SIMPLIFIED]]
556 %t1 = and i32 %arg, 603979776 ; some bit within the target 4294967168 mask.
557 call void @use32(i32 %t1)
558 %t2 = icmp eq i32 %t1, 0
559 call void @use1(i1 %t2)
560 %t3 = add i32 %arg, 128
561 call void @use32(i32 %t3)
562 %t4 = icmp ult i32 %t3, 256
563 call void @use1(i1 %t4)
564 %t5 = select i1 %t2, i1 %t4, i1 false
568 define i1 @oneuse_shl_ashr(i32 %arg) {
569 ; CHECK-LABEL: @oneuse_shl_ashr(
570 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
571 ; CHECK-NEXT: call void @use8(i8 [[T1]])
572 ; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1
573 ; CHECK-NEXT: call void @use1(i1 [[T2]])
574 ; CHECK-NEXT: [[T3:%.*]] = shl i32 [[ARG]], 24
575 ; CHECK-NEXT: call void @use32(i32 [[T3]])
576 ; CHECK-NEXT: [[T4:%.*]] = ashr exact i32 [[T3]], 24
577 ; CHECK-NEXT: call void @use32(i32 [[T4]])
578 ; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
579 ; CHECK-NEXT: call void @use1(i1 [[T5]])
580 ; CHECK-NEXT: [[T6:%.*]] = and i1 [[T2]], [[T5]]
581 ; CHECK-NEXT: ret i1 [[T6]]
583 %t1 = trunc i32 %arg to i8
584 call void @use8(i8 %t1)
585 %t2 = icmp sgt i8 %t1, -1
586 call void @use1(i1 %t2)
587 %t3 = shl i32 %arg, 24
588 call void @use32(i32 %t3)
589 %t4 = ashr i32 %t3, 24
590 call void @use32(i32 %t4)
591 %t5 = icmp eq i32 %t4, %arg
592 call void @use1(i1 %t5)
593 %t6 = and i1 %t2, %t5
597 define i1 @oneuse_shl_ashr_logical(i32 %arg) {
598 ; CHECK-LABEL: @oneuse_shl_ashr_logical(
599 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
600 ; CHECK-NEXT: call void @use8(i8 [[T1]])
601 ; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1
602 ; CHECK-NEXT: call void @use1(i1 [[T2]])
603 ; CHECK-NEXT: [[T3:%.*]] = shl i32 [[ARG]], 24
604 ; CHECK-NEXT: call void @use32(i32 [[T3]])
605 ; CHECK-NEXT: [[T4:%.*]] = ashr exact i32 [[T3]], 24
606 ; CHECK-NEXT: call void @use32(i32 [[T4]])
607 ; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
608 ; CHECK-NEXT: call void @use1(i1 [[T5]])
609 ; CHECK-NEXT: [[T6:%.*]] = select i1 [[T2]], i1 [[T5]], i1 false
610 ; CHECK-NEXT: ret i1 [[T6]]
612 %t1 = trunc i32 %arg to i8
613 call void @use8(i8 %t1)
614 %t2 = icmp sgt i8 %t1, -1
615 call void @use1(i1 %t2)
616 %t3 = shl i32 %arg, 24
617 call void @use32(i32 %t3)
618 %t4 = ashr i32 %t3, 24
619 call void @use32(i32 %t4)
620 %t5 = icmp eq i32 %t4, %arg
621 call void @use1(i1 %t5)
622 %t6 = select i1 %t2, i1 %t5, i1 false
626 define zeroext i1 @oneuse_trunc_sext(i32 %arg) {
627 ; CHECK-LABEL: @oneuse_trunc_sext(
628 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
629 ; CHECK-NEXT: call void @use8(i8 [[T1]])
630 ; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1
631 ; CHECK-NEXT: call void @use1(i1 [[T2]])
632 ; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[ARG]] to i8
633 ; CHECK-NEXT: call void @use8(i8 [[T3]])
634 ; CHECK-NEXT: [[T4:%.*]] = sext i8 [[T3]] to i32
635 ; CHECK-NEXT: call void @use32(i32 [[T4]])
636 ; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
637 ; CHECK-NEXT: call void @use1(i1 [[T5]])
638 ; CHECK-NEXT: [[T6:%.*]] = and i1 [[T2]], [[T5]]
639 ; CHECK-NEXT: ret i1 [[T6]]
641 %t1 = trunc i32 %arg to i8
642 call void @use8(i8 %t1)
643 %t2 = icmp sgt i8 %t1, -1
644 call void @use1(i1 %t2)
645 %t3 = trunc i32 %arg to i8
646 call void @use8(i8 %t3)
647 %t4 = sext i8 %t3 to i32
648 call void @use32(i32 %t4)
649 %t5 = icmp eq i32 %t4, %arg
650 call void @use1(i1 %t5)
651 %t6 = and i1 %t2, %t5
655 define zeroext i1 @oneuse_trunc_sext_logical(i32 %arg) {
656 ; CHECK-LABEL: @oneuse_trunc_sext_logical(
657 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
658 ; CHECK-NEXT: call void @use8(i8 [[T1]])
659 ; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1
660 ; CHECK-NEXT: call void @use1(i1 [[T2]])
661 ; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[ARG]] to i8
662 ; CHECK-NEXT: call void @use8(i8 [[T3]])
663 ; CHECK-NEXT: [[T4:%.*]] = sext i8 [[T3]] to i32
664 ; CHECK-NEXT: call void @use32(i32 [[T4]])
665 ; CHECK-NEXT: [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
666 ; CHECK-NEXT: call void @use1(i1 [[T5]])
667 ; CHECK-NEXT: [[T6:%.*]] = select i1 [[T2]], i1 [[T5]], i1 false
668 ; CHECK-NEXT: ret i1 [[T6]]
670 %t1 = trunc i32 %arg to i8
671 call void @use8(i8 %t1)
672 %t2 = icmp sgt i8 %t1, -1
673 call void @use1(i1 %t2)
674 %t3 = trunc i32 %arg to i8
675 call void @use8(i8 %t3)
676 %t4 = sext i8 %t3 to i32
677 call void @use32(i32 %t4)
678 %t5 = icmp eq i32 %t4, %arg
679 call void @use1(i1 %t5)
680 %t6 = select i1 %t2, i1 %t5, i1 false
684 ; ============================================================================ ;
686 ; ============================================================================ ;
688 define i1 @negative_not_arg(i32 %arg, i32 %arg2) {
689 ; CHECK-LABEL: @negative_not_arg(
690 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
691 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG2:%.*]], 128
692 ; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256
693 ; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
694 ; CHECK-NEXT: ret i1 [[T4]]
696 %t1 = icmp sgt i32 %arg, -1
697 %t2 = add i32 %arg2, 128 ; not %arg
698 %t3 = icmp ult i32 %t2, 256
699 %t4 = and i1 %t1, %t3
703 define i1 @negative_not_arg_logical(i32 %arg, i32 %arg2) {
704 ; CHECK-LABEL: @negative_not_arg_logical(
705 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
706 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG2:%.*]], 128
707 ; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256
708 ; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i1 [[T3]], i1 false
709 ; CHECK-NEXT: ret i1 [[T4]]
711 %t1 = icmp sgt i32 %arg, -1
712 %t2 = add i32 %arg2, 128 ; not %arg
713 %t3 = icmp ult i32 %t2, 256
714 %t4 = select i1 %t1, i1 %t3, i1 false
718 define i1 @negative_trunc_not_arg(i32 %arg, i32 %arg2) {
719 ; CHECK-LABEL: @negative_trunc_not_arg(
720 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
721 ; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1
722 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
723 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
724 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
725 ; CHECK-NEXT: ret i1 [[T5]]
727 %t1 = trunc i32 %arg to i8
728 %t2 = icmp sgt i8 %t1, -1
729 %t3 = add i32 %arg2, 128 ; not %arg
730 %t4 = icmp ult i32 %t3, 256
731 %t5 = and i1 %t2, %t4
735 define i1 @negative_trunc_not_arg_logical(i32 %arg, i32 %arg2) {
736 ; CHECK-LABEL: @negative_trunc_not_arg_logical(
737 ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
738 ; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[T1]], -1
739 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
740 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
741 ; CHECK-NEXT: [[T5:%.*]] = select i1 [[T2]], i1 [[T4]], i1 false
742 ; CHECK-NEXT: ret i1 [[T5]]
744 %t1 = trunc i32 %arg to i8
745 %t2 = icmp sgt i8 %t1, -1
746 %t3 = add i32 %arg2, 128 ; not %arg
747 %t4 = icmp ult i32 %t3, 256
748 %t5 = select i1 %t2, i1 %t4, i1 false
752 define i1 @positive_with_mask_not_arg(i32 %arg, i32 %arg2) {
753 ; CHECK-LABEL: @positive_with_mask_not_arg(
754 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1140850688
755 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
756 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
757 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
758 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
759 ; CHECK-NEXT: ret i1 [[T5]]
761 %t1 = and i32 %arg, 1140850688
762 %t2 = icmp eq i32 %t1, 0
763 %t3 = add i32 %arg2, 128 ; not %arg
764 %t4 = icmp ult i32 %t3, 256
765 %t5 = and i1 %t2, %t4
769 define i1 @positive_with_mask_not_arg_logical(i32 %arg, i32 %arg2) {
770 ; CHECK-LABEL: @positive_with_mask_not_arg_logical(
771 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1140850688
772 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
773 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
774 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
775 ; CHECK-NEXT: [[T5:%.*]] = select i1 [[T2]], i1 [[T4]], i1 false
776 ; CHECK-NEXT: ret i1 [[T5]]
778 %t1 = and i32 %arg, 1140850688
779 %t2 = icmp eq i32 %t1, 0
780 %t3 = add i32 %arg2, 128 ; not %arg
781 %t4 = icmp ult i32 %t3, 256
782 %t5 = select i1 %t2, i1 %t4, i1 false
786 define i1 @negative_with_nonuniform_bad_mask(i32 %arg) {
787 ; CHECK-LABEL: @negative_with_nonuniform_bad_mask(
788 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1711276033
789 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
790 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
791 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
792 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
793 ; CHECK-NEXT: ret i1 [[T5]]
795 %t1 = and i32 %arg, 1711276033 ; lowest bit is set
796 %t2 = icmp eq i32 %t1, 0
797 %t3 = add i32 %arg, 128
798 %t4 = icmp ult i32 %t3, 256
799 %t5 = and i1 %t2, %t4
803 define i1 @negative_with_nonuniform_bad_mask_logical(i32 %arg) {
804 ; CHECK-LABEL: @negative_with_nonuniform_bad_mask_logical(
805 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1711276033
806 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
807 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
808 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
809 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
810 ; CHECK-NEXT: ret i1 [[T5]]
812 %t1 = and i32 %arg, 1711276033 ; lowest bit is set
813 %t2 = icmp eq i32 %t1, 0
814 %t3 = add i32 %arg, 128
815 %t4 = icmp ult i32 %t3, 256
816 %t5 = select i1 %t2, i1 %t4, i1 false
820 define i1 @negative_with_uniform_bad_mask(i32 %arg) {
821 ; CHECK-LABEL: @negative_with_uniform_bad_mask(
822 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], -16777152
823 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
824 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
825 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
826 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
827 ; CHECK-NEXT: ret i1 [[T5]]
829 %t1 = and i32 %arg, 4278190144 ; 7'th bit is set
830 %t2 = icmp eq i32 %t1, 0
831 %t3 = add i32 %arg, 128
832 %t4 = icmp ult i32 %t3, 256
833 %t5 = and i1 %t2, %t4
837 define i1 @negative_with_uniform_bad_mask_logical(i32 %arg) {
838 ; CHECK-LABEL: @negative_with_uniform_bad_mask_logical(
839 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], -16777152
840 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
841 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
842 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
843 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
844 ; CHECK-NEXT: ret i1 [[T5]]
846 %t1 = and i32 %arg, 4278190144 ; 7'th bit is set
847 %t2 = icmp eq i32 %t1, 0
848 %t3 = add i32 %arg, 128
849 %t4 = icmp ult i32 %t3, 256
850 %t5 = select i1 %t2, i1 %t4, i1 false
854 define i1 @negative_with_wrong_mask(i32 %arg) {
855 ; CHECK-LABEL: @negative_with_wrong_mask(
856 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1
857 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
858 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
859 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
860 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
861 ; CHECK-NEXT: ret i1 [[T5]]
863 %t1 = and i32 %arg, 1 ; not even checking the right mask
864 %t2 = icmp eq i32 %t1, 0
865 %t3 = add i32 %arg, 128
866 %t4 = icmp ult i32 %t3, 256
867 %t5 = and i1 %t2, %t4
871 define i1 @negative_with_wrong_mask_logical(i32 %arg) {
872 ; CHECK-LABEL: @negative_with_wrong_mask_logical(
873 ; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1
874 ; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
875 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
876 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
877 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
878 ; CHECK-NEXT: ret i1 [[T5]]
880 %t1 = and i32 %arg, 1 ; not even checking the right mask
881 %t2 = icmp eq i32 %t1, 0
882 %t3 = add i32 %arg, 128
883 %t4 = icmp ult i32 %t3, 256
884 %t5 = select i1 %t2, i1 %t4, i1 false
888 define i1 @negative_not_less_than(i32 %arg) {
889 ; CHECK-LABEL: @negative_not_less_than(
890 ; CHECK-NEXT: ret i1 false
892 %t1 = icmp sgt i32 %arg, -1
893 %t2 = add i32 %arg, 256 ; should be less than 256
894 %t3 = icmp ult i32 %t2, 256
895 %t4 = and i1 %t1, %t3
899 define i1 @negative_not_less_than_logical(i32 %arg) {
900 ; CHECK-LABEL: @negative_not_less_than_logical(
901 ; CHECK-NEXT: ret i1 false
903 %t1 = icmp sgt i32 %arg, -1
904 %t2 = add i32 %arg, 256 ; should be less than 256
905 %t3 = icmp ult i32 %t2, 256
906 %t4 = select i1 %t1, i1 %t3, i1 false
910 define i1 @negative_not_power_of_two(i32 %arg) {
911 ; CHECK-LABEL: @negative_not_power_of_two(
912 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
913 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG]], 255
914 ; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256
915 ; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
916 ; CHECK-NEXT: ret i1 [[T4]]
918 %t1 = icmp sgt i32 %arg, -1
919 %t2 = add i32 %arg, 255 ; should be power of two
920 %t3 = icmp ult i32 %t2, 256
921 %t4 = and i1 %t1, %t3
925 define i1 @negative_not_power_of_two_logical(i32 %arg) {
926 ; CHECK-LABEL: @negative_not_power_of_two_logical(
927 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
928 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG]], 255
929 ; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256
930 ; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
931 ; CHECK-NEXT: ret i1 [[T4]]
933 %t1 = icmp sgt i32 %arg, -1
934 %t2 = add i32 %arg, 255 ; should be power of two
935 %t3 = icmp ult i32 %t2, 256
936 %t4 = select i1 %t1, i1 %t3, i1 false
940 define i1 @negative_not_next_power_of_two(i32 %arg) {
941 ; CHECK-LABEL: @negative_not_next_power_of_two(
942 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
943 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG]], 64
944 ; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256
945 ; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
946 ; CHECK-NEXT: ret i1 [[T4]]
948 %t1 = icmp sgt i32 %arg, -1
949 %t2 = add i32 %arg, 64 ; should be 256 >> 1
950 %t3 = icmp ult i32 %t2, 256
951 %t4 = and i1 %t1, %t3
955 define i1 @negative_not_next_power_of_two_logical(i32 %arg) {
956 ; CHECK-LABEL: @negative_not_next_power_of_two_logical(
957 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
958 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[ARG]], 64
959 ; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 256
960 ; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
961 ; CHECK-NEXT: ret i1 [[T4]]
963 %t1 = icmp sgt i32 %arg, -1
964 %t2 = add i32 %arg, 64 ; should be 256 >> 1
965 %t3 = icmp ult i32 %t2, 256
966 %t4 = select i1 %t1, i1 %t3, i1 false
970 ; I don't think this can be folded, at least not into single instruction.
971 define i1 @two_signed_truncation_checks(i32 %arg) {
972 ; CHECK-LABEL: @two_signed_truncation_checks(
973 ; CHECK-NEXT: [[T1:%.*]] = add i32 [[ARG:%.*]], 512
974 ; CHECK-NEXT: [[T2:%.*]] = icmp ult i32 [[T1]], 1024
975 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
976 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
977 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
978 ; CHECK-NEXT: ret i1 [[T5]]
980 %t1 = add i32 %arg, 512
981 %t2 = icmp ult i32 %t1, 1024
982 %t3 = add i32 %arg, 128
983 %t4 = icmp ult i32 %t3, 256
984 %t5 = and i1 %t2, %t4
988 define i1 @two_signed_truncation_checks_logical(i32 %arg) {
989 ; CHECK-LABEL: @two_signed_truncation_checks_logical(
990 ; CHECK-NEXT: [[T1:%.*]] = add i32 [[ARG:%.*]], 512
991 ; CHECK-NEXT: [[T2:%.*]] = icmp ult i32 [[T1]], 1024
992 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
993 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
994 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
995 ; CHECK-NEXT: ret i1 [[T5]]
997 %t1 = add i32 %arg, 512
998 %t2 = icmp ult i32 %t1, 1024
999 %t3 = add i32 %arg, 128
1000 %t4 = icmp ult i32 %t3, 256
1001 %t5 = select i1 %t2, i1 %t4, i1 false
1005 define i1 @bad_trunc_stc(i32 %arg) {
1006 ; CHECK-LABEL: @bad_trunc_stc(
1007 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
1008 ; CHECK-NEXT: [[T2:%.*]] = trunc i32 [[ARG]] to i16
1009 ; CHECK-NEXT: [[T3:%.*]] = add i16 [[T2]], 128
1010 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i16 [[T3]], 256
1011 ; CHECK-NEXT: [[T5:%.*]] = and i1 [[T1]], [[T4]]
1012 ; CHECK-NEXT: ret i1 [[T5]]
1014 %t1 = icmp sgt i32 %arg, -1 ; checks a bit outside of the i16
1015 %t2 = trunc i32 %arg to i16
1016 %t3 = add i16 %t2, 128
1017 %t4 = icmp ult i16 %t3, 256
1018 %t5 = and i1 %t1, %t4
1022 define i1 @bad_trunc_stc_logical(i32 %arg) {
1023 ; CHECK-LABEL: @bad_trunc_stc_logical(
1024 ; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
1025 ; CHECK-NEXT: [[T2:%.*]] = trunc i32 [[ARG]] to i16
1026 ; CHECK-NEXT: [[T3:%.*]] = add i16 [[T2]], 128
1027 ; CHECK-NEXT: [[T4:%.*]] = icmp ult i16 [[T3]], 256
1028 ; CHECK-NEXT: [[T5:%.*]] = select i1 [[T1]], i1 [[T4]], i1 false
1029 ; CHECK-NEXT: ret i1 [[T5]]
1031 %t1 = icmp sgt i32 %arg, -1 ; checks a bit outside of the i16
1032 %t2 = trunc i32 %arg to i16
1033 %t3 = add i16 %t2, 128
1034 %t4 = icmp ult i16 %t3, 256
1035 %t5 = select i1 %t1, i1 %t4, i1 false