xref: /llvm-project/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.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
4declare void @llvm.assume(i1)
5
6define i1 @blsmsk_eq_is_false(i32 %x) {
7; CHECK-LABEL: @blsmsk_eq_is_false(
8; CHECK-NEXT:    ret i1 false
9;
10  %x1 = or i32 %x, 10
11  %x2 = sub i32 %x1, 1
12  %x3 = xor i32 %x1, %x2
13  %z = icmp eq i32 %x3, 8
14  ret i1 %z
15}
16
17define <2 x i1> @blsmsk_ne_is_true_vec(<2 x i32> %x) {
18; CHECK-LABEL: @blsmsk_ne_is_true_vec(
19; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
20;
21  %x1 = or <2 x i32> %x, <i32 10, i32 10>
22  %x2 = sub <2 x i32> %x1, <i32 1, i32 1>
23  %x3 = xor <2 x i32> %x2, %x1
24  %z = icmp ne <2 x i32> %x3, <i32 8, i32 8>
25  ret <2 x i1> %z
26}
27
28define <2 x i1> @blsmsk_ne_is_true_diff_vec(<2 x i32> %x) {
29; CHECK-LABEL: @blsmsk_ne_is_true_diff_vec(
30; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
31;
32  %x1 = or <2 x i32> %x, <i32 10, i32 130>
33  %x2 = sub <2 x i32> %x1, <i32 1, i32 1>
34  %x3 = xor <2 x i32> %x2, %x1
35  %z = icmp ne <2 x i32> %x3, <i32 8, i32 8>
36  ret <2 x i1> %z
37}
38
39define i1 @blsmsk_ge_is_false(i32 %x) {
40; CHECK-LABEL: @blsmsk_ge_is_false(
41; CHECK-NEXT:    ret i1 false
42;
43  %x1 = or i32 %x, 10
44  %x2 = sub i32 %x1, 1
45  %x3 = xor i32 %x1, %x2
46  %z = icmp uge i32 %x3, 8
47  ret i1 %z
48}
49
50define <2 x i1> @blsmsk_gt_is_false_vec(<2 x i32> %x) {
51; CHECK-LABEL: @blsmsk_gt_is_false_vec(
52; CHECK-NEXT:    ret <2 x i1> zeroinitializer
53;
54  %x1 = or <2 x i32> %x, <i32 10, i32 10>
55  %x2 = sub <2 x i32> %x1, <i32 1, i32 1>
56  %x3 = xor <2 x i32> %x2, %x1
57  %z = icmp ugt <2 x i32> %x3, <i32 8, i32 8>
58  ret <2 x i1> %z
59}
60
61define i1 @blsmsk_signed_is_false(i32 %x) {
62; CHECK-LABEL: @blsmsk_signed_is_false(
63; CHECK-NEXT:    ret i1 false
64;
65  %x1 = or i32 %x, 10
66  %x2 = sub i32 %x1, 1
67  %x3 = xor i32 %x1, %x2
68  %z = icmp slt i32 %x3, 0
69  ret i1 %z
70}
71
72define i32 @blsmsk_add_eval(i32 %x) {
73; CHECK-LABEL: @blsmsk_add_eval(
74; CHECK-NEXT:    ret i32 33
75;
76  %x1 = or i32 %x, 9
77  %x2 = sub i32 %x1, 1
78  %x3 = xor i32 %x2, %x1
79  %z = add i32 %x3, 32
80  ret i32 %z
81}
82
83define <2 x i32> @blsmsk_add_eval_vec(<2 x i32> %x) {
84; CHECK-LABEL: @blsmsk_add_eval_vec(
85; CHECK-NEXT:    ret <2 x i32> splat (i32 33)
86;
87  %x1 = or <2 x i32> %x, <i32 9, i32 9>
88  %x2 = add <2 x i32> %x1, <i32 -1, i32 -1>
89  %x3 = xor <2 x i32> %x2, %x1
90  %z = add <2 x i32> %x3, <i32 32, i32 32>
91  ret <2 x i32> %z
92}
93
94define i32 @blsmsk_sub_eval(i32 %x) {
95; CHECK-LABEL: @blsmsk_sub_eval(
96; CHECK-NEXT:    ret i32 -31
97;
98  %x1 = or i32 %x, 9
99  %x2 = sub i32 %x1, 1
100  %x3 = xor i32 %x1, %x2
101  %z = sub i32 %x3, 32
102  ret i32 %z
103}
104
105define i32 @blsmsk_or_eval(i32 %x) {
106; CHECK-LABEL: @blsmsk_or_eval(
107; CHECK-NEXT:    ret i32 33
108;
109  %x1 = or i32 %x, 129
110  %x2 = sub i32 %x1, 1
111  %x3 = xor i32 %x2, %x1
112  %z = or i32 %x3, 32
113  ret i32 %z
114}
115
116define <2 x i32> @blsmsk_or_eval_vec(<2 x i32> %x) {
117; CHECK-LABEL: @blsmsk_or_eval_vec(
118; CHECK-NEXT:    ret <2 x i32> splat (i32 33)
119;
120  %x1 = or <2 x i32> %x, <i32 9, i32 9>
121  %x2 = add <2 x i32> %x1, <i32 -1, i32 -1>
122  %x3 = xor <2 x i32> %x2, %x1
123  %z = or <2 x i32> %x3, <i32 32, i32 32>
124  ret <2 x i32> %z
125}
126
127define i32 @blsmsk_xor_eval(i32 %x) {
128; CHECK-LABEL: @blsmsk_xor_eval(
129; CHECK-NEXT:    ret i32 33
130;
131  %x1 = or i32 %x, 255
132  %x2 = sub i32 %x1, 1
133  %x3 = xor i32 %x1, %x2
134  %z = xor i32 %x3, 32
135  ret i32 %z
136}
137
138define i32 @blsmsk_and_eval(i32 %x) {
139; CHECK-LABEL: @blsmsk_and_eval(
140; CHECK-NEXT:    ret i32 0
141;
142  %x1 = or i32 %x, 34
143  %x2 = sub i32 %x1, 1
144  %x3 = xor i32 %x2, %x1
145  %z = and i32 %x3, 32
146  ret i32 %z
147}
148
149define <2 x i32> @blsmsk_and_eval_vec(<2 x i32> %x) {
150; CHECK-LABEL: @blsmsk_and_eval_vec(
151; CHECK-NEXT:    ret <2 x i32> zeroinitializer
152;
153  %x1 = or <2 x i32> %x, <i32 34, i32 34>
154  %x2 = add <2 x i32> %x1, <i32 -1, i32 -1>
155  %x3 = xor <2 x i32> %x2, %x1
156  %z = and <2 x i32> %x3, <i32 32, i32 32>
157  ret <2 x i32> %z
158}
159
160define i32 @blsmsk_and_eval2(i32 %x) {
161; CHECK-LABEL: @blsmsk_and_eval2(
162; CHECK-NEXT:    [[X1:%.*]] = or i32 [[X:%.*]], 10
163; CHECK-NEXT:    [[X2:%.*]] = add i32 [[X1]], 63
164; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X]], [[X2]]
165; CHECK-NEXT:    [[Z:%.*]] = and i32 [[X3]], 32
166; CHECK-NEXT:    ret i32 [[Z]]
167;
168  %x1 = or i32 %x, 10
169  %x2 = sub i32 %x1, 1
170  %x3 = xor i32 %x1, %x2
171  %z = and i32 %x3, 32
172  ret i32 %z
173}
174
175define <2 x i32> @blsmsk_and_eval3_vec(<2 x i32> %x) {
176; CHECK-LABEL: @blsmsk_and_eval3_vec(
177; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 34)
178; CHECK-NEXT:    [[X2:%.*]] = add <2 x i32> [[X1]], splat (i32 63)
179; CHECK-NEXT:    [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]]
180; CHECK-NEXT:    [[Z:%.*]] = and <2 x i32> [[X3]], <i32 16, i32 32>
181; CHECK-NEXT:    ret <2 x i32> [[Z]]
182;
183  %x1 = or <2 x i32> %x, <i32 34, i32 34>
184  %x2 = add <2 x i32> %x1, <i32 -1, i32 -1>
185  %x3 = xor <2 x i32> %x2, %x1
186  %z = and <2 x i32> %x3, <i32 16, i32 32>
187  ret <2 x i32> %z
188}
189
190define i1 @blsmsk_eq_is_false_assume(i32 %x) {
191; CHECK-LABEL: @blsmsk_eq_is_false_assume(
192; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 4
193; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
194; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
195; CHECK-NEXT:    ret i1 false
196;
197  %lb = and i32 %x, 4
198  %cmp = icmp ne i32 %lb, 0
199  call void @llvm.assume(i1 %cmp)
200  %x2 = add i32 %x, -1
201  %x3 = xor i32 %x2, %x
202  %z = icmp eq i32 %x3, 8
203  ret i1 %z
204}
205
206define i1 @blsmsk_gt_is_false_assume(i32 %x) {
207; CHECK-LABEL: @blsmsk_gt_is_false_assume(
208; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 2
209; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
210; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
211; CHECK-NEXT:    ret i1 false
212;
213  %lb = and i32 %x, 2
214  %cmp = icmp ne i32 %lb, 0
215  call void @llvm.assume(i1 %cmp)
216  %x2 = sub i32 %x, 1
217  %x3 = xor i32 %x2, %x
218  %z = icmp ugt i32 %x3, 8
219  ret i1 %z
220}
221
222define i32 @blsmsk_add_eval_assume(i32 %x) {
223; CHECK-LABEL: @blsmsk_add_eval_assume(
224; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 1
225; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
226; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
227; CHECK-NEXT:    ret i32 33
228;
229  %lb = and i32 %x, 1
230  %cmp = icmp ne i32 %lb, 0
231  call void @llvm.assume(i1 %cmp)
232  %x2 = sub i32 %x, 1
233  %x3 = xor i32 %x2, %x
234  %z = add i32 %x3, 32
235  ret i32 %z
236}
237
238define <2 x i32> @blsmsk_add_eval_assume_vec(<2 x i32> %x) {
239; CHECK-LABEL: @blsmsk_add_eval_assume_vec(
240; CHECK-NEXT:    [[CMP:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i1>
241; CHECK-NEXT:    [[CMP0:%.*]] = extractelement <2 x i1> [[CMP]], i64 0
242; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP0]])
243; CHECK-NEXT:    [[CMP1:%.*]] = extractelement <2 x i1> [[CMP]], i64 1
244; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP1]])
245; CHECK-NEXT:    [[X2:%.*]] = add <2 x i32> [[X]], splat (i32 -1)
246; CHECK-NEXT:    [[X3:%.*]] = xor <2 x i32> [[X2]], [[X]]
247; CHECK-NEXT:    [[Z:%.*]] = add <2 x i32> [[X3]], splat (i32 32)
248; CHECK-NEXT:    ret <2 x i32> [[Z]]
249;
250  %lb = and <2 x i32> %x, <i32 1, i32 1>
251  %cmp = icmp ne <2 x i32> %lb, <i32 0, i32 0>
252  %cmp0 = extractelement <2 x i1> %cmp, i32 0
253  call void @llvm.assume(i1 %cmp0)
254  %cmp1 = extractelement <2 x i1> %cmp, i32 1
255  call void @llvm.assume(i1 %cmp1)
256  %x2 = sub <2 x i32> %x, <i32 1, i32 1>
257  %x3 = xor <2 x i32> %x2, %x
258  %z = add <2 x i32> %x3, <i32 32, i32 32>
259  ret <2 x i32> %z
260}
261
262define i32 @blsmsk_sub_eval_assume(i32 %x) {
263; CHECK-LABEL: @blsmsk_sub_eval_assume(
264; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 1
265; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
266; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
267; CHECK-NEXT:    ret i32 -31
268;
269  %lb = and i32 %x, 1
270  %cmp = icmp ne i32 %lb, 0
271  call void @llvm.assume(i1 %cmp)
272  %x2 = sub i32 %x, 1
273  %x3 = xor i32 %x, %x2
274  %z = sub i32 %x3, 32
275  ret i32 %z
276}
277
278define i32 @blsmsk_or_eval_assume(i32 %x) {
279; CHECK-LABEL: @blsmsk_or_eval_assume(
280; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 1
281; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
282; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
283; CHECK-NEXT:    ret i32 33
284;
285  %lb = and i32 %x, 1
286  %cmp = icmp ne i32 %lb, 0
287  call void @llvm.assume(i1 %cmp)
288  %x2 = sub i32 %x, 1
289  %x3 = xor i32 %x2, %x
290  %z = or i32 %x3, 32
291  ret i32 %z
292}
293
294define i32 @blsmsk_and_eval_assume(i32 %x) {
295; CHECK-LABEL: @blsmsk_and_eval_assume(
296; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 4
297; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
298; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
299; CHECK-NEXT:    [[X2:%.*]] = add i32 [[X]], 63
300; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X2]], [[X]]
301; CHECK-NEXT:    [[Z:%.*]] = and i32 [[X3]], 32
302; CHECK-NEXT:    ret i32 [[Z]]
303;
304  %lb = and i32 %x, 4
305  %cmp = icmp ne i32 %lb, 0
306  call void @llvm.assume(i1 %cmp)
307  %x2 = sub i32 %x, 1
308  %x3 = xor i32 %x2, %x
309  %z = and i32 %x3, 32
310  ret i32 %z
311}
312
313
314define <2 x i1> @blsi_eq_is_false_vec(<2 x i32> %x) {
315; CHECK-LABEL: @blsi_eq_is_false_vec(
316; CHECK-NEXT:    ret <2 x i1> zeroinitializer
317;
318  %x1 = or <2 x i32> %x, <i32 10, i32 10>
319  %x2 = sub <2 x i32> <i32 0, i32 0>, %x1
320  %x3 = and <2 x i32> %x1, %x2
321  %z = icmp eq <2 x i32> %x3, <i32 8, i32 8>
322  ret <2 x i1> %z
323}
324
325define i1 @blsi_ne_is_true(i32 %x) {
326; CHECK-LABEL: @blsi_ne_is_true(
327; CHECK-NEXT:    ret i1 true
328;
329  %x1 = or i32 %x, 10
330  %x2 = sub i32 0, %x1
331  %x3 = and i32 %x1, %x2
332  %z = icmp ne i32 %x3, 8
333  ret i1 %z
334}
335
336define <2 x i1> @blsi_ge_is_false_vec(<2 x i32> %x) {
337; CHECK-LABEL: @blsi_ge_is_false_vec(
338; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 10)
339; CHECK-NEXT:    [[X2:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]]
340; CHECK-NEXT:    [[X3:%.*]] = and <2 x i32> [[X]], [[X2]]
341; CHECK-NEXT:    [[Z:%.*]] = icmp ugt <2 x i32> [[X3]], splat (i32 7)
342; CHECK-NEXT:    ret <2 x i1> [[Z]]
343;
344  %x1 = or <2 x i32> %x, <i32 10, i32 10>
345  %x2 = sub <2 x i32> <i32 0, i32 0>, %x1
346  %x3 = and <2 x i32> %x1, %x2
347  %z = icmp uge <2 x i32> %x3, <i32 8, i32 8>
348  ret <2 x i1> %z
349}
350
351define <2 x i1> @blsi_ge_is_false_diff_vec(<2 x i32> %x) {
352; CHECK-LABEL: @blsi_ge_is_false_diff_vec(
353; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 10, i32 11>
354; CHECK-NEXT:    [[X2:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]]
355; CHECK-NEXT:    [[X3:%.*]] = and <2 x i32> [[X]], [[X2]]
356; CHECK-NEXT:    [[Z:%.*]] = icmp ugt <2 x i32> [[X3]], splat (i32 7)
357; CHECK-NEXT:    ret <2 x i1> [[Z]]
358;
359  %x1 = or <2 x i32> %x, <i32 10, i32 11>
360  %x2 = sub <2 x i32> <i32 0, i32 0>, %x1
361  %x3 = and <2 x i32> %x1, %x2
362  %z = icmp uge <2 x i32> %x3, <i32 8, i32 8>
363  ret <2 x i1> %z
364}
365
366define i1 @blsi_gt_is_false(i32 %x) {
367; CHECK-LABEL: @blsi_gt_is_false(
368; CHECK-NEXT:    ret i1 false
369;
370  %x1 = or i32 %x, 10
371  %x2 = sub i32 0, %x1
372  %x3 = and i32 %x2, %x1
373  %z = icmp ugt i32 %x3, 8
374  ret i1 %z
375}
376
377
378define i32 @blsi_add_eval(i32 %x) {
379; CHECK-LABEL: @blsi_add_eval(
380; CHECK-NEXT:    ret i32 33
381;
382  %x1 = or i32 %x, 9
383  %x2 = sub i32 0, %x1
384  %x3 = and i32 %x2, %x1
385  %z = add i32 %x3, 32
386  ret i32 %z
387}
388
389define i32 @blsi_sub_eval(i32 %x) {
390; CHECK-LABEL: @blsi_sub_eval(
391; CHECK-NEXT:    ret i32 -31
392;
393  %x1 = or i32 %x, 33
394  %x2 = sub i32 0, %x1
395  %x3 = and i32 %x2, %x1
396  %z = sub i32 %x3, 32
397  ret i32 %z
398}
399
400define <2 x i32> @blsi_sub_eval_vec(<2 x i32> %x) {
401; CHECK-LABEL: @blsi_sub_eval_vec(
402; CHECK-NEXT:    ret <2 x i32> splat (i32 -31)
403;
404  %x1 = or <2 x i32> %x, <i32 33, i32 33>
405  %x2 = sub <2 x i32> <i32 0, i32 0>, %x1
406  %x3 = and <2 x i32> %x1, %x2
407  %z = sub <2 x i32> %x3, <i32 32, i32 32>
408  ret <2 x i32> %z
409}
410
411define i32 @blsi_or_eval(i32 %x) {
412; CHECK-LABEL: @blsi_or_eval(
413; CHECK-NEXT:    ret i32 33
414;
415  %x1 = or i32 %x, 129
416  %x2 = sub i32 0, %x1
417  %x3 = and i32 %x2, %x1
418  %z = or i32 %x3, 32
419  ret i32 %z
420}
421
422define <2 x i32> @blsi_xor_eval_vec(<2 x i32> %x) {
423; CHECK-LABEL: @blsi_xor_eval_vec(
424; CHECK-NEXT:    ret <2 x i32> splat (i32 33)
425;
426  %x1 = or <2 x i32> %x, <i32 33, i32 33>
427  %x2 = sub <2 x i32> <i32 0, i32 0>, %x1
428  %x3 = and <2 x i32> %x2, %x1
429  %z = xor <2 x i32> %x3, <i32 32, i32 32>
430  ret <2 x i32> %z
431}
432
433define i32 @blsi_and_eval(i32 %x) {
434; CHECK-LABEL: @blsi_and_eval(
435; CHECK-NEXT:    ret i32 0
436;
437  %x1 = or i32 %x, 34
438  %x2 = sub i32 0, %x1
439  %x3 = and i32 %x2, %x1
440  %z = and i32 %x3, 32
441  ret i32 %z
442}
443
444define <2 x i32> @blsi_and_eval2_vec(<2 x i32> %x) {
445; CHECK-LABEL: @blsi_and_eval2_vec(
446; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 30)
447; CHECK-NEXT:    [[X2:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]]
448; CHECK-NEXT:    [[X3:%.*]] = and <2 x i32> [[X]], [[X2]]
449; CHECK-NEXT:    [[Z:%.*]] = and <2 x i32> [[X3]], splat (i32 32)
450; CHECK-NEXT:    ret <2 x i32> [[Z]]
451;
452  %x1 = or <2 x i32> %x, <i32 30, i32 30>
453  %x2 = sub <2 x i32> <i32 0, i32 0>, %x1
454  %x3 = and <2 x i32> %x1, %x2
455  %z = and <2 x i32> %x3, <i32 32, i32 32>
456  ret <2 x i32> %z
457}
458
459define i32 @blsi_and_eval3(i32 %x) {
460; CHECK-LABEL: @blsi_and_eval3(
461; CHECK-NEXT:    [[X1:%.*]] = or i32 [[X:%.*]], 34
462; CHECK-NEXT:    [[X2:%.*]] = sub nsw i32 0, [[X1]]
463; CHECK-NEXT:    [[X3:%.*]] = and i32 [[X]], [[X2]]
464; CHECK-NEXT:    [[Z:%.*]] = and i32 [[X3]], 208
465; CHECK-NEXT:    ret i32 [[Z]]
466;
467  %x1 = or i32 %x, 34
468  %x2 = sub i32 0, %x1
469  %x3 = and i32 %x2, %x1
470  %z = and i32 %x3, 240
471  ret i32 %z
472}
473
474define <2 x i1> @blsi_eq_is_false_assume_vec(<2 x i32> %x) {
475; CHECK-LABEL: @blsi_eq_is_false_assume_vec(
476; CHECK-NEXT:    [[LB:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 2)
477; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[LB]], zeroinitializer
478; CHECK-NEXT:    [[CMP0:%.*]] = extractelement <2 x i1> [[CMP]], i64 0
479; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP0]])
480; CHECK-NEXT:    [[CMP1:%.*]] = extractelement <2 x i1> [[CMP]], i64 1
481; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP1]])
482; CHECK-NEXT:    [[X2:%.*]] = sub <2 x i32> zeroinitializer, [[X]]
483; CHECK-NEXT:    [[X3:%.*]] = and <2 x i32> [[X]], [[X2]]
484; CHECK-NEXT:    [[Z:%.*]] = icmp eq <2 x i32> [[X3]], splat (i32 8)
485; CHECK-NEXT:    ret <2 x i1> [[Z]]
486;
487  %lb = and <2 x i32> %x, <i32 2, i32 2>
488  %cmp = icmp ne <2 x i32> %lb, <i32 0, i32 0>
489  %cmp0 = extractelement <2 x i1> %cmp, i32 0
490  call void @llvm.assume(i1 %cmp0)
491  %cmp1 = extractelement <2 x i1> %cmp, i32 1
492  call void @llvm.assume(i1 %cmp1)
493  %x2 = sub <2 x i32> <i32 0, i32 0>, %x
494  %x3 = and <2 x i32> %x2, %x
495  %z = icmp eq <2 x i32> %x3, <i32 8, i32 8>
496  ret <2 x i1> %z
497}
498
499define i1 @blsi_ne_is_true_assume(i32 %x) {
500; CHECK-LABEL: @blsi_ne_is_true_assume(
501; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 4
502; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
503; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
504; CHECK-NEXT:    ret i1 true
505;
506  %lb = and i32 %x, 4
507  %cmp = icmp ne i32 %lb, 0
508  call void @llvm.assume(i1 %cmp)
509  %x2 = sub i32 0, %x
510  %x3 = and i32 %x2, %x
511  %z = icmp ne i32 %x3, 8
512  ret i1 %z
513}
514
515define i1 @blsi_ge_is_false_assume(i32 %x) {
516; CHECK-LABEL: @blsi_ge_is_false_assume(
517; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 4
518; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
519; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
520; CHECK-NEXT:    ret i1 false
521;
522  %lb = and i32 %x, 4
523  %cmp = icmp ne i32 %lb, 0
524  call void @llvm.assume(i1 %cmp)
525  %x2 = sub i32 0, %x
526  %x3 = and i32 %x2, %x
527  %z = icmp uge i32 %x3, 8
528  ret i1 %z
529}
530
531define <2 x i1> @blsi_cmp_eq_diff_bits_vec(<2 x i32> %x) {
532; CHECK-LABEL: @blsi_cmp_eq_diff_bits_vec(
533; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 2>
534; CHECK-NEXT:    [[X2:%.*]] = sub <2 x i32> zeroinitializer, [[X1]]
535; CHECK-NEXT:    [[X3:%.*]] = and <2 x i32> [[X1]], [[X2]]
536; CHECK-NEXT:    [[Z:%.*]] = icmp eq <2 x i32> [[X3]], splat (i32 32)
537; CHECK-NEXT:    ret <2 x i1> [[Z]]
538;
539  %x1 = or <2 x i32> %x, <i32 1, i32 2>
540  %x2 = sub <2 x i32> <i32 0, i32 0>, %x1
541  %x3 = and <2 x i32> %x1, %x2
542  %z = icmp eq <2 x i32> %x3, <i32 32, i32 32>
543  ret <2 x i1> %z
544}
545
546define i32 @blsi_xor_eval_assume(i32 %x) {
547; CHECK-LABEL: @blsi_xor_eval_assume(
548; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 1
549; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
550; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
551; CHECK-NEXT:    ret i32 33
552;
553  %lb = and i32 %x, 1
554  %cmp = icmp ne i32 %lb, 0
555  call void @llvm.assume(i1 %cmp)
556  %x2 = sub i32 0, %x
557  %x3 = and i32 %x2, %x
558  %z = xor i32 %x3, 32
559  ret i32 %z
560}
561
562define i32 @blsi_and_eval_assume(i32 %x) {
563; CHECK-LABEL: @blsi_and_eval_assume(
564; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 8
565; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
566; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
567; CHECK-NEXT:    ret i32 0
568;
569  %lb = and i32 %x, 8
570  %cmp = icmp ne i32 %lb, 0
571  call void @llvm.assume(i1 %cmp)
572  %x2 = sub i32 0, %x
573  %x3 = and i32 %x2, %x
574  %z = and i32 %x3, 32
575  ret i32 %z
576}
577
578define <2 x i1> @blsmsk_ne_no_proof_vec(<2 x i32> %x) {
579; CHECK-LABEL: @blsmsk_ne_no_proof_vec(
580; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 10)
581; CHECK-NEXT:    [[X2:%.*]] = add nsw <2 x i32> [[X1]], <i32 -2, i32 -3>
582; CHECK-NEXT:    [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]]
583; CHECK-NEXT:    [[Z:%.*]] = icmp ne <2 x i32> [[X3]], splat (i32 8)
584; CHECK-NEXT:    ret <2 x i1> [[Z]]
585;
586  %x1 = or <2 x i32> %x, <i32 10, i32 10>
587  %x2 = sub <2 x i32> %x1, <i32 2, i32 3>
588  %x3 = xor <2 x i32> %x2, %x1
589  %z = icmp ne <2 x i32> %x3, <i32 8, i32 8>
590  ret <2 x i1> %z
591}
592
593define <2 x i32> @blsmsk_add_noeval_vec(<2 x i32> %x) {
594; CHECK-LABEL: @blsmsk_add_noeval_vec(
595; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 9)
596; CHECK-NEXT:    [[X2:%.*]] = add <2 x i32> [[X1]], <i32 1, i32 -2>
597; CHECK-NEXT:    [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]]
598; CHECK-NEXT:    [[Z:%.*]] = add <2 x i32> [[X3]], splat (i32 32)
599; CHECK-NEXT:    ret <2 x i32> [[Z]]
600;
601  %x1 = or <2 x i32> %x, <i32 9, i32 9>
602  %x2 = add <2 x i32> %x1, <i32 1, i32 -2>
603  %x3 = xor <2 x i32> %x2, %x1
604  %z = add <2 x i32> %x3, <i32 32, i32 32>
605  ret <2 x i32> %z
606}
607
608define i1 @blsmsk_eq_no_proof(i32 %x) {
609; CHECK-LABEL: @blsmsk_eq_no_proof(
610; CHECK-NEXT:    ret i1 false
611;
612  %x1 = or i32 %x, 10
613  %x2 = add i32 %x1, -2
614  %x3 = xor i32 %x2, %x1
615  %z = icmp eq i32 %x3, 8
616  ret i1 %z
617}
618
619
620define i32 @blsmsk_add_no_eval(i32 %x) {
621; CHECK-LABEL: @blsmsk_add_no_eval(
622; CHECK-NEXT:    [[X1:%.*]] = or i32 [[X:%.*]], 9
623; CHECK-NEXT:    [[X2:%.*]] = add nsw i32 [[X1]], -3
624; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X1]], [[X2]]
625; CHECK-NEXT:    [[Z:%.*]] = add i32 [[X3]], 32
626; CHECK-NEXT:    ret i32 [[Z]]
627;
628  %x1 = or i32 %x, 9
629  %x2 = sub i32 %x1, 3
630  %x3 = xor i32 %x1, %x2
631  %z = add i32 %x3, 32
632  ret i32 %z
633}
634
635define i32 @blsmsk_add_no_eval2(i32 %x) {
636; CHECK-LABEL: @blsmsk_add_no_eval2(
637; CHECK-NEXT:    [[X1:%.*]] = or i32 [[X:%.*]], 256
638; CHECK-NEXT:    [[X2:%.*]] = add nsw i32 [[X1]], -1
639; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X1]], [[X2]]
640; CHECK-NEXT:    [[Z:%.*]] = add nuw nsw i32 [[X3]], 32
641; CHECK-NEXT:    ret i32 [[Z]]
642;
643  %x1 = or i32 %x, 256
644  %x2 = sub i32 %x1, 1
645  %x3 = xor i32 %x1, %x2
646  %z = add i32 %x3, 32
647  ret i32 %z
648}
649
650define <2 x i32> @blsmsk_xor_no_eval_vec(<2 x i32> %x) {
651; CHECK-LABEL: @blsmsk_xor_no_eval_vec(
652; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 34)
653; CHECK-NEXT:    [[X2:%.*]] = add <2 x i32> [[X1]], <i32 -9, i32 1>
654; CHECK-NEXT:    [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]]
655; CHECK-NEXT:    [[Z:%.*]] = xor <2 x i32> [[X3]], splat (i32 32)
656; CHECK-NEXT:    ret <2 x i32> [[Z]]
657;
658  %x1 = or <2 x i32> %x, <i32 34, i32 34>
659  %x2 = add <2 x i32> %x1, <i32 -9, i32 1>
660  %x3 = xor <2 x i32> %x2, %x1
661  %z = xor <2 x i32> %x3, <i32 32, i32 32>
662  ret <2 x i32> %z
663}
664
665define i32 @blsmsk_xor_no_eval_assume(i32 %x) {
666; CHECK-LABEL: @blsmsk_xor_no_eval_assume(
667; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 1
668; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[LB]], 0
669; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
670; CHECK-NEXT:    [[X2:%.*]] = add i32 [[X]], -1
671; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X]], [[X2]]
672; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[X3]], 32
673; CHECK-NEXT:    ret i32 [[Z]]
674;
675  %lb = and i32 %x, 1
676  %cmp = icmp ne i32 %lb, 1
677  call void @llvm.assume(i1 %cmp)
678  %x2 = sub i32 %x, 1
679  %x3 = xor i32 %x, %x2
680  %z = xor i32 %x3, 32
681  ret i32 %z
682}
683
684define i32 @blsmsk_xor_no_eval_assume2(i32 %x) {
685; CHECK-LABEL: @blsmsk_xor_no_eval_assume2(
686; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 128
687; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
688; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
689; CHECK-NEXT:    [[X2:%.*]] = add nsw i32 [[X]], -1
690; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X]], [[X2]]
691; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[X3]], 32
692; CHECK-NEXT:    ret i32 [[Z]]
693;
694  %lb = and i32 %x, 128
695  %cmp = icmp ne i32 %lb, 0
696  call void @llvm.assume(i1 %cmp)
697  %x2 = sub i32 %x, 1
698  %x3 = xor i32 %x, %x2
699  %z = xor i32 %x3, 32
700  ret i32 %z
701}
702
703define i1 @blsi_ne_no_proof2(i32 %x) {
704; CHECK-LABEL: @blsi_ne_no_proof2(
705; CHECK-NEXT:    [[X1:%.*]] = or i32 [[X:%.*]], 512
706; CHECK-NEXT:    [[X2:%.*]] = sub nsw i32 0, [[X1]]
707; CHECK-NEXT:    [[X3:%.*]] = and i32 [[X1]], [[X2]]
708; CHECK-NEXT:    [[Z:%.*]] = icmp ne i32 [[X3]], 8
709; CHECK-NEXT:    ret i1 [[Z]]
710;
711  %x1 = or i32 %x, 512
712  %x2 = sub i32 0, %x1
713  %x3 = and i32 %x2, %x1
714  %z = icmp ne i32 %x3, 8
715  ret i1 %z
716}
717
718
719define i32 @blsi_or_no_eval(i32 %x) {
720; CHECK-LABEL: @blsi_or_no_eval(
721; CHECK-NEXT:    [[X1:%.*]] = or i32 [[X:%.*]], 129
722; CHECK-NEXT:    [[X2:%.*]] = sub nsw i32 2, [[X1]]
723; CHECK-NEXT:    [[X3:%.*]] = and i32 [[X2]], [[X1]]
724; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X3]], 32
725; CHECK-NEXT:    ret i32 [[Z]]
726;
727  %x1 = or i32 %x, 129
728  %x2 = sub i32 2, %x1
729  %x3 = and i32 %x2, %x1
730  %z = or i32 %x3, 32
731  ret i32 %z
732}
733
734define <2 x i32> @blsi_or_no_partial_eval_vec(<2 x i32> %x) {
735; CHECK-LABEL: @blsi_or_no_partial_eval_vec(
736; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 30)
737; CHECK-NEXT:    [[X2:%.*]] = sub nsw <2 x i32> <i32 0, i32 1>, [[X1]]
738; CHECK-NEXT:    [[X3:%.*]] = and <2 x i32> [[X1]], [[X2]]
739; CHECK-NEXT:    [[Z:%.*]] = or <2 x i32> [[X3]], splat (i32 32)
740; CHECK-NEXT:    ret <2 x i32> [[Z]]
741;
742  %x1 = or <2 x i32> %x, <i32 30, i32 30>
743  %x2 = sub <2 x i32> <i32 0, i32 1>, %x1
744  %x3 = and <2 x i32> %x1, %x2
745  %z = or <2 x i32> %x3, <i32 32, i32 32>
746  ret <2 x i32> %z
747}
748
749
750;; Test that if we have different knowledge about lowbit of X/-X that we select the minimum.
751define i1 @blsi_differing_lowbits(i8 %x) {
752; CHECK-LABEL: @blsi_differing_lowbits(
753; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[X:%.*]]
754; CHECK-NEXT:    [[LB:%.*]] = and i8 [[Z]], 2
755; CHECK-NEXT:    [[NE:%.*]] = icmp ne i8 [[LB]], 0
756; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
757; CHECK-NEXT:    ret i1 false
758;
759  %y = or i8 %x, 8
760  %z = sub i8 0, %y
761  %lb = and i8 %z, 2
762  %ne = icmp ne i8 %lb, 0
763  call void @llvm.assume(i1 %ne)
764  %o = and i8 %z, %y
765  %r = icmp eq i8 %o, 4
766  ret i1 %r
767}
768
769define i1 @blsi_differing_lowbits2(i8 %x) {
770; CHECK-LABEL: @blsi_differing_lowbits2(
771; CHECK-NEXT:    [[Z:%.*]] = sub nsw i8 0, [[X:%.*]]
772; CHECK-NEXT:    [[LB:%.*]] = and i8 [[Z]], 8
773; CHECK-NEXT:    [[NE:%.*]] = icmp ne i8 [[LB]], 0
774; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
775; CHECK-NEXT:    [[LB2:%.*]] = and i8 [[X]], 2
776; CHECK-NEXT:    [[NE2:%.*]] = icmp ne i8 [[LB2]], 0
777; CHECK-NEXT:    call void @llvm.assume(i1 [[NE2]])
778; CHECK-NEXT:    ret i1 false
779;
780  %z = sub i8 0, %x
781  %lb = and i8 %z, 8
782  %ne = icmp ne i8 %lb, 0
783  call void @llvm.assume(i1 %ne)
784  %lb2 = and i8 %x, 2
785  %ne2 = icmp ne i8 %lb2, 0
786  call void @llvm.assume(i1 %ne2)
787  %o = and i8 %z, %x
788  %r = icmp eq i8 %o, 4
789  ret i1 %r
790}
791