[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-ne-pow2.ll
blobb19909a234481188977de150ed4c66ae42acef42
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4 declare void @llvm.assume(i1)
5 declare i32 @llvm.ctpop.i32(i32)
7 define i32 @pow2_32_assume(i32 %x) {
8 ; CHECK-LABEL: @pow2_32_assume(
9 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 4
10 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
11 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
12 ; CHECK-NEXT:    ret i32 4
14   %and = and i32 %x, 4
15   %cmp = icmp ne i32 %and, 0
16   call void @llvm.assume(i1 %cmp)
17   %and2 = and i32 %x, 4
18   ret i32 %and2
21 define i32 @not_pow2_32_assume(i32 %x) {
22 ; CHECK-LABEL: @not_pow2_32_assume(
23 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
24 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
25 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
26 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], 3
27 ; CHECK-NEXT:    ret i32 [[AND2]]
29   %and = and i32 %x, 3
30   %cmp = icmp ne i32 %and, 0
31   call void @llvm.assume(i1 %cmp)
32   %and2 = and i32 %x, 3
33   ret i32 %and2
36 define i64 @pow2_64_assume(i64 %x) {
37 ; CHECK-LABEL: @pow2_64_assume(
38 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[X:%.*]], 1
39 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[AND]], 0
40 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
41 ; CHECK-NEXT:    ret i64 [[X]]
43   %and = and i64 %x, 1
44   %cmp = icmp ne i64 %and, 0
45   call void @llvm.assume(i1 %cmp)
46   %or = or i64 %x, 1
47   ret i64 %or
50 define i64 @not_pow2_64_assume(i64 %x) {
51 ; CHECK-LABEL: @not_pow2_64_assume(
52 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[X:%.*]], 2147483647
53 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[AND]], 0
54 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
55 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[X]], 2147483647
56 ; CHECK-NEXT:    ret i64 [[OR]]
58   %and = and i64 %x, 2147483647
59   %cmp = icmp ne i64 %and, 0
60   call void @llvm.assume(i1 %cmp)
61   %or = or i64 %x, 2147483647
62   ret i64 %or
65 define i16 @pow2_16_assume(i16 %x) {
66 ; CHECK-LABEL: @pow2_16_assume(
67 ; CHECK-NEXT:    [[AND:%.*]] = and i16 [[X:%.*]], 16384
68 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 [[AND]], 0
69 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
70 ; CHECK-NEXT:    ret i16 16384
72   %and = and i16 %x, 16384
73   %cmp = icmp eq i16 %and, 16384
74   call void @llvm.assume(i1 %cmp)
75   %and2 = and i16 %x, 16384
76   ret i16 %and2
79 define i16 @not_pow2_16_assume(i16 %x) {
80 ; CHECK-LABEL: @not_pow2_16_assume(
81 ; CHECK-NEXT:    [[AND:%.*]] = and i16 [[X:%.*]], 7
82 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 [[AND]], 7
83 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
84 ; CHECK-NEXT:    [[AND2:%.*]] = and i16 [[X]], 7
85 ; CHECK-NEXT:    ret i16 [[AND2]]
87   %and = and i16 %x, 7
88   %cmp = icmp ne i16 %and, 7
89   call void @llvm.assume(i1 %cmp)
90   %and2 = and i16 %x, 7
91   ret i16 %and2
94 define i8 @pow2_8_assume(i8 %x) {
95 ; CHECK-LABEL: @pow2_8_assume(
96 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
97 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
98 ; CHECK-NEXT:    ret i8 [[X]]
100   %and = and i8 %x, 128
101   %cmp = icmp eq i8 %and, 128
102   call void @llvm.assume(i1 %cmp)
103   %or = or i8 %x, 128
104   ret i8 %or
107 define i8 @not_pow2_8_assume(i8 %x) {
108 ; CHECK-LABEL: @not_pow2_8_assume(
109 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], 127
110 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[AND]], 127
111 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
112 ; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X]], 127
113 ; CHECK-NEXT:    ret i8 [[OR]]
115   %and = and i8 %x, 127
116   %cmp = icmp ne i8 %and, 127
117   call void @llvm.assume(i1 %cmp)
118   %or = or i8 %x, 127
119   ret i8 %or
122 define i32 @pow2_32_br(i32 %x) {
123 ; CHECK-LABEL: @pow2_32_br(
124 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 4
125 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
126 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
127 ; CHECK:       True:
128 ; CHECK-NEXT:    ret i32 [[X]]
129 ; CHECK:       False:
130 ; CHECK-NEXT:    ret i32 0
132   %and = and i32 %x, 4
133   %cmp = icmp eq i32 %and, 4
134   br i1 %cmp, label %True, label %False
135 True:
136   %or = or i32 %x, 4
137   ret i32 %or
138 False:
139   ret i32 0
142 define i32 @not_pow2_32_br(i32 %x) {
143 ; CHECK-LABEL: @not_pow2_32_br(
144 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
145 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
146 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
147 ; CHECK:       True:
148 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], 3
149 ; CHECK-NEXT:    ret i32 [[OR]]
150 ; CHECK:       False:
151 ; CHECK-NEXT:    ret i32 0
153   %and = and i32 %x, 3
154   %cmp = icmp ne i32 %and, 0
155   br i1 %cmp, label %True, label %False
156 True:
157   %or = or i32 %x, 3
158   ret i32 %or
159 False:
160   ret i32 0
163 define i64 @pow2_64_br(i64 %x) {
164 ; CHECK-LABEL: @pow2_64_br(
165 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[X:%.*]], 1
166 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i64 [[AND]], 0
167 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
168 ; CHECK:       True:
169 ; CHECK-NEXT:    ret i64 1
170 ; CHECK:       False:
171 ; CHECK-NEXT:    ret i64 0
173   %and = and i64 %x, 1
174   %cmp = icmp ne i64 %and, 0
175   br i1 %cmp, label %True, label %False
176 True:
177   %and2 = and i64 %x, 1
178   ret i64 %and2
179 False:
180   ret i64 0
183 define i64 @not_pow2_64_br(i64 %x) {
184 ; CHECK-LABEL: @not_pow2_64_br(
185 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[X:%.*]], 2147483647
186 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i64 [[AND]], 0
187 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
188 ; CHECK:       True:
189 ; CHECK-NEXT:    [[AND2:%.*]] = and i64 [[X]], 2147483647
190 ; CHECK-NEXT:    ret i64 [[AND2]]
191 ; CHECK:       False:
192 ; CHECK-NEXT:    ret i64 0
194   %and = and i64 %x, 2147483647
195   %cmp = icmp ne i64 %and, 0
196   br i1 %cmp, label %True, label %False
197 True:
198   %and2 = and i64 %x, 2147483647
199   ret i64 %and2
200 False:
201   ret i64 0
204 define i16 @pow2_16_br(i16 %x) {
205 ; CHECK-LABEL: @pow2_16_br(
206 ; CHECK-NEXT:    [[AND:%.*]] = and i16 [[X:%.*]], 16384
207 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i16 [[AND]], 0
208 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
209 ; CHECK:       True:
210 ; CHECK-NEXT:    ret i16 [[X]]
211 ; CHECK:       False:
212 ; CHECK-NEXT:    ret i16 0
214   %and = and i16 %x, 16384
215   %cmp = icmp eq i16 %and, 16384
216   br i1 %cmp, label %True, label %False
217 True:
218   %or = or i16 %x, 16384
219   ret i16 %or
220 False:
221   ret i16 0
224 define i16 @not_pow2_16_br(i16 %x) {
225 ; CHECK-LABEL: @not_pow2_16_br(
226 ; CHECK-NEXT:    [[AND:%.*]] = and i16 [[X:%.*]], 7
227 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i16 [[AND]], 7
228 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
229 ; CHECK:       True:
230 ; CHECK-NEXT:    [[OR:%.*]] = or i16 [[X]], 7
231 ; CHECK-NEXT:    ret i16 [[OR]]
232 ; CHECK:       False:
233 ; CHECK-NEXT:    ret i16 0
235   %and = and i16 %x, 7
236   %cmp = icmp ne i16 %and, 7
237   br i1 %cmp, label %True, label %False
238 True:
239   %or = or i16 %x, 7
240   ret i16 %or
241 False:
242   ret i16 0
245 define i8 @pow2_8_br(i8 %x) {
246 ; CHECK-LABEL: @pow2_8_br(
247 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i8 [[X:%.*]], -1
248 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
249 ; CHECK:       True:
250 ; CHECK-NEXT:    ret i8 -128
251 ; CHECK:       False:
252 ; CHECK-NEXT:    ret i8 0
254   %and = and i8 %x, 128
255   %cmp = icmp ne i8 %and, 0
256   br i1 %cmp, label %True, label %False
257 True:
258   %and2 = and i8 %x, 128
259   ret i8 %and2
260 False:
261   ret i8 0
264 define i8 @not_pow2_8_br(i8 %x) {
265 ; CHECK-LABEL: @not_pow2_8_br(
266 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], 127
267 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 127
268 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
269 ; CHECK:       True:
270 ; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X]], 127
271 ; CHECK-NEXT:    ret i8 [[AND2]]
272 ; CHECK:       False:
273 ; CHECK-NEXT:    ret i8 0
275   %and = and i8 %x, 127
276   %cmp = icmp ne i8 %and, 127
277   br i1 %cmp, label %True, label %False
278 True:
279   %and2 = and i8 %x, 127
280   ret i8 %and2
281 False:
282   ret i8 0
285 define i32 @pow2_32_nonconst_assume(i32 %x, i32 %y) {
286 ; CHECK-LABEL: @pow2_32_nonconst_assume(
287 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
288 ; CHECK-NEXT:    [[YP2:%.*]] = icmp eq i32 [[CTPOP]], 1
289 ; CHECK-NEXT:    call void @llvm.assume(i1 [[YP2]])
290 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y]]
291 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
292 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
293 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], [[Y]]
294 ; CHECK-NEXT:    ret i32 [[AND2]]
296   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
297   %yp2 = icmp eq i32 %ctpop, 1
298   call void @llvm.assume(i1 %yp2)
300   %and = and i32 %x, %y
301   %cmp = icmp ne i32 %and, 0
302   call void @llvm.assume(i1 %cmp)
303   %and2 = and i32 %x, %y
304   ret i32 %and2
307 define i32 @pow2_32_gtnonconst_assume(i32 %x, i32 %y) {
308 ; CHECK-LABEL: @pow2_32_gtnonconst_assume(
309 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
310 ; CHECK-NEXT:    [[YP2:%.*]] = icmp eq i32 [[CTPOP]], 1
311 ; CHECK-NEXT:    call void @llvm.assume(i1 [[YP2]])
312 ; CHECK-NEXT:    [[YGT:%.*]] = icmp ugt i32 [[Y]], [[X:%.*]]
313 ; CHECK-NEXT:    call void @llvm.assume(i1 [[YGT]])
314 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
315 ; CHECK-NEXT:    ret i32 [[AND]]
317   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
318   %yp2 = icmp eq i32 %ctpop, 1
319   call void @llvm.assume(i1 %yp2)
321   %ygt = icmp ugt i32 %y, %x
322   call void @llvm.assume(i1 %ygt)
324   %and = and i32 %x, %y
325   ret i32 %and
328 define i32 @not_pow2_32_nonconst_assume(i32 %x, i32 %y) {
329 ; CHECK-LABEL: @not_pow2_32_nonconst_assume(
330 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
331 ; CHECK-NEXT:    [[YP2:%.*]] = icmp ne i32 [[CTPOP]], 1
332 ; CHECK-NEXT:    call void @llvm.assume(i1 [[YP2]])
333 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y]]
334 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
335 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
336 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], [[Y]]
337 ; CHECK-NEXT:    ret i32 [[AND2]]
339   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
340   %yp2 = icmp ne i32 %ctpop, 1
341   call void @llvm.assume(i1 %yp2)
343   %and = and i32 %x, %y
344   %cmp = icmp ne i32 %and, 0
345   call void @llvm.assume(i1 %cmp)
346   %and2 = and i32 %x, %y
347   ret i32 %and2
350 define i32 @pow2_or_zero_32_nonconst_assume(i32 %x, i32 %y) {
351 ; CHECK-LABEL: @pow2_or_zero_32_nonconst_assume(
352 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
353 ; CHECK-NEXT:    [[YP2:%.*]] = icmp samesign ult i32 [[CTPOP]], 2
354 ; CHECK-NEXT:    call void @llvm.assume(i1 [[YP2]])
355 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y]]
356 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
357 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
358 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], [[Y]]
359 ; CHECK-NEXT:    ret i32 [[AND2]]
361   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
362   %yp2 = icmp ule i32 %ctpop, 1
363   call void @llvm.assume(i1 %yp2)
365   %and = and i32 %x, %y
366   %cmp = icmp ne i32 %and, 0
367   call void @llvm.assume(i1 %cmp)
368   %and2 = and i32 %x, %y
369   ret i32 %and2
372 define i32 @pow2_32_nonconst_assume_br(i32 %x, i32 %y) {
373 ; CHECK-LABEL: @pow2_32_nonconst_assume_br(
374 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
375 ; CHECK-NEXT:    [[YP2:%.*]] = icmp eq i32 [[CTPOP]], 1
376 ; CHECK-NEXT:    call void @llvm.assume(i1 [[YP2]])
377 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y]]
378 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
379 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
380 ; CHECK:       True:
381 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], [[Y]]
382 ; CHECK-NEXT:    ret i32 [[AND2]]
383 ; CHECK:       False:
384 ; CHECK-NEXT:    ret i32 0
386   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
387   %yp2 = icmp eq i32 %ctpop, 1
388   call void @llvm.assume(i1 %yp2)
389   %and = and i32 %x, %y
390   %cmp = icmp ne i32 %and, 0
391   br i1 %cmp, label %True, label %False
392 True:
393   %and2 = and i32 %x, %y
394   ret i32 %and2
395 False:
396   ret i32 0
399 define i32 @not_pow2_32_nonconst_assume_br(i32 %x, i32 %y) {
400 ; CHECK-LABEL: @not_pow2_32_nonconst_assume_br(
401 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
402 ; CHECK-NEXT:    [[YP2:%.*]] = icmp ne i32 [[CTPOP]], 1
403 ; CHECK-NEXT:    call void @llvm.assume(i1 [[YP2]])
404 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y]]
405 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
406 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
407 ; CHECK:       True:
408 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], [[Y]]
409 ; CHECK-NEXT:    ret i32 [[AND2]]
410 ; CHECK:       False:
411 ; CHECK-NEXT:    ret i32 0
413   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
414   %yp2 = icmp ne i32 %ctpop, 1
415   call void @llvm.assume(i1 %yp2)
416   %and = and i32 %x, %y
417   %cmp = icmp ne i32 %and, 0
418   br i1 %cmp, label %True, label %False
419 True:
420   %and2 = and i32 %x, %y
421   ret i32 %and2
422 False:
423   ret i32 0
426 define i32 @pow2_or_zero_32_nonconst_assume_br(i32 %x, i32 %y) {
427 ; CHECK-LABEL: @pow2_or_zero_32_nonconst_assume_br(
428 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
429 ; CHECK-NEXT:    [[YP2:%.*]] = icmp samesign ult i32 [[CTPOP]], 2
430 ; CHECK-NEXT:    call void @llvm.assume(i1 [[YP2]])
431 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y]]
432 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
433 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
434 ; CHECK:       True:
435 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], [[Y]]
436 ; CHECK-NEXT:    ret i32 [[AND2]]
437 ; CHECK:       False:
438 ; CHECK-NEXT:    ret i32 0
440   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
441   %yp2 = icmp ule i32 %ctpop, 1
442   call void @llvm.assume(i1 %yp2)
443   %and = and i32 %x, %y
444   %cmp = icmp ne i32 %and, 0
445   br i1 %cmp, label %True, label %False
446 True:
447   %and2 = and i32 %x, %y
448   ret i32 %and2
449 False:
450   ret i32 0
453 define i32 @pow2_32_nonconst_br1_br(i32 %x, i32 %y) {
454 ; CHECK-LABEL: @pow2_32_nonconst_br1_br(
455 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
456 ; CHECK-NEXT:    [[YP2:%.*]] = icmp eq i32 [[CTPOP]], 1
457 ; CHECK-NEXT:    br i1 [[YP2]], label [[CONT:%.*]], label [[FALSE:%.*]]
458 ; CHECK:       Cont:
459 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y]]
460 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
461 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE]], label [[TRUE:%.*]]
462 ; CHECK:       True:
463 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], [[Y]]
464 ; CHECK-NEXT:    ret i32 [[AND2]]
465 ; CHECK:       False:
466 ; CHECK-NEXT:    ret i32 0
468   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
469   %yp2 = icmp eq i32 %ctpop, 1
470   br i1 %yp2, label %Cont, label %False
471 Cont:
472   %and = and i32 %x, %y
473   %cmp = icmp ne i32 %and, 0
474   br i1 %cmp, label %True, label %False
475 True:
476   %and2 = and i32 %x, %y
477   ret i32 %and2
478 False:
479   ret i32 0
482 define i32 @not_pow2_32_nonconst_br1_br(i32 %x, i32 %y) {
483 ; CHECK-LABEL: @not_pow2_32_nonconst_br1_br(
484 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[Y:%.*]])
485 ; CHECK-NEXT:    [[YP2_NOT:%.*]] = icmp eq i32 [[CTPOP]], 1
486 ; CHECK-NEXT:    br i1 [[YP2_NOT]], label [[FALSE:%.*]], label [[CONT:%.*]]
487 ; CHECK:       Cont:
488 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y]]
489 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
490 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE]], label [[TRUE:%.*]]
491 ; CHECK:       True:
492 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], [[Y]]
493 ; CHECK-NEXT:    ret i32 [[AND2]]
494 ; CHECK:       False:
495 ; CHECK-NEXT:    ret i32 0
497   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
498   %yp2 = icmp ne i32 %ctpop, 1
499   br i1 %yp2, label %Cont, label %False
500 Cont:
501   %and = and i32 %x, %y
502   %cmp = icmp ne i32 %and, 0
503   br i1 %cmp, label %True, label %False
504 True:
505   %and2 = and i32 %x, %y
506   ret i32 %and2
507 False:
508   ret i32 0
511 define i32 @maybe_pow2_32_noncont(i32 %x, i32 %y) {
512 ; CHECK-LABEL: @maybe_pow2_32_noncont(
513 ; CHECK-NEXT:    [[YGT8:%.*]] = icmp ugt i32 [[Y:%.*]], 8
514 ; CHECK-NEXT:    br i1 [[YGT8]], label [[CONT1:%.*]], label [[CONT2:%.*]]
515 ; CHECK:       Cont1:
516 ; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[Y]])
517 ; CHECK-NEXT:    [[YP2:%.*]] = icmp eq i32 [[CTPOP]], 1
518 ; CHECK-NEXT:    call void @llvm.assume(i1 [[YP2]])
519 ; CHECK-NEXT:    br i1 true, label [[CONT2]], label [[FALSE:%.*]]
520 ; CHECK:       Cont2:
521 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y]]
522 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
523 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FALSE]], label [[TRUE:%.*]]
524 ; CHECK:       True:
525 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], [[Y]]
526 ; CHECK-NEXT:    ret i32 [[AND2]]
527 ; CHECK:       False:
528 ; CHECK-NEXT:    ret i32 0
530   %ygt8 = icmp ugt i32 %y, 8
531   br i1 %ygt8, label %Cont1, label %Cont2
532 Cont1:
533   %ctpop = call i32 @llvm.ctpop.i32(i32 %y)
534   %yp2 = icmp eq i32 %ctpop, 1
535   call void @llvm.assume(i1 %yp2)
536   br i1 true, label %Cont2, label %False
537 Cont2:
538   %and = and i32 %x, %y
539   %cmp = icmp ne i32 %and, 0
540   br i1 %cmp, label %True, label %False
541 True:
542   %and2 = and i32 %x, %y
543   ret i32 %and2
544 False:
545   ret i32 0