[Transforms] Silence a warning in SROA.cpp (NFC)
[llvm-project.git] / llvm / test / Analysis / ValueTracking / knownbits-bmi-pattern.ll
blob663de281f19ba40f4349c2edf050e91eaaffa01f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 declare void @llvm.assume(i1)
6 define i1 @blsmsk_eq_is_false(i32 %x) {
7 ; CHECK-LABEL: @blsmsk_eq_is_false(
8 ; CHECK-NEXT:    ret i1 false
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
17 define <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)
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
28 define <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)
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
39 define i1 @blsmsk_ge_is_false(i32 %x) {
40 ; CHECK-LABEL: @blsmsk_ge_is_false(
41 ; CHECK-NEXT:    ret i1 false
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
50 define <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
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
61 define i1 @blsmsk_signed_is_false(i32 %x) {
62 ; CHECK-LABEL: @blsmsk_signed_is_false(
63 ; CHECK-NEXT:    ret i1 false
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
72 define i32 @blsmsk_add_eval(i32 %x) {
73 ; CHECK-LABEL: @blsmsk_add_eval(
74 ; CHECK-NEXT:    ret i32 33
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
83 define <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)
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
94 define i32 @blsmsk_sub_eval(i32 %x) {
95 ; CHECK-LABEL: @blsmsk_sub_eval(
96 ; CHECK-NEXT:    ret i32 -31
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
105 define i32 @blsmsk_or_eval(i32 %x) {
106 ; CHECK-LABEL: @blsmsk_or_eval(
107 ; CHECK-NEXT:    ret i32 33
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
116 define <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)
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
127 define i32 @blsmsk_xor_eval(i32 %x) {
128 ; CHECK-LABEL: @blsmsk_xor_eval(
129 ; CHECK-NEXT:    ret i32 33
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
138 define i32 @blsmsk_and_eval(i32 %x) {
139 ; CHECK-LABEL: @blsmsk_and_eval(
140 ; CHECK-NEXT:    ret i32 0
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
149 define <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
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
160 define 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]]
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
175 define <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]]
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
190 define 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
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
206 define 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
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
222 define 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
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
238 define <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]]
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
262 define 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
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
278 define 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
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
294 define 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]]
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
314 define <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
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
325 define i1 @blsi_ne_is_true(i32 %x) {
326 ; CHECK-LABEL: @blsi_ne_is_true(
327 ; CHECK-NEXT:    ret i1 true
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
336 define <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]]
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
351 define <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]]
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
366 define i1 @blsi_gt_is_false(i32 %x) {
367 ; CHECK-LABEL: @blsi_gt_is_false(
368 ; CHECK-NEXT:    ret i1 false
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
378 define i32 @blsi_add_eval(i32 %x) {
379 ; CHECK-LABEL: @blsi_add_eval(
380 ; CHECK-NEXT:    ret i32 33
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
389 define i32 @blsi_sub_eval(i32 %x) {
390 ; CHECK-LABEL: @blsi_sub_eval(
391 ; CHECK-NEXT:    ret i32 -31
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
400 define <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)
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
411 define i32 @blsi_or_eval(i32 %x) {
412 ; CHECK-LABEL: @blsi_or_eval(
413 ; CHECK-NEXT:    ret i32 33
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
422 define <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)
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
433 define i32 @blsi_and_eval(i32 %x) {
434 ; CHECK-LABEL: @blsi_and_eval(
435 ; CHECK-NEXT:    ret i32 0
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
444 define <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]]
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
459 define 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]]
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
474 define <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]]
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
499 define 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
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
515 define 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
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
531 define <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]]
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
546 define 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
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
562 define 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
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
578 define <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]]
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
593 define <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]]
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
608 define i1 @blsmsk_eq_no_proof(i32 %x) {
609 ; CHECK-LABEL: @blsmsk_eq_no_proof(
610 ; CHECK-NEXT:    ret i1 false
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
620 define 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]]
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
635 define 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]]
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
650 define <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]]
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
665 define 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]]
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
684 define 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]]
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
703 define 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]]
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
719 define 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]]
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
734 define <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]]
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
750 ;; Test that if we have different knowledge about lowbit of X/-X that we select the minimum.
751 define 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
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
769 define 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
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