xref: /llvm-project/llvm/test/Transforms/InstCombine/ispow2.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i1 @is_pow2or0_negate_op(i32 %x) {
5; CHECK-LABEL: @is_pow2or0_negate_op(
6; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
7; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[TMP1]], 2
8; CHECK-NEXT:    ret i1 [[CMP]]
9;
10  %neg = sub i32 0, %x
11  %and = and i32 %neg, %x
12  %cmp = icmp eq i32 %and, %x
13  ret i1 %cmp
14}
15
16define <2 x i1> @is_pow2or0_negate_op_vec(<2 x i32> %x) {
17; CHECK-LABEL: @is_pow2or0_negate_op_vec(
18; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])
19; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult <2 x i32> [[TMP1]], splat (i32 2)
20; CHECK-NEXT:    ret <2 x i1> [[CMP]]
21;
22  %neg = sub <2 x i32> zeroinitializer, %x
23  %and = and <2 x i32> %neg, %x
24  %cmp = icmp eq <2 x i32> %and, %x
25  ret <2 x i1> %cmp
26}
27
28define i1 @is_pow2or0_decrement_op(i8 %x) {
29; CHECK-LABEL: @is_pow2or0_decrement_op(
30; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])
31; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i8 [[TMP1]], 2
32; CHECK-NEXT:    ret i1 [[CMP]]
33;
34  %dec = add i8 %x, -1
35  %and = and i8 %dec, %x
36  %cmp = icmp eq i8 %and, 0
37  ret i1 %cmp
38}
39
40define <2 x i1> @is_pow2or0_decrement_op_vec(<2 x i8> %x) {
41; CHECK-LABEL: @is_pow2or0_decrement_op_vec(
42; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
43; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult <2 x i8> [[TMP1]], splat (i8 2)
44; CHECK-NEXT:    ret <2 x i1> [[CMP]]
45;
46  %dec = add <2 x i8> %x, <i8 -1, i8 -1>
47  %and = and <2 x i8> %dec, %x
48  %cmp = icmp eq <2 x i8> %and, zeroinitializer
49  ret <2 x i1> %cmp
50}
51
52define i1 @isnot_pow2or0_negate_op(i32 %x) {
53; CHECK-LABEL: @isnot_pow2or0_negate_op(
54; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
55; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[TMP1]], 1
56; CHECK-NEXT:    ret i1 [[CMP]]
57;
58  %neg = sub i32 0, %x
59  %and = and i32 %neg, %x
60  %cmp = icmp ne i32 %and, %x
61  ret i1 %cmp
62}
63
64define <2 x i1> @isnot_pow2or0_negate_op_vec(<2 x i32> %x) {
65; CHECK-LABEL: @isnot_pow2or0_negate_op_vec(
66; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])
67; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt <2 x i32> [[TMP1]], splat (i32 1)
68; CHECK-NEXT:    ret <2 x i1> [[CMP]]
69;
70  %neg = sub <2 x i32> zeroinitializer, %x
71  %and = and <2 x i32> %neg, %x
72  %cmp = icmp ne <2 x i32> %and, %x
73  ret <2 x i1> %cmp
74}
75
76define i1 @isnot_pow2or0_decrement_op(i8 %x) {
77; CHECK-LABEL: @isnot_pow2or0_decrement_op(
78; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])
79; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i8 [[TMP1]], 1
80; CHECK-NEXT:    ret i1 [[CMP]]
81;
82  %dec = add i8 %x, -1
83  %and = and i8 %dec, %x
84  %cmp = icmp ne i8 %and, 0
85  ret i1 %cmp
86}
87
88define <2 x i1> @isnot_pow2or0_decrement_op_vec(<2 x i8> %x) {
89; CHECK-LABEL: @isnot_pow2or0_decrement_op_vec(
90; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
91; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt <2 x i8> [[TMP1]], splat (i8 1)
92; CHECK-NEXT:    ret <2 x i1> [[CMP]]
93;
94  %dec = add <2 x i8> %x, <i8 -1, i8 -1>
95  %and = and <2 x i8> %dec, %x
96  %cmp = icmp ne <2 x i8> %and, zeroinitializer
97  ret <2 x i1> %cmp
98}
99
100define i1 @is_pow2or0_negate_op_commute1(i32 %p) {
101; CHECK-LABEL: @is_pow2or0_negate_op_commute1(
102; CHECK-NEXT:    [[X:%.*]] = srem i32 42, [[P:%.*]]
103; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 7) i32 @llvm.ctpop.i32(i32 [[X]])
104; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[TMP1]], 2
105; CHECK-NEXT:    ret i1 [[CMP]]
106;
107  %x = srem i32 42, %p ; thwart complexity-based canonicalization
108  %neg = sub i32 0, %x
109  %and = and i32 %x, %neg
110  %cmp = icmp eq i32 %and, %x
111  ret i1 %cmp
112}
113
114; x can't be <= complexity of the 'neg' but >= complexity of the 'and'.
115
116define i1 @isnot_pow2or0_negate_op_commute2(i32 %p) {
117; CHECK-LABEL: @isnot_pow2or0_negate_op_commute2(
118; CHECK-NEXT:    [[X:%.*]] = urem i32 42, [[P:%.*]]
119; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 7) i32 @llvm.ctpop.i32(i32 [[X]])
120; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[TMP1]], 1
121; CHECK-NEXT:    ret i1 [[CMP]]
122;
123  %x = urem i32 42, %p ; thwart complexity-based canonicalization
124  %neg = sub i32 0, %x
125  %and = and i32 %neg, %x
126  %cmp = icmp ne i32 %x, %and
127  ret i1 %cmp
128}
129
130define i1 @isnot_pow2or0_negate_op_commute3(i32 %p) {
131; CHECK-LABEL: @isnot_pow2or0_negate_op_commute3(
132; CHECK-NEXT:    [[X:%.*]] = urem i32 42, [[P:%.*]]
133; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 7) i32 @llvm.ctpop.i32(i32 [[X]])
134; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[TMP1]], 1
135; CHECK-NEXT:    ret i1 [[CMP]]
136;
137  %x = urem i32 42, %p ; thwart complexity-based canonicalization
138  %neg = sub i32 0, %x
139  %and = and i32 %x, %neg
140  %cmp = icmp ne i32 %x, %and
141  ret i1 %cmp
142}
143
144declare void @use(i32)
145
146define i1 @is_pow2or0_negate_op_extra_use1(i32 %x) {
147; CHECK-LABEL: @is_pow2or0_negate_op_extra_use1(
148; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]
149; CHECK-NEXT:    call void @use(i32 [[NEG]])
150; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
151; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[TMP1]], 2
152; CHECK-NEXT:    ret i1 [[CMP]]
153;
154  %neg = sub i32 0, %x
155  call void @use(i32 %neg)
156  %and = and i32 %neg, %x
157  %cmp = icmp eq i32 %and, %x
158  ret i1 %cmp
159}
160
161define i1 @is_pow2or0_negate_op_extra_use2(i32 %x) {
162; CHECK-LABEL: @is_pow2or0_negate_op_extra_use2(
163; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]
164; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[NEG]]
165; CHECK-NEXT:    call void @use(i32 [[AND]])
166; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[X]]
167; CHECK-NEXT:    ret i1 [[CMP]]
168;
169  %neg = sub i32 0, %x
170  %and = and i32 %neg, %x
171  call void @use(i32 %and)
172  %cmp = icmp eq i32 %and, %x
173  ret i1 %cmp
174}
175
176declare i32 @llvm.ctpop.i32(i32)
177declare <2 x i8> @llvm.ctpop.v2i8(<2 x i8>)
178declare void @llvm.assume(i1)
179
180; (X != 0) && (ctpop(X) u< 2) --> ctpop(X) == 1
181
182define i1 @is_pow2_ctpop(i32 %x) {
183; CHECK-LABEL: @is_pow2_ctpop(
184; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
185; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[T0]], 1
186; CHECK-NEXT:    ret i1 [[R]]
187;
188  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
189  %cmp = icmp ult i32 %t0, 2
190  %notzero = icmp ne i32 %x, 0
191  %r = and i1 %notzero, %cmp
192  ret i1 %r
193}
194
195; tests from PR57328
196define i1 @is_pow2_non_zero_ult_2(i32 %x) {
197; CHECK-LABEL: @is_pow2_non_zero_ult_2(
198; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X:%.*]], 0
199; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTZERO]])
200; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])
201; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2
202; CHECK-NEXT:    ret i1 [[CMP]]
203;
204  %notzero = icmp ne i32 %x, 0
205  call void @llvm.assume(i1 %notzero)
206  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
207  %cmp = icmp ult i32 %t0, 2
208  ret i1 %cmp
209}
210
211define i1 @is_pow2_non_zero_eq_1(i32 %x) {
212; CHECK-LABEL: @is_pow2_non_zero_eq_1(
213; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X:%.*]], 0
214; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTZERO]])
215; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])
216; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 1
217; CHECK-NEXT:    ret i1 [[CMP]]
218;
219  %notzero = icmp ne i32 %x, 0
220  call void @llvm.assume(i1 %notzero)
221  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
222  %cmp = icmp eq i32 %t0, 1
223  ret i1 %cmp
224}
225
226define i1 @is_pow2_non_zero_ugt_1(i32 %x) {
227; CHECK-LABEL: @is_pow2_non_zero_ugt_1(
228; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X:%.*]], 0
229; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTZERO]])
230; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])
231; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1
232; CHECK-NEXT:    ret i1 [[CMP]]
233;
234  %notzero = icmp ne i32 %x, 0
235  call void @llvm.assume(i1 %notzero)
236  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
237  %cmp = icmp ugt i32 %t0, 1
238  ret i1 %cmp
239}
240
241define i1 @is_pow2_non_zero_ne_1(i32 %x) {
242; CHECK-LABEL: @is_pow2_non_zero_ne_1(
243; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X:%.*]], 0
244; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTZERO]])
245; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])
246; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 1
247; CHECK-NEXT:    ret i1 [[CMP]]
248;
249  %notzero = icmp ne i32 %x, 0
250  call void @llvm.assume(i1 %notzero)
251  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
252  %cmp = icmp ne i32 %t0, 1
253  ret i1 %cmp
254}
255
256define i1 @is_pow2_ctpop_logical(i32 %x) {
257; CHECK-LABEL: @is_pow2_ctpop_logical(
258; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
259; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[T0]], 1
260; CHECK-NEXT:    ret i1 [[R]]
261;
262  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
263  %cmp = icmp ult i32 %t0, 2
264  %notzero = icmp ne i32 %x, 0
265  %r = select i1 %notzero, i1 %cmp, i1 false
266  ret i1 %r
267}
268
269; Extra uses don't change the fold.
270declare void @use_i1(i1)
271
272define i1 @is_pow2_ctpop_extra_uses(i32 %x) {
273; CHECK-LABEL: @is_pow2_ctpop_extra_uses(
274; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
275; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2
276; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
277; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
278; CHECK-NEXT:    call void @use_i1(i1 [[NOTZERO]])
279; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[T0]], 1
280; CHECK-NEXT:    ret i1 [[R]]
281;
282  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
283  %cmp = icmp ult i32 %t0, 2
284  call void @use_i1(i1 %cmp)
285  %notzero = icmp ne i32 %x, 0
286  call void @use_i1(i1 %notzero)
287  %r = and i1 %notzero, %cmp
288  ret i1 %r
289}
290
291define i1 @is_pow2_ctpop_extra_uses_logical(i32 %x) {
292; CHECK-LABEL: @is_pow2_ctpop_extra_uses_logical(
293; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
294; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2
295; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
296; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
297; CHECK-NEXT:    call void @use_i1(i1 [[NOTZERO]])
298; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[T0]], 1
299; CHECK-NEXT:    ret i1 [[R]]
300;
301  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
302  %cmp = icmp ult i32 %t0, 2
303  call void @use_i1(i1 %cmp)
304  %notzero = icmp ne i32 %x, 0
305  call void @use_i1(i1 %notzero)
306  %r = select i1 %notzero, i1 %cmp, i1 false
307  ret i1 %r
308}
309
310; Test vector type and commuted 'and' operands.
311
312define <2 x i1> @is_pow2_ctpop_commute_vec(<2 x i8> %x) {
313; CHECK-LABEL: @is_pow2_ctpop_commute_vec(
314; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
315; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[T0]], splat (i8 1)
316; CHECK-NEXT:    ret <2 x i1> [[R]]
317;
318  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
319  %cmp = icmp ult <2 x i8> %t0, <i8 2, i8 2>
320  %notzero = icmp ne <2 x i8> %x, zeroinitializer
321  %r = and <2 x i1> %cmp, %notzero
322  ret <2 x i1> %r
323}
324
325; Negative test - wrong constant.
326
327define i1 @is_pow2_ctpop_wrong_cmp_op1(i32 %x) {
328; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op1(
329; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
330; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 3
331; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
332; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]
333; CHECK-NEXT:    ret i1 [[R]]
334;
335  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
336  %cmp = icmp ult i32 %t0, 3
337  %notzero = icmp ne i32 %x, 0
338  %r = and i1 %notzero, %cmp
339  ret i1 %r
340}
341
342define i1 @is_pow2_ctpop_wrong_cmp_op1_logical(i32 %x) {
343; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op1_logical(
344; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
345; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 3
346; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
347; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOTZERO]], i1 [[CMP]], i1 false
348; CHECK-NEXT:    ret i1 [[R]]
349;
350  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
351  %cmp = icmp ult i32 %t0, 3
352  %notzero = icmp ne i32 %x, 0
353  %r = select i1 %notzero, i1 %cmp, i1 false
354  ret i1 %r
355}
356
357; Negative test - wrong constant.
358
359define i1 @is_pow2_ctpop_wrong_cmp_op2(i32 %x) {
360; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op2(
361; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
362; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2
363; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 1
364; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]
365; CHECK-NEXT:    ret i1 [[R]]
366;
367  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
368  %cmp = icmp ult i32 %t0, 2
369  %notzero = icmp ne i32 %x, 1
370  %r = and i1 %notzero, %cmp
371  ret i1 %r
372}
373
374define i1 @is_pow2_ctpop_wrong_cmp_op2_logical(i32 %x) {
375; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op2_logical(
376; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
377; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2
378; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 1
379; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOTZERO]], i1 [[CMP]], i1 false
380; CHECK-NEXT:    ret i1 [[R]]
381;
382  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
383  %cmp = icmp ult i32 %t0, 2
384  %notzero = icmp ne i32 %x, 1
385  %r = select i1 %notzero, i1 %cmp, i1 false
386  ret i1 %r
387}
388
389; Negative test - wrong predicate.
390
391define i1 @is_pow2_ctpop_wrong_pred1(i32 %x) {
392; CHECK-LABEL: @is_pow2_ctpop_wrong_pred1(
393; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
394; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 2
395; CHECK-NEXT:    ret i1 [[CMP]]
396;
397  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
398  %cmp = icmp ugt i32 %t0, 2
399  %notzero = icmp ne i32 %x, 0
400  %r = and i1 %notzero, %cmp
401  ret i1 %r
402}
403
404define i1 @is_pow2_ctpop_wrong_pred1_logical(i32 %x) {
405; CHECK-LABEL: @is_pow2_ctpop_wrong_pred1_logical(
406; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
407; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 2
408; CHECK-NEXT:    ret i1 [[CMP]]
409;
410  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
411  %cmp = icmp ugt i32 %t0, 2
412  %notzero = icmp ne i32 %x, 0
413  %r = select i1 %notzero, i1 %cmp, i1 false
414  ret i1 %r
415}
416
417; Negative test - wrong predicate.
418
419define i1 @is_pow2_ctpop_wrong_pred2(i32 %x) {
420; CHECK-LABEL: @is_pow2_ctpop_wrong_pred2(
421; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
422; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2
423; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X]], 0
424; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP2]], [[CMP]]
425; CHECK-NEXT:    ret i1 [[R]]
426;
427  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
428  %cmp = icmp ult i32 %t0, 2
429  %cmp2 = icmp sgt i32 %x, 0
430  %r = and i1 %cmp2, %cmp
431  ret i1 %r
432}
433
434define i1 @is_pow2_ctpop_wrong_pred2_logical(i32 %x) {
435; CHECK-LABEL: @is_pow2_ctpop_wrong_pred2_logical(
436; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
437; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2
438; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X]], 0
439; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP2]], i1 [[CMP]], i1 false
440; CHECK-NEXT:    ret i1 [[R]]
441;
442  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
443  %cmp = icmp ult i32 %t0, 2
444  %cmp2 = icmp sgt i32 %x, 0
445  %r = select i1 %cmp2, i1 %cmp, i1 false
446  ret i1 %r
447}
448
449; (X == 0) || (ctpop(X) u> 1) --> ctpop(X) != 1
450
451define i1 @isnot_pow2_ctpop(i32 %x) {
452; CHECK-LABEL: @isnot_pow2_ctpop(
453; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
454; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[T0]], 1
455; CHECK-NEXT:    ret i1 [[R]]
456;
457  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
458  %cmp = icmp ugt i32 %t0, 1
459  %iszero = icmp eq i32 %x, 0
460  %r = or i1 %iszero, %cmp
461  ret i1 %r
462}
463
464define i1 @isnot_pow2_ctpop_logical(i32 %x) {
465; CHECK-LABEL: @isnot_pow2_ctpop_logical(
466; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
467; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[T0]], 1
468; CHECK-NEXT:    ret i1 [[R]]
469;
470  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
471  %cmp = icmp ugt i32 %t0, 1
472  %iszero = icmp eq i32 %x, 0
473  %r = select i1 %iszero, i1 true, i1 %cmp
474  ret i1 %r
475}
476
477; Extra uses don't change the fold.
478
479define i1 @isnot_pow2_ctpop_extra_uses(i32 %x) {
480; CHECK-LABEL: @isnot_pow2_ctpop_extra_uses(
481; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
482; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1
483; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
484; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
485; CHECK-NEXT:    call void @use_i1(i1 [[ISZERO]])
486; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[T0]], 1
487; CHECK-NEXT:    ret i1 [[R]]
488;
489  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
490  %cmp = icmp ugt i32 %t0, 1
491  call void @use_i1(i1 %cmp)
492  %iszero = icmp eq i32 %x, 0
493  call void @use_i1(i1 %iszero)
494  %r = or i1 %iszero, %cmp
495  ret i1 %r
496}
497
498define i1 @isnot_pow2_ctpop_extra_uses_logical(i32 %x) {
499; CHECK-LABEL: @isnot_pow2_ctpop_extra_uses_logical(
500; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
501; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1
502; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
503; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
504; CHECK-NEXT:    call void @use_i1(i1 [[ISZERO]])
505; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[T0]], 1
506; CHECK-NEXT:    ret i1 [[R]]
507;
508  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
509  %cmp = icmp ugt i32 %t0, 1
510  call void @use_i1(i1 %cmp)
511  %iszero = icmp eq i32 %x, 0
512  call void @use_i1(i1 %iszero)
513  %r = select i1 %iszero, i1 true, i1 %cmp
514  ret i1 %r
515}
516
517; Test vector type and commuted 'or' operands.
518
519define <2 x i1> @isnot_pow2_ctpop_commute_vec(<2 x i8> %x) {
520; CHECK-LABEL: @isnot_pow2_ctpop_commute_vec(
521; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
522; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[T0]], splat (i8 1)
523; CHECK-NEXT:    ret <2 x i1> [[R]]
524;
525  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
526  %cmp = icmp ugt <2 x i8> %t0, <i8 1, i8 1>
527  %iszero = icmp eq <2 x i8> %x, zeroinitializer
528  %r = or <2 x i1> %cmp, %iszero
529  ret <2 x i1> %r
530}
531
532; Negative test - wrong constant.
533
534define i1 @isnot_pow2_ctpop_wrong_cmp_op1(i32 %x) {
535; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op1(
536; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
537; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 2
538; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
539; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
540; CHECK-NEXT:    ret i1 [[R]]
541;
542  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
543  %cmp = icmp ugt i32 %t0, 2
544  %iszero = icmp eq i32 %x, 0
545  %r = or i1 %iszero, %cmp
546  ret i1 %r
547}
548
549define i1 @isnot_pow2_ctpop_wrong_cmp_op1_logical(i32 %x) {
550; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op1_logical(
551; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
552; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 2
553; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
554; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISZERO]], i1 true, i1 [[CMP]]
555; CHECK-NEXT:    ret i1 [[R]]
556;
557  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
558  %cmp = icmp ugt i32 %t0, 2
559  %iszero = icmp eq i32 %x, 0
560  %r = select i1 %iszero, i1 true, i1 %cmp
561  ret i1 %r
562}
563
564; Negative test - wrong constant.
565
566define i1 @isnot_pow2_ctpop_wrong_cmp_op2(i32 %x) {
567; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op2(
568; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
569; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1
570; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 1
571; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
572; CHECK-NEXT:    ret i1 [[R]]
573;
574  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
575  %cmp = icmp ugt i32 %t0, 1
576  %iszero = icmp eq i32 %x, 1
577  %r = or i1 %iszero, %cmp
578  ret i1 %r
579}
580
581define i1 @isnot_pow2_ctpop_wrong_cmp_op2_logical(i32 %x) {
582; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op2_logical(
583; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
584; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1
585; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 1
586; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISZERO]], i1 true, i1 [[CMP]]
587; CHECK-NEXT:    ret i1 [[R]]
588;
589  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
590  %cmp = icmp ugt i32 %t0, 1
591  %iszero = icmp eq i32 %x, 1
592  %r = select i1 %iszero, i1 true, i1 %cmp
593  ret i1 %r
594}
595
596; Negative test - wrong predicate.
597
598define i1 @isnot_pow2_ctpop_wrong_pred2(i32 %x) {
599; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred2(
600; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
601; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1
602; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 0
603; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP2]], [[CMP]]
604; CHECK-NEXT:    ret i1 [[R]]
605;
606  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
607  %cmp = icmp ugt i32 %t0, 1
608  %cmp2 = icmp slt i32 %x, 0
609  %r = or i1 %cmp2, %cmp
610  ret i1 %r
611}
612
613define i1 @isnot_pow2_ctpop_wrong_pred2_logical(i32 %x) {
614; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred2_logical(
615; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
616; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1
617; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 0
618; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP2]], i1 true, i1 [[CMP]]
619; CHECK-NEXT:    ret i1 [[R]]
620;
621  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
622  %cmp = icmp ugt i32 %t0, 1
623  %cmp2 = icmp slt i32 %x, 0
624  %r = select i1 %cmp2, i1 true, i1 %cmp
625  ret i1 %r
626}
627
628define i1 @is_pow2_negate_op(i32 %x) {
629; CHECK-LABEL: @is_pow2_negate_op(
630; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
631; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 1
632; CHECK-NEXT:    ret i1 [[R]]
633;
634  %neg = sub i32 0, %x
635  %and = and i32 %neg, %x
636  %cmp = icmp eq i32 %and, %x
637  %notzero = icmp ne i32 %x, 0
638  %r = and i1 %notzero, %cmp
639  ret i1 %r
640}
641
642define i1 @is_pow2_negate_op_logical(i32 %x) {
643; CHECK-LABEL: @is_pow2_negate_op_logical(
644; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
645; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 1
646; CHECK-NEXT:    ret i1 [[R]]
647;
648  %neg = sub i32 0, %x
649  %and = and i32 %neg, %x
650  %cmp = icmp eq i32 %and, %x
651  %notzero = icmp ne i32 %x, 0
652  %r = select i1 %notzero, i1 %cmp, i1 false
653  ret i1 %r
654}
655
656define <2 x i1> @is_pow2_negate_op_vec(<2 x i32> %x) {
657; CHECK-LABEL: @is_pow2_negate_op_vec(
658; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])
659; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 1)
660; CHECK-NEXT:    ret <2 x i1> [[R]]
661;
662  %neg = sub <2 x i32> zeroinitializer, %x
663  %and = and <2 x i32> %neg, %x
664  %cmp = icmp eq <2 x i32> %and, %x
665  %notzero = icmp ne <2 x i32> %x, zeroinitializer
666  %r = and <2 x i1> %cmp, %notzero
667  ret <2 x i1> %r
668}
669
670define i1 @is_pow2_decrement_op(i8 %x) {
671; CHECK-LABEL: @is_pow2_decrement_op(
672; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])
673; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], 1
674; CHECK-NEXT:    ret i1 [[R]]
675;
676  %dec = add i8 %x, -1
677  %and = and i8 %dec, %x
678  %cmp = icmp eq i8 %and, 0
679  %notzero = icmp ne i8 %x, 0
680  %r = and i1 %cmp, %notzero
681  ret i1 %r
682}
683
684define i1 @is_pow2_decrement_op_logical(i8 %x) {
685; CHECK-LABEL: @is_pow2_decrement_op_logical(
686; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])
687; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], 1
688; CHECK-NEXT:    ret i1 [[R]]
689;
690  %dec = add i8 %x, -1
691  %and = and i8 %dec, %x
692  %cmp = icmp eq i8 %and, 0
693  %notzero = icmp ne i8 %x, 0
694  %r = select i1 %cmp, i1 %notzero, i1 false
695  ret i1 %r
696}
697
698define <2 x i1> @is_pow2_decrement_op_vec(<2 x i8> %x) {
699; CHECK-LABEL: @is_pow2_decrement_op_vec(
700; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
701; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], splat (i8 1)
702; CHECK-NEXT:    ret <2 x i1> [[R]]
703;
704  %dec = add <2 x i8> %x, <i8 -1, i8 -1>
705  %and = and <2 x i8> %dec, %x
706  %cmp = icmp eq <2 x i8> %and, zeroinitializer
707  %notzero = icmp ne <2 x i8> %x, zeroinitializer
708  %r = and <2 x i1> %notzero, %cmp
709  ret <2 x i1> %r
710}
711
712define i1 @isnot_pow2_negate_op(i32 %x) {
713; CHECK-LABEL: @isnot_pow2_negate_op(
714; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
715; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 1
716; CHECK-NEXT:    ret i1 [[R]]
717;
718  %neg = sub i32 0, %x
719  %and = and i32 %neg, %x
720  %cmp = icmp ne i32 %and, %x
721  %iszero = icmp eq i32 %x, 0
722  %r = or i1 %cmp, %iszero
723  ret i1 %r
724}
725
726define i1 @isnot_pow2_negate_op_logical(i32 %x) {
727; CHECK-LABEL: @isnot_pow2_negate_op_logical(
728; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
729; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 1
730; CHECK-NEXT:    ret i1 [[R]]
731;
732  %neg = sub i32 0, %x
733  %and = and i32 %neg, %x
734  %cmp = icmp ne i32 %and, %x
735  %iszero = icmp eq i32 %x, 0
736  %r = select i1 %cmp, i1 true, i1 %iszero
737  ret i1 %r
738}
739
740define <2 x i1> @isnot_pow2_negate_op_vec(<2 x i32> %x) {
741; CHECK-LABEL: @isnot_pow2_negate_op_vec(
742; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])
743; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 1)
744; CHECK-NEXT:    ret <2 x i1> [[R]]
745;
746  %neg = sub <2 x i32> zeroinitializer, %x
747  %and = and <2 x i32> %neg, %x
748  %cmp = icmp ne <2 x i32> %and, %x
749  %iszero = icmp eq <2 x i32> %x, zeroinitializer
750  %r = or <2 x i1> %iszero, %cmp
751  ret <2 x i1> %r
752}
753
754define i1 @isnot_pow2_decrement_op(i8 %x) {
755; CHECK-LABEL: @isnot_pow2_decrement_op(
756; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])
757; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[TMP1]], 1
758; CHECK-NEXT:    ret i1 [[R]]
759;
760  %dec = add i8 %x, -1
761  %and = and i8 %dec, %x
762  %cmp = icmp ne i8 %and, 0
763  %iszero = icmp eq i8 %x, 0
764  %r = or i1 %iszero, %cmp
765  ret i1 %r
766}
767
768define i1 @isnot_pow2_decrement_op_logical(i8 %x) {
769; CHECK-LABEL: @isnot_pow2_decrement_op_logical(
770; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])
771; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[TMP1]], 1
772; CHECK-NEXT:    ret i1 [[R]]
773;
774  %dec = add i8 %x, -1
775  %and = and i8 %dec, %x
776  %cmp = icmp ne i8 %and, 0
777  %iszero = icmp eq i8 %x, 0
778  %r = select i1 %iszero, i1 true, i1 %cmp
779  ret i1 %r
780}
781
782define <2 x i1> @isnot_pow2_decrement_op_vec(<2 x i8> %x) {
783; CHECK-LABEL: @isnot_pow2_decrement_op_vec(
784; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
785; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[TMP1]], splat (i8 1)
786; CHECK-NEXT:    ret <2 x i1> [[R]]
787;
788  %dec = add <2 x i8> %x, <i8 -1, i8 -1>
789  %and = and <2 x i8> %dec, %x
790  %cmp = icmp ne <2 x i8> %and, zeroinitializer
791  %iszero = icmp eq <2 x i8> %x, zeroinitializer
792  %r = or <2 x i1> %cmp, %iszero
793  ret <2 x i1> %r
794}
795
796; (ctpop(X) == 1) || (X == 0) --> ctpop(X) u< 2
797
798define i1 @is_pow2or0_ctpop(i32 %x) {
799; CHECK-LABEL: @is_pow2or0_ctpop(
800; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
801; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2
802; CHECK-NEXT:    ret i1 [[R]]
803;
804  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
805  %cmp = icmp eq i32 %t0, 1
806  %iszero = icmp eq i32 %x, 0
807  %r = or i1 %iszero, %cmp
808  ret i1 %r
809}
810
811define i1 @is_pow2or0_ctpop_swap_cmp(i32 %x) {
812; CHECK-LABEL: @is_pow2or0_ctpop_swap_cmp(
813; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
814; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2
815; CHECK-NEXT:    ret i1 [[R]]
816;
817  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
818  %cmp = icmp eq i32 %t0, 1
819  %iszero = icmp eq i32 %x, 0
820  %r = or i1 %cmp, %iszero
821  ret i1 %r
822}
823
824define i1 @is_pow2or0_ctpop_logical(i32 %x) {
825; CHECK-LABEL: @is_pow2or0_ctpop_logical(
826; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
827; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2
828; CHECK-NEXT:    ret i1 [[R]]
829;
830  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
831  %cmp = icmp eq i32 %t0, 1
832  %iszero = icmp eq i32 %x, 0
833  %r = select i1 %iszero, i1 true, i1 %cmp
834  ret i1 %r
835}
836
837define <2 x i1> @is_pow2or0_ctpop_commute_vec(<2 x i8> %x) {
838; CHECK-LABEL: @is_pow2or0_ctpop_commute_vec(
839; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
840; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult <2 x i8> [[T0]], splat (i8 2)
841; CHECK-NEXT:    ret <2 x i1> [[R]]
842;
843  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
844  %cmp = icmp eq <2 x i8> %t0, <i8 1, i8 1>
845  %iszero = icmp eq <2 x i8> %x, <i8 0, i8 0>
846  %r = or <2 x i1> %iszero, %cmp
847  ret <2 x i1> %r
848}
849
850; Extra uses don't change the fold.
851
852define i1 @is_pow2or0_ctpop_extra_uses(i32 %x) {
853; CHECK-LABEL: @is_pow2or0_ctpop_extra_uses(
854; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
855; CHECK-NEXT:    call void @use(i32 [[T0]])
856; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 1
857; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
858; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
859; CHECK-NEXT:    call void @use_i1(i1 [[ISZERO]])
860; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2
861; CHECK-NEXT:    ret i1 [[R]]
862;
863  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
864  call void @use(i32 %t0)
865  %cmp = icmp eq i32 %t0, 1
866  call void @use_i1(i1 %cmp)
867  %iszero = icmp eq i32 %x, 0
868  call void @use_i1(i1 %iszero)
869  %r = or i1 %iszero, %cmp
870  ret i1 %r
871}
872
873define i1 @is_pow2or0_ctpop_logical_extra_uses(i32 %x) {
874; CHECK-LABEL: @is_pow2or0_ctpop_logical_extra_uses(
875; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
876; CHECK-NEXT:    call void @use(i32 [[T0]])
877; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 1
878; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
879; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
880; CHECK-NEXT:    call void @use_i1(i1 [[ISZERO]])
881; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2
882; CHECK-NEXT:    ret i1 [[R]]
883;
884  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
885  call void @use(i32 %t0)
886  %cmp = icmp eq i32 %t0, 1
887  call void @use_i1(i1 %cmp)
888  %iszero = icmp eq i32 %x, 0
889  call void @use_i1(i1 %iszero)
890  %r = select i1 %iszero, i1 true, i1 %cmp
891  ret i1 %r
892}
893
894; Negative test - wrong constant.
895
896define i1 @is_pow2or0_ctpop_wrong_cmp_op1(i32 %x) {
897; CHECK-LABEL: @is_pow2or0_ctpop_wrong_cmp_op1(
898; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
899; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 2
900; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
901; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
902; CHECK-NEXT:    ret i1 [[R]]
903;
904  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
905  %cmp = icmp eq i32 %t0, 2
906  %iszero = icmp eq i32 %x, 0
907  %r = or i1 %iszero, %cmp
908  ret i1 %r
909}
910
911define i1 @is_pow2or0_ctpop_wrong_cmp_op1_logical(i32 %x) {
912; CHECK-LABEL: @is_pow2or0_ctpop_wrong_cmp_op1_logical(
913; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
914; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 3
915; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
916; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISZERO]], i1 true, i1 [[CMP]]
917; CHECK-NEXT:    ret i1 [[R]]
918;
919  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
920  %cmp = icmp eq i32 %t0, 3
921  %iszero = icmp eq i32 %x, 0
922  %r = select i1 %iszero, i1 true, i1 %cmp
923  ret i1 %r
924}
925
926define <2 x i1> @is_pow2or0_ctpop_commute_vec_wrong_cmp_op1(<2 x i8> %x) {
927; CHECK-LABEL: @is_pow2or0_ctpop_commute_vec_wrong_cmp_op1(
928; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
929; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[T0]], <i8 -1, i8 1>
930; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq <2 x i8> [[X]], zeroinitializer
931; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[CMP]], [[ISZERO]]
932; CHECK-NEXT:    ret <2 x i1> [[R]]
933;
934  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
935  %cmp = icmp eq <2 x i8> %t0, <i8 -1, i8 1>
936  %iszero = icmp eq <2 x i8> %x, <i8 0, i8 0>
937  %r = or <2 x i1> %cmp, %iszero
938  ret <2 x i1> %r
939}
940
941; Negative test - wrong predicate.
942
943define i1 @is_pow2or0_ctpop_wrong_pred1(i32 %x) {
944; CHECK-LABEL: @is_pow2or0_ctpop_wrong_pred1(
945; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
946; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 1
947; CHECK-NEXT:    ret i1 [[CMP]]
948;
949  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
950  %cmp = icmp ne i32 %t0, 1
951  %iszero = icmp eq i32 %x, 0
952  %r = or i1 %iszero, %cmp
953  ret i1 %r
954}
955
956define i1 @is_pow2or0_ctpop_wrong_pred2(i32 %x) {
957; CHECK-LABEL: @is_pow2or0_ctpop_wrong_pred2(
958; CHECK-NEXT:    ret i1 true
959;
960  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
961  %cmp = icmp ne i32 %t0, 1
962  %iszero = icmp ne i32 %x, 0
963  %r = or i1 %iszero, %cmp
964  ret i1 %r
965}
966
967define i1 @is_pow2or0_ctpop_wrong_pred2_logical(i32 %x) {
968; CHECK-LABEL: @is_pow2or0_ctpop_wrong_pred2_logical(
969; CHECK-NEXT:    ret i1 true
970;
971  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
972  %cmp = icmp ne i32 %t0, 1
973  %iszero = icmp ne i32 %x, 0
974  %r = select i1 %iszero, i1 true, i1 %cmp
975  ret i1 %r
976}
977
978define <2 x i1> @is_pow2or0_ctpop_commute_vec_wrong_pred3(<2 x i8> %x) {
979; CHECK-LABEL: @is_pow2or0_ctpop_commute_vec_wrong_pred3(
980; CHECK-NEXT:    ret <2 x i1> zeroinitializer
981;
982  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
983  %cmp = icmp eq <2 x i8> %t0, <i8 1, i8 1>
984  %iszero = icmp eq <2 x i8> %x, <i8 0, i8 0>
985  %r = and <2 x i1> %cmp, %iszero
986  ret <2 x i1> %r
987}
988
989; (ctpop(X) != 1) && (X != 0) --> ctpop(X) u> 1
990
991define i1 @isnot_pow2nor0_ctpop(i32 %x) {
992; CHECK-LABEL: @isnot_pow2nor0_ctpop(
993; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
994; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 1
995; CHECK-NEXT:    ret i1 [[R]]
996;
997  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
998  %cmp = icmp ne i32 %t0, 1
999  %notzero = icmp ne i32 %x, 0
1000  %r = and i1 %notzero, %cmp
1001  ret i1 %r
1002}
1003
1004define i1 @isnot_pow2nor0_ctpop_swap_cmp(i32 %x) {
1005; CHECK-LABEL: @isnot_pow2nor0_ctpop_swap_cmp(
1006; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1007; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 1
1008; CHECK-NEXT:    ret i1 [[R]]
1009;
1010  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
1011  %cmp = icmp ne i32 %t0, 1
1012  %notzero = icmp ne i32 %x, 0
1013  %r = and i1 %cmp, %notzero
1014  ret i1 %r
1015}
1016
1017define i1 @isnot_pow2nor0_ctpop_logical(i32 %x) {
1018; CHECK-LABEL: @isnot_pow2nor0_ctpop_logical(
1019; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1020; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 1
1021; CHECK-NEXT:    ret i1 [[R]]
1022;
1023  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
1024  %cmp = icmp ne i32 %t0, 1
1025  %notzero = icmp ne i32 %x, 0
1026  %r = select i1 %notzero, i1 %cmp, i1 false
1027  ret i1 %r
1028}
1029
1030define <2 x i1> @isnot_pow2nor0_ctpop_commute_vec(<2 x i8> %x) {
1031; CHECK-LABEL: @isnot_pow2nor0_ctpop_commute_vec(
1032; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
1033; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt <2 x i8> [[T0]], splat (i8 1)
1034; CHECK-NEXT:    ret <2 x i1> [[R]]
1035;
1036  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
1037  %cmp = icmp ne <2 x i8> %t0, <i8 1, i8 1>
1038  %notzero = icmp ne <2 x i8> %x, <i8 0, i8 0>
1039  %r = and <2 x i1> %notzero, %cmp
1040  ret <2 x i1> %r
1041}
1042
1043; Extra uses don't change the fold.
1044
1045define i1 @isnot_pow2nor0_ctpop_extra_uses(i32 %x) {
1046; CHECK-LABEL: @isnot_pow2nor0_ctpop_extra_uses(
1047; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1048; CHECK-NEXT:    call void @use(i32 [[T0]])
1049; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 1
1050; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
1051; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
1052; CHECK-NEXT:    call void @use_i1(i1 [[NOTZERO]])
1053; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 1
1054; CHECK-NEXT:    ret i1 [[R]]
1055;
1056  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
1057  call void @use(i32 %t0)
1058  %cmp = icmp ne i32 %t0, 1
1059  call void @use_i1(i1 %cmp)
1060  %notzero = icmp ne i32 %x, 0
1061  call void @use_i1(i1 %notzero)
1062  %r = and i1 %notzero, %cmp
1063  ret i1 %r
1064}
1065
1066define i1 @isnot_pow2nor0_ctpop_logical_extra_uses(i32 %x) {
1067; CHECK-LABEL: @isnot_pow2nor0_ctpop_logical_extra_uses(
1068; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1069; CHECK-NEXT:    call void @use(i32 [[T0]])
1070; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 1
1071; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
1072; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
1073; CHECK-NEXT:    call void @use_i1(i1 [[NOTZERO]])
1074; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 1
1075; CHECK-NEXT:    ret i1 [[R]]
1076;
1077  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
1078  call void @use(i32 %t0)
1079  %cmp = icmp ne i32 %t0, 1
1080  call void @use_i1(i1 %cmp)
1081  %notzero = icmp ne i32 %x, 0
1082  call void @use_i1(i1 %notzero)
1083  %r = select i1 %notzero, i1 %cmp, i1 false
1084  ret i1 %r
1085}
1086
1087; Negative test - wrong constant.
1088
1089define i1 @isnot_pow2nor0_ctpop_wrong_cmp_op1(i32 %x) {
1090; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_cmp_op1(
1091; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1092; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 4
1093; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
1094; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]
1095; CHECK-NEXT:    ret i1 [[R]]
1096;
1097  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
1098  %cmp = icmp ne i32 %t0, 4
1099  %notzero = icmp ne i32 %x, 0
1100  %r = and i1 %notzero, %cmp
1101  ret i1 %r
1102}
1103
1104define i1 @isnot_pow2nor0_ctpop_wrong_cmp_op1_logical(i32 %x) {
1105; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_cmp_op1_logical(
1106; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1107; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 5
1108; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
1109; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOTZERO]], i1 [[CMP]], i1 false
1110; CHECK-NEXT:    ret i1 [[R]]
1111;
1112  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
1113  %cmp = icmp ne i32 %t0, 5
1114  %notzero = icmp ne i32 %x, 0
1115  %r = select i1 %notzero, i1 %cmp, i1 false
1116  ret i1 %r
1117}
1118
1119define <2 x i1> @isnot_pow2nor0_ctpop_commute_vec_wrong_cmp_op1(<2 x i8> %x) {
1120; CHECK-LABEL: @isnot_pow2nor0_ctpop_commute_vec_wrong_cmp_op1(
1121; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
1122; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i8> [[T0]], <i8 0, i8 -1>
1123; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne <2 x i8> [[X]], zeroinitializer
1124; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[CMP]], [[NOTZERO]]
1125; CHECK-NEXT:    ret <2 x i1> [[R]]
1126;
1127  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
1128  %cmp = icmp ne <2 x i8> %t0, <i8 0, i8 -1>
1129  %notzero = icmp ne <2 x i8> %x, <i8 0, i8 0>
1130  %r = and <2 x i1> %cmp, %notzero
1131  ret <2 x i1> %r
1132}
1133
1134; Negative test - wrong predicate.
1135
1136define i1 @isnot_pow2nor0_ctpop_wrong_pred1(i32 %x) {
1137; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_pred1(
1138; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1139; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 1
1140; CHECK-NEXT:    ret i1 [[CMP]]
1141;
1142  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
1143  %cmp = icmp eq i32 %t0, 1
1144  %notzero = icmp ne i32 %x, 0
1145  %r = and i1 %notzero, %cmp
1146  ret i1 %r
1147}
1148
1149define i1 @isnot_pow2nor0_ctpop_wrong_pred2(i32 %x) {
1150; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_pred2(
1151; CHECK-NEXT:    ret i1 false
1152;
1153  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
1154  %cmp = icmp eq i32 %t0, 1
1155  %notzero = icmp eq i32 %x, 0
1156  %r = and i1 %notzero, %cmp
1157  ret i1 %r
1158}
1159
1160define i1 @isnot_pow2nor0_ctpop_wrong_pred2_logical(i32 %x) {
1161; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_pred2_logical(
1162; CHECK-NEXT:    ret i1 false
1163;
1164  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
1165  %cmp = icmp eq i32 %t0, 1
1166  %notzero = icmp eq i32 %x, 0
1167  %r = select i1 %notzero, i1 %cmp, i1 false
1168  ret i1 %r
1169}
1170
1171define <2 x i1> @isnot_pow2nor0_wrong_pred3_ctpop_commute_vec(<2 x i8> %x) {
1172; CHECK-LABEL: @isnot_pow2nor0_wrong_pred3_ctpop_commute_vec(
1173; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1174;
1175  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)
1176  %cmp = icmp ne <2 x i8> %t0, <i8 1, i8 1>
1177  %notzero = icmp ne <2 x i8> %x, <i8 0, i8 0>
1178  %r = or <2 x i1> %cmp, %notzero
1179  ret <2 x i1> %r
1180}
1181
1182define i1 @is_pow2_fail_pr63327(i32 %x) {
1183; CHECK-LABEL: @is_pow2_fail_pr63327(
1184; CHECK-NEXT:    [[NX:%.*]] = sub i32 0, [[X:%.*]]
1185; CHECK-NEXT:    [[X_AND_NX:%.*]] = and i32 [[X]], [[NX]]
1186; CHECK-NEXT:    [[R:%.*]] = icmp sge i32 [[X_AND_NX]], [[X]]
1187; CHECK-NEXT:    ret i1 [[R]]
1188;
1189  %nx = sub i32 0, %x
1190  %x_and_nx = and i32 %x, %nx
1191  %r = icmp sge i32 %x_and_nx, %x
1192  ret i1 %r
1193}
1194
1195define i1 @blsmsk_is_p2_or_z(i32 %xx, i32 %yy) {
1196; CHECK-LABEL: @blsmsk_is_p2_or_z(
1197; CHECK-NEXT:    [[X:%.*]] = or i32 [[XX:%.*]], [[YY:%.*]]
1198; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X]], -1
1199; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X]], [[XM1]]
1200; CHECK-NEXT:    [[R:%.*]] = icmp uge i32 [[X]], [[Y]]
1201; CHECK-NEXT:    ret i1 [[R]]
1202;
1203  %x = or i32 %xx, %yy
1204  %xm1 = add i32 %x, -1
1205  %y = xor i32 %x, %xm1
1206  %r = icmp uge i32 %x, %y
1207  ret i1 %r
1208}
1209
1210define i1 @blsmsk_isnt_p2_or_z(i32 %x) {
1211; CHECK-LABEL: @blsmsk_isnt_p2_or_z(
1212; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1213; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[TMP1]], 1
1214; CHECK-NEXT:    ret i1 [[R]]
1215;
1216  %xm1 = add i32 %x, -1
1217  %y = xor i32 %x, %xm1
1218  %r = icmp ult i32 %y, %x
1219  ret i1 %r
1220}
1221
1222define i1 @blsmsk_is_p2_or_z_fail(i32 %xx, i32 %yy) {
1223; CHECK-LABEL: @blsmsk_is_p2_or_z_fail(
1224; CHECK-NEXT:    [[X:%.*]] = or i32 [[XX:%.*]], [[YY:%.*]]
1225; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])
1226; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[TMP1]], 1
1227; CHECK-NEXT:    ret i1 [[R]]
1228;
1229  %x = or i32 %xx, %yy
1230  %xm1 = add i32 %x, -1
1231  %y = xor i32 %x, %xm1
1232  %r = icmp ugt i32 %x, %y
1233  ret i1 %r
1234}
1235
1236define i1 @blsmsk_isnt_p2_or_z_fail(i32 %x) {
1237; CHECK-LABEL: @blsmsk_isnt_p2_or_z_fail(
1238; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X:%.*]], -1
1239; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X]], [[XM1]]
1240; CHECK-NEXT:    [[R:%.*]] = icmp ule i32 [[Y]], [[X]]
1241; CHECK-NEXT:    ret i1 [[R]]
1242;
1243  %xm1 = add i32 %x, -1
1244  %y = xor i32 %x, %xm1
1245  %r = icmp ule i32 %y, %x
1246  ret i1 %r
1247}
1248
1249declare void @use.i32(i32)
1250
1251define i1 @blsmsk_isnt_p2_or_z_fail_multiuse(i32 %x) {
1252; CHECK-LABEL: @blsmsk_isnt_p2_or_z_fail_multiuse(
1253; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X:%.*]], -1
1254; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X]], [[XM1]]
1255; CHECK-NEXT:    call void @use.i32(i32 [[Y]])
1256; CHECK-NEXT:    [[R:%.*]] = icmp ult i32 [[Y]], [[X]]
1257; CHECK-NEXT:    ret i1 [[R]]
1258;
1259  %xm1 = add i32 %x, -1
1260  %y = xor i32 %x, %xm1
1261  call void @use.i32(i32 %y)
1262  %r = icmp ult i32 %y, %x
1263  ret i1 %r
1264}
1265
1266define i1 @blsmsk_isnt_p2_or_z_fail_wrong_add(i32 %x, i32 %z) {
1267; CHECK-LABEL: @blsmsk_isnt_p2_or_z_fail_wrong_add(
1268; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[Z:%.*]], -1
1269; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X:%.*]], [[XM1]]
1270; CHECK-NEXT:    [[R:%.*]] = icmp ult i32 [[Y]], [[X]]
1271; CHECK-NEXT:    ret i1 [[R]]
1272;
1273  %xm1 = add i32 %z, -1
1274  %y = xor i32 %x, %xm1
1275  %r = icmp ult i32 %y, %x
1276  ret i1 %r
1277}
1278
1279
1280define i1 @blsmsk_isnt_p2_or_z_fail_bad_xor(i32 %x, i32 %z) {
1281; CHECK-LABEL: @blsmsk_isnt_p2_or_z_fail_bad_xor(
1282; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X:%.*]], -1
1283; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[Z:%.*]], [[XM1]]
1284; CHECK-NEXT:    [[R:%.*]] = icmp ult i32 [[Y]], [[X]]
1285; CHECK-NEXT:    ret i1 [[R]]
1286;
1287  %xm1 = add i32 %x, -1
1288  %y = xor i32 %z, %xm1
1289  %r = icmp ult i32 %y, %x
1290  ret i1 %r
1291}
1292
1293
1294define i1 @blsmsk_is_p2_or_z_fail_bad_cmp(i32 %x, i32 %z) {
1295; CHECK-LABEL: @blsmsk_is_p2_or_z_fail_bad_cmp(
1296; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X:%.*]], -1
1297; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X]], [[XM1]]
1298; CHECK-NEXT:    [[R:%.*]] = icmp uge i32 [[Y]], [[Z:%.*]]
1299; CHECK-NEXT:    ret i1 [[R]]
1300;
1301  %xm1 = add i32 %x, -1
1302  %y = xor i32 %x, %xm1
1303  %r = icmp uge i32 %y, %z
1304  ret i1 %r
1305}
1306
1307define i1 @blsmsk_is_p2_or_z_ule_xy(i8 %xx, i8 %yy) {
1308; CHECK-LABEL: @blsmsk_is_p2_or_z_ule_xy(
1309; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]
1310; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X]])
1311; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i8 [[TMP1]], 2
1312; CHECK-NEXT:    ret i1 [[R]]
1313;
1314  %x = or i8 %xx, %yy
1315  %xm1 = add i8 %x, -1
1316  %y = xor i8 %x, %xm1
1317  %r = icmp ule i8 %x, %y
1318  ret i1 %r
1319}
1320
1321
1322define i1 @blsmsk_is_p2_or_z_ule_yx_fail(i8 %xx, i8 %yy) {
1323; CHECK-LABEL: @blsmsk_is_p2_or_z_ule_yx_fail(
1324; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]
1325; CHECK-NEXT:    [[XM1:%.*]] = add i8 [[X]], -1
1326; CHECK-NEXT:    [[Y:%.*]] = xor i8 [[X]], [[XM1]]
1327; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[Y]], [[X]]
1328; CHECK-NEXT:    ret i1 [[R]]
1329;
1330  %x = or i8 %xx, %yy
1331  %xm1 = add i8 %x, -1
1332  %y = xor i8 %x, %xm1
1333  %r = icmp ule i8 %y, %x
1334  ret i1 %r
1335}
1336
1337
1338define i1 @blsmsk_is_p2_or_z_uge_yx(i8 %xx, i8 %yy) {
1339; CHECK-LABEL: @blsmsk_is_p2_or_z_uge_yx(
1340; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]
1341; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X]])
1342; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i8 [[TMP1]], 2
1343; CHECK-NEXT:    ret i1 [[R]]
1344;
1345  %x = or i8 %xx, %yy
1346  %xm1 = add i8 %x, -1
1347  %y = xor i8 %x, %xm1
1348  %r = icmp uge i8 %y, %x
1349  ret i1 %r
1350}
1351
1352
1353define i1 @blsmsk_is_p2_or_z_uge_xy_fail(i8 %xx, i8 %yy) {
1354; CHECK-LABEL: @blsmsk_is_p2_or_z_uge_xy_fail(
1355; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]
1356; CHECK-NEXT:    [[XM1:%.*]] = add i8 [[X]], -1
1357; CHECK-NEXT:    [[Y:%.*]] = xor i8 [[X]], [[XM1]]
1358; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[X]], [[Y]]
1359; CHECK-NEXT:    ret i1 [[R]]
1360;
1361  %x = or i8 %xx, %yy
1362  %xm1 = add i8 %x, -1
1363  %y = xor i8 %x, %xm1
1364  %r = icmp uge i8 %x, %y
1365  ret i1 %r
1366}
1367
1368define i1 @blsmsk_isnt_p2_or_z_ugt_xy(i8 %xx, i8 %yy) {
1369; CHECK-LABEL: @blsmsk_isnt_p2_or_z_ugt_xy(
1370; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]
1371; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X]])
1372; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i8 [[TMP1]], 1
1373; CHECK-NEXT:    ret i1 [[R]]
1374;
1375  %x = or i8 %xx, %yy
1376  %xm1 = add i8 %x, -1
1377  %y = xor i8 %x, %xm1
1378  %r = icmp ugt i8 %x, %y
1379  ret i1 %r
1380}
1381
1382
1383define i1 @blsmsk_isnt_p2_or_z_ugt_yx_fail(i8 %xx, i8 %yy) {
1384; CHECK-LABEL: @blsmsk_isnt_p2_or_z_ugt_yx_fail(
1385; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]
1386; CHECK-NEXT:    [[XM1:%.*]] = add i8 [[X]], -1
1387; CHECK-NEXT:    [[Y:%.*]] = xor i8 [[X]], [[XM1]]
1388; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[Y]], [[X]]
1389; CHECK-NEXT:    ret i1 [[R]]
1390;
1391  %x = or i8 %xx, %yy
1392  %xm1 = add i8 %x, -1
1393  %y = xor i8 %x, %xm1
1394  %r = icmp ugt i8 %y, %x
1395  ret i1 %r
1396}
1397
1398
1399define i1 @blsmsk_isnt_p2_or_z_ult_yx(i8 %xx, i8 %yy) {
1400; CHECK-LABEL: @blsmsk_isnt_p2_or_z_ult_yx(
1401; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]
1402; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X]])
1403; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i8 [[TMP1]], 1
1404; CHECK-NEXT:    ret i1 [[R]]
1405;
1406  %x = or i8 %xx, %yy
1407  %xm1 = add i8 %x, -1
1408  %y = xor i8 %x, %xm1
1409  %r = icmp ult i8 %y, %x
1410  ret i1 %r
1411}
1412
1413
1414define i1 @blsmsk_isnt_p2_or_z_ult_xy_fail(i8 %xx, i8 %yy) {
1415; CHECK-LABEL: @blsmsk_isnt_p2_or_z_ult_xy_fail(
1416; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]
1417; CHECK-NEXT:    [[XM1:%.*]] = add i8 [[X]], -1
1418; CHECK-NEXT:    [[Y:%.*]] = xor i8 [[X]], [[XM1]]
1419; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X]], [[Y]]
1420; CHECK-NEXT:    ret i1 [[R]]
1421;
1422  %x = or i8 %xx, %yy
1423  %xm1 = add i8 %x, -1
1424  %y = xor i8 %x, %xm1
1425  %r = icmp ult i8 %x, %y
1426  ret i1 %r
1427}
1428
1429declare <2 x i32> @llvm.ctpop.2xi32(<2 x i32>)
1430define i1 @is_pow2_nz_known_bits(i32 %xin) {
1431; CHECK-LABEL: @is_pow2_nz_known_bits(
1432; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[XIN:%.*]], -65
1433; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 0
1434; CHECK-NEXT:    ret i1 [[R]]
1435;
1436  %x = or i32 %xin, 64
1437  %cnt = call i32 @llvm.ctpop.i32(i32 %x)
1438  %r = icmp eq i32 %cnt, 1
1439  ret i1 %r
1440}
1441
1442define i1 @is_pow2_nz_known_bits_fail_multiuse(i32 %xin) {
1443; CHECK-LABEL: @is_pow2_nz_known_bits_fail_multiuse(
1444; CHECK-NEXT:    [[X:%.*]] = or i32 [[XIN:%.*]], 64
1445; CHECK-NEXT:    [[CNT:%.*]] = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])
1446; CHECK-NEXT:    call void @use.i32(i32 [[CNT]])
1447; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[CNT]], 1
1448; CHECK-NEXT:    ret i1 [[R]]
1449;
1450  %x = or i32 %xin, 64
1451  %cnt = call i32 @llvm.ctpop.i32(i32 %x)
1452  call void @use.i32(i32 %cnt)
1453  %r = icmp eq i32 %cnt, 1
1454  ret i1 %r
1455}
1456
1457define i1 @not_pow2_nz_known_bits(i32 %xin) {
1458; CHECK-LABEL: @not_pow2_nz_known_bits(
1459; CHECK-NEXT:    [[R:%.*]] = icmp ugt i32 [[XIN:%.*]], 1
1460; CHECK-NEXT:    ret i1 [[R]]
1461;
1462  %x = or i32 %xin, 1
1463  %cnt = call i32 @llvm.ctpop.i32(i32 %x)
1464  %r = icmp ne i32 %cnt, 1
1465  ret i1 %r
1466}
1467
1468define i1 @not_pow2_nz_known_bits_fail_not_p2_test(i32 %xin) {
1469; CHECK-LABEL: @not_pow2_nz_known_bits_fail_not_p2_test(
1470; CHECK-NEXT:    [[X:%.*]] = or i32 [[XIN:%.*]], 1
1471; CHECK-NEXT:    [[CNT:%.*]] = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])
1472; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[CNT]], 2
1473; CHECK-NEXT:    ret i1 [[R]]
1474;
1475  %x = or i32 %xin, 1
1476  %cnt = call i32 @llvm.ctpop.i32(i32 %x)
1477  %r = icmp ne i32 %cnt, 2
1478  ret i1 %r
1479}
1480
1481define i1 @is_pow2_or_z_known_bits(i32 %xin) {
1482; CHECK-LABEL: @is_pow2_or_z_known_bits(
1483; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[XIN:%.*]], 2147483647
1484; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 0
1485; CHECK-NEXT:    ret i1 [[R]]
1486;
1487  %x = or i32 %xin, 2147483648
1488  %cnt = call i32 @llvm.ctpop.i32(i32 %x)
1489  %r = icmp ult i32 %cnt, 2
1490  ret i1 %r
1491}
1492
1493define <2 x i1> @not_pow2_or_z_known_bits(<2 x i32> %xin) {
1494; CHECK-LABEL: @not_pow2_or_z_known_bits(
1495; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[XIN:%.*]], splat (i32 -65)
1496; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
1497; CHECK-NEXT:    ret <2 x i1> [[R]]
1498;
1499  %x = or <2 x i32> %xin, <i32 64, i32 64>
1500  %cnt = call <2 x i32> @llvm.ctpop.2xi32(<2 x i32> %x)
1501  %r = icmp ugt <2 x i32> %cnt, <i32 1, i32 1>
1502  ret <2 x i1> %r
1503}
1504
1505define <2 x i1> @not_pow2_or_z_known_bits_fail_wrong_cmp(<2 x i32> %xin) {
1506; CHECK-LABEL: @not_pow2_or_z_known_bits_fail_wrong_cmp(
1507; CHECK-NEXT:    [[X:%.*]] = or <2 x i32> [[XIN:%.*]], splat (i32 64)
1508; CHECK-NEXT:    [[CNT:%.*]] = call range(i32 1, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X]])
1509; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt <2 x i32> [[CNT]], splat (i32 2)
1510; CHECK-NEXT:    ret <2 x i1> [[R]]
1511;
1512  %x = or <2 x i32> %xin, <i32 64, i32 64>
1513  %cnt = call <2 x i32> @llvm.ctpop.2xi32(<2 x i32> %x)
1514  %r = icmp ugt <2 x i32> %cnt, <i32 2, i32 2>
1515  ret <2 x i1> %r
1516}
1517
1518; Make sure that range attributes on return values are dropped after merging these two icmps
1519
1520define i1 @has_single_bit(i32 %x) {
1521; CHECK-LABEL: @has_single_bit(
1522; CHECK-NEXT:  entry:
1523; CHECK-NEXT:    [[POPCNT:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1524; CHECK-NEXT:    [[SEL:%.*]] = icmp eq i32 [[POPCNT]], 1
1525; CHECK-NEXT:    ret i1 [[SEL]]
1526;
1527entry:
1528  %cmp1 = icmp ne i32 %x, 0
1529  %popcnt = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)
1530  %cmp2 = icmp ult i32 %popcnt, 2
1531  %sel = select i1 %cmp1, i1 %cmp2, i1 false
1532  ret i1 %sel
1533}
1534
1535define i1 @has_single_bit_inv(i32 %x) {
1536; CHECK-LABEL: @has_single_bit_inv(
1537; CHECK-NEXT:  entry:
1538; CHECK-NEXT:    [[POPCNT:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1539; CHECK-NEXT:    [[SEL:%.*]] = icmp ne i32 [[POPCNT]], 1
1540; CHECK-NEXT:    ret i1 [[SEL]]
1541;
1542entry:
1543  %cmp1 = icmp eq i32 %x, 0
1544  %popcnt = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)
1545  %cmp2 = icmp ugt i32 %popcnt, 1
1546  %sel = select i1 %cmp1, i1 true, i1 %cmp2
1547  ret i1 %sel
1548}
1549
1550define i1 @is_power2_or_zero_with_range(i32 %x) {
1551; CHECK-LABEL: @is_power2_or_zero_with_range(
1552; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1553; CHECK-NEXT:    [[RES:%.*]] = icmp samesign ult i32 [[CTPOP]], 2
1554; CHECK-NEXT:    ret i1 [[RES]]
1555;
1556  %ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)
1557  %cmp = icmp eq i32 %ctpop, 1
1558  %notzero = icmp eq i32 %x, 0
1559  %res = select i1 %notzero, i1 true, i1 %cmp
1560  ret i1 %res
1561}
1562
1563define i1 @is_power2_or_zero_inv_with_range(i32 %x) {
1564; CHECK-LABEL: @is_power2_or_zero_inv_with_range(
1565; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])
1566; CHECK-NEXT:    [[RES:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
1567; CHECK-NEXT:    ret i1 [[RES]]
1568;
1569  %ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)
1570  %cmp = icmp ne i32 %ctpop, 1
1571  %notzero = icmp ne i32 %x, 0
1572  %res = select i1 %notzero, i1 %cmp, i1 false
1573  ret i1 %res
1574}
1575