Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / signed-truncation-check.ll
blob7e762627e5ec029929d3b269a83fb81179f7323e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; General pattern:
5 ;   X & Y
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
12 ; Or
13 ;   %t0 = shl       i32 %arg,    24
14 ;   %t1 = ashr      i32 %t0,     24
15 ;   %r  = icmp  eq  i32 %t1,     %arg
16 ; Or
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.
23 ; I.e. can be one of:
24 ;   %r = icmp sgt i32   %arg,    -1
25 ; Or
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 ; ============================================================================ ;
36 ; Basic positive test
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
47   %t4 = and i1 %t1, %t3
48   ret i1 %t4
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
60   ret i1 %t4
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
72   %t5 = and i1 %t2, %t4
73   ret i1 %t5
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
86   ret i1 %t5
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
97   %t4 = and i1 %t1, %t3
98   ret i1 %t4
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
110   ret i1 %t4
113 ; Still the same
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
123   ret i1 %t4
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
135   ret i1 %t4
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:    [[T5:%.*]] = and i1 [[T5_SIMPLIFIED]], [[Z:%.*]]
146 ; CHECK-NEXT:    ret i1 [[T5]]
148   %t1 = icmp sgt i32 %arg, -1
149   %t2 = add i32 %arg, 128
150   %t3 = icmp ult i32 %t2, 256
151   %t4 = and i1 %t1, %z
152   %t5 = and i1 %t3, %t4
153   ret i1 %t5
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
167   ret i1 %t5
170 ; ============================================================================ ;
171 ; Vector tests
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
183   ret <2 x i1> %t4
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
198   ret <2 x i1> %t4
201 define <3 x i1> @positive_vec_poison0(<3 x i32> %arg) {
202 ; CHECK-LABEL: @positive_vec_poison0(
203 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
204 ; CHECK-NEXT:    ret <3 x i1> [[T4_SIMPLIFIED]]
206   %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
207   %t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
208   %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 256, i32 256>
209   %t4 = and <3 x i1> %t1, %t3
210   ret <3 x i1> %t4
213 define <3 x i1> @positive_vec_poison1(<3 x i32> %arg) {
214 ; CHECK-LABEL: @positive_vec_poison1(
215 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
216 ; CHECK-NEXT:    ret <3 x i1> [[T4_SIMPLIFIED]]
218   %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
219   %t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
220   %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 256, i32 256>
221   %t4 = and <3 x i1> %t1, %t3
222   ret <3 x i1> %t4
225 define <3 x i1> @positive_vec_poison2(<3 x i32> %arg) {
226 ; CHECK-LABEL: @positive_vec_poison2(
227 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
228 ; CHECK-NEXT:    ret <3 x i1> [[T4_SIMPLIFIED]]
230   %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
231   %t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
232   %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 poison, i32 256>
233   %t4 = and <3 x i1> %t1, %t3
234   ret <3 x i1> %t4
237 define <3 x i1> @positive_vec_poison3(<3 x i32> %arg) {
238 ; CHECK-LABEL: @positive_vec_poison3(
239 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
240 ; CHECK-NEXT:    ret <3 x i1> [[T4_SIMPLIFIED]]
242   %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
243   %t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
244   %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 256, i32 256>
245   %t4 = and <3 x i1> %t1, %t3
246   ret <3 x i1> %t4
249 define <3 x i1> @positive_vec_poison4(<3 x i32> %arg) {
250 ; CHECK-LABEL: @positive_vec_poison4(
251 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
252 ; CHECK-NEXT:    ret <3 x i1> [[T4_SIMPLIFIED]]
254   %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
255   %t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
256   %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 poison, i32 256>
257   %t4 = and <3 x i1> %t1, %t3
258   ret <3 x i1> %t4
261 define <3 x i1> @positive_vec_poison5(<3 x i32> %arg) {
262 ; CHECK-LABEL: @positive_vec_poison5(
263 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
264 ; CHECK-NEXT:    ret <3 x i1> [[T4_SIMPLIFIED]]
266   %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
267   %t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
268   %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 poison, i32 256>
269   %t4 = and <3 x i1> %t1, %t3
270   ret <3 x i1> %t4
273 define <3 x i1> @positive_vec_poison6(<3 x i32> %arg) {
274 ; CHECK-LABEL: @positive_vec_poison6(
275 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
276 ; CHECK-NEXT:    ret <3 x i1> [[T4_SIMPLIFIED]]
278   %t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
279   %t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
280   %t3 = icmp ult <3 x i32> %t2, <i32 256, i32 poison, i32 256>
281   %t4 = and <3 x i1> %t1, %t3
282   ret <3 x i1> %t4
285 ; ============================================================================ ;
286 ; Commutativity tests.
287 ; ============================================================================ ;
289 declare i32 @gen32()
291 define i1 @commutative() {
292 ; CHECK-LABEL: @commutative(
293 ; CHECK-NEXT:    [[ARG:%.*]] = call i32 @gen32()
294 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
295 ; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
297   %arg = call i32 @gen32()
298   %t1 = icmp sgt i32 %arg, -1
299   %t2 = add i32 %arg, 128
300   %t3 = icmp ult i32 %t2, 256
301   %t4 = and i1 %t3, %t1 ; swapped order
302   ret i1 %t4
305 define i1 @commutative_logical() {
306 ; CHECK-LABEL: @commutative_logical(
307 ; CHECK-NEXT:    [[ARG:%.*]] = call i32 @gen32()
308 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
309 ; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
311   %arg = call i32 @gen32()
312   %t1 = icmp sgt i32 %arg, -1
313   %t2 = add i32 %arg, 128
314   %t3 = icmp ult i32 %t2, 256
315   %t4 = select i1 %t3, i1 %t1, i1 false ; swapped order
316   ret i1 %t4
319 define i1 @commutative_with_icmp() {
320 ; CHECK-LABEL: @commutative_with_icmp(
321 ; CHECK-NEXT:    [[ARG:%.*]] = call i32 @gen32()
322 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
323 ; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
325   %arg = call i32 @gen32()
326   %t1 = icmp ult i32 %arg, 512
327   %t2 = add i32 %arg, 128
328   %t3 = icmp ult i32 %t2, 256
329   %t4 = and i1 %t3, %t1 ; swapped order
330   ret i1 %t4
333 define i1 @commutative_with_icmp_logical() {
334 ; CHECK-LABEL: @commutative_with_icmp_logical(
335 ; CHECK-NEXT:    [[ARG:%.*]] = call i32 @gen32()
336 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
337 ; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
339   %arg = call i32 @gen32()
340   %t1 = icmp ult i32 %arg, 512
341   %t2 = add i32 %arg, 128
342   %t3 = icmp ult i32 %t2, 256
343   %t4 = select i1 %t3, i1 %t1, i1 false ; swapped order
344   ret i1 %t4
347 ; ============================================================================ ;
348 ; Truncations.
349 ; ============================================================================ ;
351 define i1 @positive_trunc_signbit(i32 %arg) {
352 ; CHECK-LABEL: @positive_trunc_signbit(
353 ; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
354 ; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
356   %t1 = trunc i32 %arg to i8
357   %t2 = icmp sgt i8 %t1, -1
358   %t3 = add i32 %arg, 128
359   %t4 = icmp ult i32 %t3, 256
360   %t5 = and i1 %t2, %t4
361   ret i1 %t5
364 define i1 @positive_trunc_signbit_logical(i32 %arg) {
365 ; CHECK-LABEL: @positive_trunc_signbit_logical(
366 ; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
367 ; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
369   %t1 = trunc i32 %arg to i8
370   %t2 = icmp sgt i8 %t1, -1
371   %t3 = add i32 %arg, 128
372   %t4 = icmp ult i32 %t3, 256
373   %t5 = select i1 %t2, i1 %t4, i1 false
374   ret i1 %t5
377 define i1 @positive_trunc_base(i32 %arg) {
378 ; CHECK-LABEL: @positive_trunc_base(
379 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 65408
380 ; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp eq i32 [[TMP1]], 0
381 ; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
383   %t1 = trunc i32 %arg to i16
384   %t2 = icmp sgt i16 %t1, -1
385   %t3 = add i16 %t1, 128
386   %t4 = icmp ult i16 %t3, 256
387   %t5 = and i1 %t2, %t4
388   ret i1 %t5
391 define i1 @positive_trunc_base_logical(i32 %arg) {
392 ; CHECK-LABEL: @positive_trunc_base_logical(
393 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 65408
394 ; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp eq i32 [[TMP1]], 0
395 ; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
397   %t1 = trunc i32 %arg to i16
398   %t2 = icmp sgt i16 %t1, -1
399   %t3 = add i16 %t1, 128
400   %t4 = icmp ult i16 %t3, 256
401   %t5 = select i1 %t2, i1 %t4, i1 false
402   ret i1 %t5
405 define i1 @positive_different_trunc_both(i32 %arg) {
406 ; CHECK-LABEL: @positive_different_trunc_both(
407 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 16384
408 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[TMP1]], 0
409 ; CHECK-NEXT:    [[T3:%.*]] = trunc i32 [[ARG]] to i16
410 ; CHECK-NEXT:    [[T4:%.*]] = add i16 [[T3]], 128
411 ; CHECK-NEXT:    [[T5:%.*]] = icmp ult i16 [[T4]], 256
412 ; CHECK-NEXT:    [[T6:%.*]] = and i1 [[T2]], [[T5]]
413 ; CHECK-NEXT:    ret i1 [[T6]]
415   %t1 = trunc i32 %arg to i15
416   %t2 = icmp sgt i15 %t1, -1
417   %t3 = trunc i32 %arg to i16
418   %t4 = add i16 %t3, 128
419   %t5 = icmp ult i16 %t4, 256
420   %t6 = and i1 %t2, %t5
421   ret i1 %t6
424 define i1 @positive_different_trunc_both_logical(i32 %arg) {
425 ; CHECK-LABEL: @positive_different_trunc_both_logical(
426 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 16384
427 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[TMP1]], 0
428 ; CHECK-NEXT:    [[T3:%.*]] = trunc i32 [[ARG]] to i16
429 ; CHECK-NEXT:    [[T4:%.*]] = add i16 [[T3]], 128
430 ; CHECK-NEXT:    [[T5:%.*]] = icmp ult i16 [[T4]], 256
431 ; CHECK-NEXT:    [[T6:%.*]] = select i1 [[T2]], i1 [[T5]], i1 false
432 ; CHECK-NEXT:    ret i1 [[T6]]
434   %t1 = trunc i32 %arg to i15
435   %t2 = icmp sgt i15 %t1, -1
436   %t3 = trunc i32 %arg to i16
437   %t4 = add i16 %t3, 128
438   %t5 = icmp ult i16 %t4, 256
439   %t6 = select i1 %t2, i1 %t5, i1 false
440   ret i1 %t6
443 ; ============================================================================ ;
444 ; One-use tests.
446 ; We will only produce one instruction, so we do not care about one-use.
447 ; But, we *could* handle more patterns that we weren't able to canonicalize
448 ; because of extra-uses.
449 ; ============================================================================ ;
451 declare void @use32(i32)
452 declare void @use8(i8)
453 declare void @use1(i1)
455 define i1 @oneuse_with_signbit(i32 %arg) {
456 ; CHECK-LABEL: @oneuse_with_signbit(
457 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
458 ; CHECK-NEXT:    call void @use1(i1 [[T1]])
459 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[ARG]], 128
460 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
461 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 256
462 ; CHECK-NEXT:    call void @use1(i1 [[T3]])
463 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
464 ; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
466   %t1 = icmp sgt i32 %arg, -1
467   call void @use1(i1 %t1)
468   %t2 = add i32 %arg, 128
469   call void @use32(i32 %t2)
470   %t3 = icmp ult i32 %t2, 256
471   call void @use1(i1 %t3)
472   %t4 = and i1 %t1, %t3
473   ret i1 %t4
476 define i1 @oneuse_with_signbit_logical(i32 %arg) {
477 ; CHECK-LABEL: @oneuse_with_signbit_logical(
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 = select i1 %t1, i1 %t3, i1 false
494   ret i1 %t4
497 define i1 @oneuse_with_mask(i32 %arg) {
498 ; CHECK-LABEL: @oneuse_with_mask(
499 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 603979776
500 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
501 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
502 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
503 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
504 ; CHECK-NEXT:    call void @use32(i32 [[T3]])
505 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
506 ; CHECK-NEXT:    call void @use1(i1 [[T4]])
507 ; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
508 ; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
510   %t1 = and i32 %arg, 603979776 ; some bit within the target 4294967168 mask.
511   call void @use32(i32 %t1)
512   %t2 = icmp eq i32 %t1, 0
513   call void @use1(i1 %t2)
514   %t3 = add i32 %arg, 128
515   call void @use32(i32 %t3)
516   %t4 = icmp ult i32 %t3, 256
517   call void @use1(i1 %t4)
518   %t5 = and i1 %t2, %t4
519   ret i1 %t5
522 define i1 @oneuse_with_mask_logical(i32 %arg) {
523 ; CHECK-LABEL: @oneuse_with_mask_logical(
524 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 603979776
525 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
526 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
527 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
528 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
529 ; CHECK-NEXT:    call void @use32(i32 [[T3]])
530 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
531 ; CHECK-NEXT:    call void @use1(i1 [[T4]])
532 ; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
533 ; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
535   %t1 = and i32 %arg, 603979776 ; some bit within the target 4294967168 mask.
536   call void @use32(i32 %t1)
537   %t2 = icmp eq i32 %t1, 0
538   call void @use1(i1 %t2)
539   %t3 = add i32 %arg, 128
540   call void @use32(i32 %t3)
541   %t4 = icmp ult i32 %t3, 256
542   call void @use1(i1 %t4)
543   %t5 = select i1 %t2, i1 %t4, i1 false
544   ret i1 %t5
547 define i1 @oneuse_shl_ashr(i32 %arg) {
548 ; CHECK-LABEL: @oneuse_shl_ashr(
549 ; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
550 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
551 ; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[T1]], -1
552 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
553 ; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[ARG]], 24
554 ; CHECK-NEXT:    call void @use32(i32 [[T3]])
555 ; CHECK-NEXT:    [[T4:%.*]] = ashr exact i32 [[T3]], 24
556 ; CHECK-NEXT:    call void @use32(i32 [[T4]])
557 ; CHECK-NEXT:    [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
558 ; CHECK-NEXT:    call void @use1(i1 [[T5]])
559 ; CHECK-NEXT:    [[T6:%.*]] = and i1 [[T2]], [[T5]]
560 ; CHECK-NEXT:    ret i1 [[T6]]
562   %t1 = trunc i32 %arg to i8
563   call void @use8(i8 %t1)
564   %t2 = icmp sgt i8 %t1, -1
565   call void @use1(i1 %t2)
566   %t3 = shl i32 %arg, 24
567   call void @use32(i32 %t3)
568   %t4 = ashr i32 %t3, 24
569   call void @use32(i32 %t4)
570   %t5 = icmp eq i32 %t4, %arg
571   call void @use1(i1 %t5)
572   %t6 = and i1 %t2, %t5
573   ret i1 %t6
576 define i1 @oneuse_shl_ashr_logical(i32 %arg) {
577 ; CHECK-LABEL: @oneuse_shl_ashr_logical(
578 ; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
579 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
580 ; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[T1]], -1
581 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
582 ; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[ARG]], 24
583 ; CHECK-NEXT:    call void @use32(i32 [[T3]])
584 ; CHECK-NEXT:    [[T4:%.*]] = ashr exact i32 [[T3]], 24
585 ; CHECK-NEXT:    call void @use32(i32 [[T4]])
586 ; CHECK-NEXT:    [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
587 ; CHECK-NEXT:    call void @use1(i1 [[T5]])
588 ; CHECK-NEXT:    [[T6:%.*]] = select i1 [[T2]], i1 [[T5]], i1 false
589 ; CHECK-NEXT:    ret i1 [[T6]]
591   %t1 = trunc i32 %arg to i8
592   call void @use8(i8 %t1)
593   %t2 = icmp sgt i8 %t1, -1
594   call void @use1(i1 %t2)
595   %t3 = shl i32 %arg, 24
596   call void @use32(i32 %t3)
597   %t4 = ashr i32 %t3, 24
598   call void @use32(i32 %t4)
599   %t5 = icmp eq i32 %t4, %arg
600   call void @use1(i1 %t5)
601   %t6 = select i1 %t2, i1 %t5, i1 false
602   ret i1 %t6
605 define zeroext i1 @oneuse_trunc_sext(i32 %arg) {
606 ; CHECK-LABEL: @oneuse_trunc_sext(
607 ; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
608 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
609 ; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[T1]], -1
610 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
611 ; CHECK-NEXT:    [[T3:%.*]] = trunc i32 [[ARG]] to i8
612 ; CHECK-NEXT:    call void @use8(i8 [[T3]])
613 ; CHECK-NEXT:    [[T4:%.*]] = sext i8 [[T3]] to i32
614 ; CHECK-NEXT:    call void @use32(i32 [[T4]])
615 ; CHECK-NEXT:    [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
616 ; CHECK-NEXT:    call void @use1(i1 [[T5]])
617 ; CHECK-NEXT:    [[T6:%.*]] = and i1 [[T2]], [[T5]]
618 ; CHECK-NEXT:    ret i1 [[T6]]
620   %t1 = trunc i32 %arg to i8
621   call void @use8(i8 %t1)
622   %t2 = icmp sgt i8 %t1, -1
623   call void @use1(i1 %t2)
624   %t3 = trunc i32 %arg to i8
625   call void @use8(i8 %t3)
626   %t4 = sext i8 %t3 to i32
627   call void @use32(i32 %t4)
628   %t5 = icmp eq i32 %t4, %arg
629   call void @use1(i1 %t5)
630   %t6 = and i1 %t2, %t5
631   ret i1 %t6
634 define zeroext i1 @oneuse_trunc_sext_logical(i32 %arg) {
635 ; CHECK-LABEL: @oneuse_trunc_sext_logical(
636 ; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
637 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
638 ; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[T1]], -1
639 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
640 ; CHECK-NEXT:    [[T3:%.*]] = trunc i32 [[ARG]] to i8
641 ; CHECK-NEXT:    call void @use8(i8 [[T3]])
642 ; CHECK-NEXT:    [[T4:%.*]] = sext i8 [[T3]] to i32
643 ; CHECK-NEXT:    call void @use32(i32 [[T4]])
644 ; CHECK-NEXT:    [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
645 ; CHECK-NEXT:    call void @use1(i1 [[T5]])
646 ; CHECK-NEXT:    [[T6:%.*]] = select i1 [[T2]], i1 [[T5]], i1 false
647 ; CHECK-NEXT:    ret i1 [[T6]]
649   %t1 = trunc i32 %arg to i8
650   call void @use8(i8 %t1)
651   %t2 = icmp sgt i8 %t1, -1
652   call void @use1(i1 %t2)
653   %t3 = trunc i32 %arg to i8
654   call void @use8(i8 %t3)
655   %t4 = sext i8 %t3 to i32
656   call void @use32(i32 %t4)
657   %t5 = icmp eq i32 %t4, %arg
658   call void @use1(i1 %t5)
659   %t6 = select i1 %t2, i1 %t5, i1 false
660   ret i1 %t6
663 ; ============================================================================ ;
664 ; Negative tests
665 ; ============================================================================ ;
667 define i1 @negative_not_arg(i32 %arg, i32 %arg2) {
668 ; CHECK-LABEL: @negative_not_arg(
669 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
670 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[ARG2:%.*]], 128
671 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 256
672 ; CHECK-NEXT:    [[T4:%.*]] = and i1 [[T1]], [[T3]]
673 ; CHECK-NEXT:    ret i1 [[T4]]
675   %t1 = icmp sgt i32 %arg, -1
676   %t2 = add i32 %arg2, 128 ; not %arg
677   %t3 = icmp ult i32 %t2, 256
678   %t4 = and i1 %t1, %t3
679   ret i1 %t4
682 define i1 @negative_not_arg_logical(i32 %arg, i32 %arg2) {
683 ; CHECK-LABEL: @negative_not_arg_logical(
684 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
685 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[ARG2:%.*]], 128
686 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 256
687 ; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T1]], i1 [[T3]], i1 false
688 ; CHECK-NEXT:    ret i1 [[T4]]
690   %t1 = icmp sgt i32 %arg, -1
691   %t2 = add i32 %arg2, 128 ; not %arg
692   %t3 = icmp ult i32 %t2, 256
693   %t4 = select i1 %t1, i1 %t3, i1 false
694   ret i1 %t4
697 define i1 @negative_trunc_not_arg(i32 %arg, i32 %arg2) {
698 ; CHECK-LABEL: @negative_trunc_not_arg(
699 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 128
700 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[TMP1]], 0
701 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
702 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
703 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
704 ; CHECK-NEXT:    ret i1 [[T5]]
706   %t1 = trunc i32 %arg to i8
707   %t2 = icmp sgt i8 %t1, -1
708   %t3 = add i32 %arg2, 128 ; not %arg
709   %t4 = icmp ult i32 %t3, 256
710   %t5 = and i1 %t2, %t4
711   ret i1 %t5
714 define i1 @negative_trunc_not_arg_logical(i32 %arg, i32 %arg2) {
715 ; CHECK-LABEL: @negative_trunc_not_arg_logical(
716 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 128
717 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[TMP1]], 0
718 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
719 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
720 ; CHECK-NEXT:    [[T5:%.*]] = select i1 [[T2]], i1 [[T4]], i1 false
721 ; CHECK-NEXT:    ret i1 [[T5]]
723   %t1 = trunc i32 %arg to i8
724   %t2 = icmp sgt i8 %t1, -1
725   %t3 = add i32 %arg2, 128 ; not %arg
726   %t4 = icmp ult i32 %t3, 256
727   %t5 = select i1 %t2, i1 %t4, i1 false
728   ret i1 %t5
731 define i1 @positive_with_mask_not_arg(i32 %arg, i32 %arg2) {
732 ; CHECK-LABEL: @positive_with_mask_not_arg(
733 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1140850688
734 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
735 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
736 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
737 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
738 ; CHECK-NEXT:    ret i1 [[T5]]
740   %t1 = and i32 %arg, 1140850688
741   %t2 = icmp eq i32 %t1, 0
742   %t3 = add i32 %arg2, 128 ; not %arg
743   %t4 = icmp ult i32 %t3, 256
744   %t5 = and i1 %t2, %t4
745   ret i1 %t5
748 define i1 @positive_with_mask_not_arg_logical(i32 %arg, i32 %arg2) {
749 ; CHECK-LABEL: @positive_with_mask_not_arg_logical(
750 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1140850688
751 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
752 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
753 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
754 ; CHECK-NEXT:    [[T5:%.*]] = select i1 [[T2]], i1 [[T4]], i1 false
755 ; CHECK-NEXT:    ret i1 [[T5]]
757   %t1 = and i32 %arg, 1140850688
758   %t2 = icmp eq i32 %t1, 0
759   %t3 = add i32 %arg2, 128 ; not %arg
760   %t4 = icmp ult i32 %t3, 256
761   %t5 = select i1 %t2, i1 %t4, i1 false
762   ret i1 %t5
765 define i1 @negative_with_nonuniform_bad_mask(i32 %arg) {
766 ; CHECK-LABEL: @negative_with_nonuniform_bad_mask(
767 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1711276033
768 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
769 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
770 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
771 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
772 ; CHECK-NEXT:    ret i1 [[T5]]
774   %t1 = and i32 %arg, 1711276033 ; lowest bit is set
775   %t2 = icmp eq i32 %t1, 0
776   %t3 = add i32 %arg, 128
777   %t4 = icmp ult i32 %t3, 256
778   %t5 = and i1 %t2, %t4
779   ret i1 %t5
782 define i1 @negative_with_nonuniform_bad_mask_logical(i32 %arg) {
783 ; CHECK-LABEL: @negative_with_nonuniform_bad_mask_logical(
784 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1711276033
785 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
786 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
787 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
788 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
789 ; CHECK-NEXT:    ret i1 [[T5]]
791   %t1 = and i32 %arg, 1711276033 ; lowest bit is set
792   %t2 = icmp eq i32 %t1, 0
793   %t3 = add i32 %arg, 128
794   %t4 = icmp ult i32 %t3, 256
795   %t5 = select i1 %t2, i1 %t4, i1 false
796   ret i1 %t5
799 define i1 @negative_with_uniform_bad_mask(i32 %arg) {
800 ; CHECK-LABEL: @negative_with_uniform_bad_mask(
801 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], -16777152
802 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
803 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
804 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
805 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
806 ; CHECK-NEXT:    ret i1 [[T5]]
808   %t1 = and i32 %arg, 4278190144 ; 7'th bit is set
809   %t2 = icmp eq i32 %t1, 0
810   %t3 = add i32 %arg, 128
811   %t4 = icmp ult i32 %t3, 256
812   %t5 = and i1 %t2, %t4
813   ret i1 %t5
816 define i1 @negative_with_uniform_bad_mask_logical(i32 %arg) {
817 ; CHECK-LABEL: @negative_with_uniform_bad_mask_logical(
818 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], -16777152
819 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
820 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
821 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
822 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
823 ; CHECK-NEXT:    ret i1 [[T5]]
825   %t1 = and i32 %arg, 4278190144 ; 7'th bit is set
826   %t2 = icmp eq i32 %t1, 0
827   %t3 = add i32 %arg, 128
828   %t4 = icmp ult i32 %t3, 256
829   %t5 = select i1 %t2, i1 %t4, i1 false
830   ret i1 %t5
833 define i1 @negative_with_wrong_mask(i32 %arg) {
834 ; CHECK-LABEL: @negative_with_wrong_mask(
835 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1
836 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
837 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
838 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
839 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
840 ; CHECK-NEXT:    ret i1 [[T5]]
842   %t1 = and i32 %arg, 1 ; not even checking the right mask
843   %t2 = icmp eq i32 %t1, 0
844   %t3 = add i32 %arg, 128
845   %t4 = icmp ult i32 %t3, 256
846   %t5 = and i1 %t2, %t4
847   ret i1 %t5
850 define i1 @negative_with_wrong_mask_logical(i32 %arg) {
851 ; CHECK-LABEL: @negative_with_wrong_mask_logical(
852 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1
853 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
854 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
855 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
856 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
857 ; CHECK-NEXT:    ret i1 [[T5]]
859   %t1 = and i32 %arg, 1 ; not even checking the right mask
860   %t2 = icmp eq i32 %t1, 0
861   %t3 = add i32 %arg, 128
862   %t4 = icmp ult i32 %t3, 256
863   %t5 = select i1 %t2, i1 %t4, i1 false
864   ret i1 %t5
867 define i1 @negative_not_less_than(i32 %arg) {
868 ; CHECK-LABEL: @negative_not_less_than(
869 ; CHECK-NEXT:    ret i1 false
871   %t1 = icmp sgt i32 %arg, -1
872   %t2 = add i32 %arg, 256 ; should be less than 256
873   %t3 = icmp ult i32 %t2, 256
874   %t4 = and i1 %t1, %t3
875   ret i1 %t4
878 define i1 @negative_not_less_than_logical(i32 %arg) {
879 ; CHECK-LABEL: @negative_not_less_than_logical(
880 ; CHECK-NEXT:    ret i1 false
882   %t1 = icmp sgt i32 %arg, -1
883   %t2 = add i32 %arg, 256 ; should be less than 256
884   %t3 = icmp ult i32 %t2, 256
885   %t4 = select i1 %t1, i1 %t3, i1 false
886   ret i1 %t4
889 define i1 @negative_not_power_of_two(i32 %arg) {
890 ; CHECK-LABEL: @negative_not_power_of_two(
891 ; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[ARG:%.*]], 0
892 ; CHECK-NEXT:    ret i1 [[T4]]
894   %t1 = icmp sgt i32 %arg, -1
895   %t2 = add i32 %arg, 255 ; should be power of two
896   %t3 = icmp ult i32 %t2, 256
897   %t4 = and i1 %t1, %t3
898   ret i1 %t4
901 define i1 @negative_not_power_of_two_logical(i32 %arg) {
902 ; CHECK-LABEL: @negative_not_power_of_two_logical(
903 ; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[ARG:%.*]], 0
904 ; CHECK-NEXT:    ret i1 [[T4]]
906   %t1 = icmp sgt i32 %arg, -1
907   %t2 = add i32 %arg, 255 ; should be power of two
908   %t3 = icmp ult i32 %t2, 256
909   %t4 = select i1 %t1, i1 %t3, i1 false
910   ret i1 %t4
913 define i1 @negative_not_next_power_of_two(i32 %arg) {
914 ; CHECK-LABEL: @negative_not_next_power_of_two(
915 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[ARG:%.*]], 192
916 ; CHECK-NEXT:    ret i1 [[T4]]
918   %t1 = icmp sgt i32 %arg, -1
919   %t2 = add i32 %arg, 64 ; should be 256 >> 1
920   %t3 = icmp ult i32 %t2, 256
921   %t4 = and i1 %t1, %t3
922   ret i1 %t4
925 define i1 @negative_not_next_power_of_two_logical(i32 %arg) {
926 ; CHECK-LABEL: @negative_not_next_power_of_two_logical(
927 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[ARG:%.*]], 192
928 ; CHECK-NEXT:    ret i1 [[T4]]
930   %t1 = icmp sgt i32 %arg, -1
931   %t2 = add i32 %arg, 64 ; should be 256 >> 1
932   %t3 = icmp ult i32 %t2, 256
933   %t4 = select i1 %t1, i1 %t3, i1 false
934   ret i1 %t4
937 define i1 @two_signed_truncation_checks(i32 %arg) {
938 ; CHECK-LABEL: @two_signed_truncation_checks(
939 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[ARG:%.*]], 128
940 ; CHECK-NEXT:    [[T5:%.*]] = icmp ult i32 [[TMP1]], 256
941 ; CHECK-NEXT:    ret i1 [[T5]]
943   %t1 = add i32 %arg, 512
944   %t2 = icmp ult i32 %t1, 1024
945   %t3 = add i32 %arg, 128
946   %t4 = icmp ult i32 %t3, 256
947   %t5 = and i1 %t2, %t4
948   ret i1 %t5
951 define i1 @two_signed_truncation_checks_logical(i32 %arg) {
952 ; CHECK-LABEL: @two_signed_truncation_checks_logical(
953 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[ARG:%.*]], 128
954 ; CHECK-NEXT:    [[T5:%.*]] = icmp ult i32 [[TMP1]], 256
955 ; CHECK-NEXT:    ret i1 [[T5]]
957   %t1 = add i32 %arg, 512
958   %t2 = icmp ult i32 %t1, 1024
959   %t3 = add i32 %arg, 128
960   %t4 = icmp ult i32 %t3, 256
961   %t5 = select i1 %t2, i1 %t4, i1 false
962   ret i1 %t5
965 define i1 @bad_trunc_stc(i32 %arg) {
966 ; CHECK-LABEL: @bad_trunc_stc(
967 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
968 ; CHECK-NEXT:    [[T2:%.*]] = trunc i32 [[ARG]] to i16
969 ; CHECK-NEXT:    [[T3:%.*]] = add i16 [[T2]], 128
970 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i16 [[T3]], 256
971 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T1]], [[T4]]
972 ; CHECK-NEXT:    ret i1 [[T5]]
974   %t1 = icmp sgt i32 %arg, -1 ; checks a bit outside of the i16
975   %t2 = trunc i32 %arg to i16
976   %t3 = add i16 %t2, 128
977   %t4 = icmp ult i16 %t3, 256
978   %t5 = and i1 %t1, %t4
979   ret i1 %t5
982 define i1 @bad_trunc_stc_logical(i32 %arg) {
983 ; CHECK-LABEL: @bad_trunc_stc_logical(
984 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
985 ; CHECK-NEXT:    [[T2:%.*]] = trunc i32 [[ARG]] to i16
986 ; CHECK-NEXT:    [[T3:%.*]] = add i16 [[T2]], 128
987 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i16 [[T3]], 256
988 ; CHECK-NEXT:    [[T5:%.*]] = select i1 [[T1]], i1 [[T4]], i1 false
989 ; CHECK-NEXT:    ret i1 [[T5]]
991   %t1 = icmp sgt i32 %arg, -1 ; checks a bit outside of the i16
992   %t2 = trunc i32 %arg to i16
993   %t3 = add i16 %t2, 128
994   %t4 = icmp ult i16 %t3, 256
995   %t5 = select i1 %t1, i1 %t4, i1 false
996   ret i1 %t5