xref: /llvm-project/llvm/test/Analysis/ValueTracking/known-non-zero.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instsimplify < %s -S | FileCheck %s
3
4declare void @llvm.assume(i1)
5declare i8 @llvm.abs.i8(i8, i1)
6declare i8 @llvm.bitreverse.i8(i8)
7declare i16 @llvm.bswap.i16(i16)
8declare i8 @llvm.ctpop.i8(i8)
9declare <2 x i8> @llvm.uadd.sat.2xi8(<2 x i8>, <2 x i8>)
10declare i8 @llvm.uadd.sat.i8(i8, i8)
11declare i8 @llvm.fshr.i8(i8, i8, i8)
12declare i8 @llvm.fshl.i8(i8, i8, i8)
13declare i8 @llvm.ctlz.i8(i8, i1)
14declare i8 @llvm.cttz.i8(i8, i1)
15declare i8 @llvm.sadd.sat.i8(i8, i8)
16declare i8 @llvm.smax.i8(i8, i8)
17declare i8 @llvm.smin.i8(i8, i8)
18declare i8 @llvm.sshl.sat.i8(i8, i8)
19declare i8 @llvm.ssub.sat.i8(i8, i8)
20declare i8 @llvm.umax.i8(i8, i8)
21declare i8 @llvm.umin.i8(i8, i8)
22declare i8 @llvm.ushl.sat.i8(i8, i8)
23declare i8 @llvm.usub.sat.i8(i8, i8)
24declare float @llvm.maximum.f32(float, float)
25
26;; Throughout use: X > Y || Y == 0 which folds to X > Y iff X known
27;; non-zero. Do this because many of the expressions already have
28;; hardcoded cases for folding Foo(X) == 0 -> X == 0 and we want to
29;; test explicitly that `isKnownNonZero` works.
30
31define i1 @check_neg(i8 %x, i8 %y) {
32; CHECK-LABEL: @check_neg(
33; CHECK-NEXT:    [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
34; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
35; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[X]]
36; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
37; CHECK-NEXT:    ret i1 [[CMP0]]
38;
39  %ne = icmp ne i8 %x, 0
40  call void @llvm.assume(i1 %ne)
41  %z = sub i8 0, %x
42  %cmp0 = icmp ugt i8 %z, %y
43  %cmp1 = icmp eq i8 %y, 0
44  %r = or i1 %cmp0, %cmp1
45  ret i1 %r
46}
47
48define i1 @check_abs(i8 %x, i8 %y) {
49; CHECK-LABEL: @check_abs(
50; CHECK-NEXT:    [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
51; CHECK-NEXT:    br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]]
52; CHECK:       true:
53; CHECK-NEXT:    [[Z:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true)
54; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
55; CHECK-NEXT:    ret i1 [[CMP0]]
56; CHECK:       false:
57; CHECK-NEXT:    ret i1 [[NE]]
58;
59  %ne = icmp ne i8 %x, 0
60  br i1 %ne, label %true, label %false
61true:
62  %z = call i8 @llvm.abs.i8(i8 %x, i1 true)
63  %cmp0 = icmp ugt i8 %z, %y
64  %cmp1 = icmp eq i8 %y, 0
65  %r = or i1 %cmp0, %cmp1
66  ret i1 %r
67false:
68  ret i1 %ne
69}
70
71define i1 @check_abs_failish(i8 %x, i8 %y) {
72; CHECK-LABEL: @check_abs_failish(
73; CHECK-NEXT:    [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
74; CHECK-NEXT:    br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]]
75; CHECK:       false:
76; CHECK-NEXT:    [[Z:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true)
77; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
78; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
79; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
80; CHECK-NEXT:    ret i1 [[R]]
81; CHECK:       true:
82; CHECK-NEXT:    ret i1 [[NE]]
83;
84  %ne = icmp ne i8 %x, 0
85  br i1 %ne, label %true, label %false
86false:
87  %z = call i8 @llvm.abs.i8(i8 %x, i1 true)
88  %cmp0 = icmp ugt i8 %z, %y
89  %cmp1 = icmp eq i8 %y, 0
90  %r = or i1 %cmp0, %cmp1
91  ret i1 %r
92true:
93  ret i1 %ne
94}
95
96define i1 @check_bitreverse(i8 %x, i8 %y) {
97; CHECK-LABEL: @check_bitreverse(
98; CHECK-NEXT:    [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
99; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
100; CHECK-NEXT:    [[Z:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[X]])
101; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
102; CHECK-NEXT:    ret i1 [[CMP0]]
103;
104  %ne = icmp ne i8 %x, 0
105  call void @llvm.assume(i1 %ne)
106  %z = call i8 @llvm.bitreverse.i8(i8 %x)
107  %cmp0 = icmp ugt i8 %z, %y
108  %cmp1 = icmp eq i8 %y, 0
109  %r = or i1 %cmp0, %cmp1
110  ret i1 %r
111}
112
113define i1 @check_bswap(i16 %x, i16 %y) {
114; CHECK-LABEL: @check_bswap(
115; CHECK-NEXT:    [[NE:%.*]] = icmp ne i16 [[X:%.*]], 0
116; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
117; CHECK-NEXT:    [[Z:%.*]] = call i16 @llvm.bswap.i16(i16 [[X]])
118; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i16 [[Z]], [[Y:%.*]]
119; CHECK-NEXT:    ret i1 [[CMP0]]
120;
121  %ne = icmp ne i16 %x, 0
122  call void @llvm.assume(i1 %ne)
123  %z = call i16 @llvm.bswap.i16(i16 %x)
124  %cmp0 = icmp ugt i16 %z, %y
125  %cmp1 = icmp eq i16 %y, 0
126  %r = or i1 %cmp0, %cmp1
127  ret i1 %r
128}
129
130define i1 @check_ctpop(i8 %x, i8 %y) {
131; CHECK-LABEL: @check_ctpop(
132; CHECK-NEXT:    [[NE:%.*]] = icmp eq i8 [[X:%.*]], 0
133; CHECK-NEXT:    br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]]
134; CHECK:       true:
135; CHECK-NEXT:    ret i1 [[NE]]
136; CHECK:       false:
137; CHECK-NEXT:    [[Z:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X]])
138; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
139; CHECK-NEXT:    ret i1 [[CMP0]]
140;
141  %ne = icmp eq i8 %x, 0
142  br i1 %ne, label %true, label %false
143true:
144  ret i1 %ne
145false:
146  %z = call i8 @llvm.ctpop.i8(i8 %x)
147  %cmp0 = icmp ugt i8 %z, %y
148  %cmp1 = icmp eq i8 %y, 0
149  %r = or i1 %cmp0, %cmp1
150  ret i1 %r
151}
152
153define i1 @check_add_sat(i8 %x, i8 %y, i8 %w) {
154; CHECK-LABEL: @check_add_sat(
155; CHECK-NEXT:    [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
156; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
157; CHECK-NEXT:    [[Z:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X]], i8 [[Y:%.*]])
158; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[W:%.*]]
159; CHECK-NEXT:    ret i1 [[CMP0]]
160;
161  %ne = icmp ne i8 %x, 0
162  call void @llvm.assume(i1 %ne)
163  %z = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
164  %cmp0 = icmp ugt i8 %z, %w
165  %cmp1 = icmp eq i8 %w, 0
166  %r = or i1 %cmp0, %cmp1
167  ret i1 %r
168}
169
170define <2 x i1> @check_add_sat_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %w) {
171; CHECK-LABEL: @check_add_sat_vec(
172; CHECK-NEXT:    [[YNZ:%.*]] = or <2 x i8> [[Y:%.*]], <i8 2, i8 1>
173; CHECK-NEXT:    [[Z:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[YNZ]])
174; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt <2 x i8> [[Z]], [[W:%.*]]
175; CHECK-NEXT:    ret <2 x i1> [[CMP0]]
176;
177  %ynz = or <2 x i8> %y, <i8 2, i8 1>
178  %z = call <2 x i8> @llvm.uadd.sat.2xi8(<2 x i8> %x, <2 x i8> %ynz)
179  %cmp0 = icmp ugt <2 x i8> %z, %w
180  %cmp1 = icmp eq <2 x i8> %w, <i8 0, i8 0>
181  %r = or <2 x i1> %cmp0, %cmp1
182  ret <2 x i1> %r
183}
184
185define <2 x i1> @shl_nz_bounded_cnt_vec(<2 x i32> %x, <2 x i32> %y) {
186; CHECK-LABEL: @shl_nz_bounded_cnt_vec(
187; CHECK-NEXT:    ret <2 x i1> zeroinitializer
188;
189  %cnt = and <2 x i32> %x, <i32 16, i32 24>
190  %val = or <2 x i32> %y, <i32 131088, i32 16>
191  %shl = shl <2 x i32> %val, %cnt
192  %r = icmp eq <2 x i32> %shl, zeroinitializer
193  ret <2 x i1> %r
194}
195
196define i1 @shl_nz_bounded_cnt(i32 %cnt, i32 %y) {
197; CHECK-LABEL: @shl_nz_bounded_cnt(
198; CHECK-NEXT:    [[CNT_ULT4:%.*]] = icmp ult i32 [[CNT:%.*]], 4
199; CHECK-NEXT:    call void @llvm.assume(i1 [[CNT_ULT4]])
200; CHECK-NEXT:    ret i1 false
201;
202  %cnt_ult4 = icmp ult i32 %cnt, 4
203  call void @llvm.assume(i1 %cnt_ult4)
204  %val = or i32 %y, 131072
205  %shl = shl i32 %val, %cnt
206  %r = icmp eq i32 %shl, 0
207  ret i1 %r
208}
209
210define <2 x i1> @shl_nz_bounded_cnt_vec_todo_no_common_bit(<2 x i32> %x, <2 x i32> %y) {
211; CHECK-LABEL: @shl_nz_bounded_cnt_vec_todo_no_common_bit(
212; CHECK-NEXT:    [[CNT:%.*]] = and <2 x i32> [[X:%.*]], <i32 16, i32 32>
213; CHECK-NEXT:    [[VAL:%.*]] = or <2 x i32> [[Y:%.*]], splat (i32 16)
214; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i32> [[VAL]], [[CNT]]
215; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer
216; CHECK-NEXT:    ret <2 x i1> [[R]]
217;
218  %cnt = and <2 x i32> %x, <i32 16, i32 32>
219  %val = or <2 x i32> %y, <i32 16, i32 16>
220  %shl = shl <2 x i32> %val, %cnt
221  %r = icmp eq <2 x i32> %shl, zeroinitializer
222  ret <2 x i1> %r
223}
224
225define i1 @shl_maybe_zero_bounded_cnt_fail(i32 %x, i32 %y) {
226; CHECK-LABEL: @shl_maybe_zero_bounded_cnt_fail(
227; CHECK-NEXT:    [[CNT:%.*]] = and i32 [[X:%.*]], 16
228; CHECK-NEXT:    [[VAL:%.*]] = or i32 [[Y:%.*]], 65536
229; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[VAL]], [[CNT]]
230; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[SHL]], 0
231; CHECK-NEXT:    ret i1 [[R]]
232;
233  %cnt = and i32 %x, 16
234  %val = or i32 %y, 65536
235  %shl = shl i32 %val, %cnt
236  %r = icmp eq i32 %shl, 0
237  ret i1 %r
238}
239
240define i1 @shl_non_zero_nsw(i8 %s, i8 %cnt) {
241; CHECK-LABEL: @shl_non_zero_nsw(
242; CHECK-NEXT:    [[NZ:%.*]] = icmp ne i8 [[S:%.*]], 0
243; CHECK-NEXT:    call void @llvm.assume(i1 [[NZ]])
244; CHECK-NEXT:    ret i1 false
245;
246  %nz = icmp ne i8 %s, 0
247  call void @llvm.assume(i1 %nz)
248  %v = shl nsw i8 %s, %cnt
249  %r = icmp eq i8 %v, 0
250  ret i1 %r
251}
252
253define i1 @shl_maybe_zero_nsw_fail(i8 %s, i8 %cnt) {
254; CHECK-LABEL: @shl_maybe_zero_nsw_fail(
255; CHECK-NEXT:    [[V:%.*]] = shl nsw i8 [[S:%.*]], [[CNT:%.*]]
256; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[V]], 0
257; CHECK-NEXT:    ret i1 [[R]]
258;
259  %v = shl nsw i8 %s, %cnt
260  %r = icmp eq i8 %v, 0
261  ret i1 %r
262}
263
264define i1 @shl_out_of_range_is_poison(i32 %v, i32 %c) {
265; CHECK-LABEL: @shl_out_of_range_is_poison(
266; CHECK-NEXT:    ret i1 poison
267;
268  %sval = or i32 %v, 32
269  %shl = shl i32 %c, %sval
270  %z = icmp eq i32 %shl, 0
271  ret i1 %z
272}
273
274define i1 @lshr_nz_bounded_cnt(i32 %cnt, i32 %y) {
275; CHECK-LABEL: @lshr_nz_bounded_cnt(
276; CHECK-NEXT:    [[CNT_ULT4:%.*]] = icmp ult i32 [[CNT:%.*]], 4
277; CHECK-NEXT:    call void @llvm.assume(i1 [[CNT_ULT4]])
278; CHECK-NEXT:    ret i1 false
279;
280  %cnt_ult4 = icmp ult i32 %cnt, 4
281  call void @llvm.assume(i1 %cnt_ult4)
282  %val = or i32 %y, 90
283  %shl = lshr i32 %val, %cnt
284  %r = icmp eq i32 %shl, 0
285  ret i1 %r
286}
287
288define <2 x i1> @ashr_nz_bounded_cnt_vec(<2 x i32> %x, <2 x i32> %y) {
289; CHECK-LABEL: @ashr_nz_bounded_cnt_vec(
290; CHECK-NEXT:    ret <2 x i1> zeroinitializer
291;
292  %cnt = and <2 x i32> %x, <i32 16, i32 24>
293  %val = or <2 x i32> %y, <i32 402784272, i32 268697601>
294  %shl = ashr <2 x i32> %val, %cnt
295  %r = icmp eq <2 x i32> %shl, zeroinitializer
296  ret <2 x i1> %r
297}
298
299define i1 @lshr_nz_bounded_cnt_fail(i32 %cnt, i32 %y) {
300; CHECK-LABEL: @lshr_nz_bounded_cnt_fail(
301; CHECK-NEXT:    [[CNT_ULT:%.*]] = icmp ult i32 [[CNT:%.*]], 20
302; CHECK-NEXT:    call void @llvm.assume(i1 [[CNT_ULT]])
303; CHECK-NEXT:    [[VAL:%.*]] = or i32 [[Y:%.*]], 131072
304; CHECK-NEXT:    [[SHL:%.*]] = lshr i32 [[VAL]], [[CNT]]
305; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[SHL]], 0
306; CHECK-NEXT:    ret i1 [[R]]
307;
308  %cnt_ult = icmp ult i32 %cnt, 20
309  call void @llvm.assume(i1 %cnt_ult)
310  %val = or i32 %y, 131072
311  %shl = lshr i32 %val, %cnt
312  %r = icmp eq i32 %shl, 0
313  ret i1 %r
314}
315
316define <2 x i1> @ashr_nz_bounded_cnt_vec_fail(<2 x i32> %x, <2 x i32> %y) {
317; CHECK-LABEL: @ashr_nz_bounded_cnt_vec_fail(
318; CHECK-NEXT:    [[CNT:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 24)
319; CHECK-NEXT:    [[VAL:%.*]] = or <2 x i32> [[Y:%.*]], <i32 131088, i32 268697601>
320; CHECK-NEXT:    [[SHL:%.*]] = ashr <2 x i32> [[VAL]], [[CNT]]
321; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer
322; CHECK-NEXT:    ret <2 x i1> [[R]]
323;
324  %cnt = and <2 x i32> %x, <i32 24, i32 24>
325  %val = or <2 x i32> %y, <i32 131088, i32 268697601>
326  %shl = ashr <2 x i32> %val, %cnt
327  %r = icmp eq <2 x i32> %shl, zeroinitializer
328  ret <2 x i1> %r
329}
330
331define i1 @lshr_nonzero_and_shift_out_zeros(i32 %cnt, i32 %y) {
332; CHECK-LABEL: @lshr_nonzero_and_shift_out_zeros(
333; CHECK-NEXT:    [[CNT_ULT:%.*]] = icmp ult i32 [[CNT:%.*]], 4
334; CHECK-NEXT:    call void @llvm.assume(i1 [[CNT_ULT]])
335; CHECK-NEXT:    [[VAL:%.*]] = and i32 [[Y:%.*]], -131072
336; CHECK-NEXT:    [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0
337; CHECK-NEXT:    call void @llvm.assume(i1 [[VAL_NZ]])
338; CHECK-NEXT:    ret i1 false
339;
340  %cnt_ult = icmp ult i32 %cnt, 4
341  call void @llvm.assume(i1 %cnt_ult)
342  %val = and i32 %y, -131072
343  %val_nz = icmp ne i32 %val, 0
344  call void @llvm.assume(i1 %val_nz)
345  %shl = lshr i32 %val, %cnt
346  %r = icmp eq i32 %shl, 0
347  ret i1 %r
348}
349
350define i1 @ashr_nonzero_and_shift_out_zeros(i32 %ccnt, i32 %y) {
351; CHECK-LABEL: @ashr_nonzero_and_shift_out_zeros(
352; CHECK-NEXT:    [[VAL:%.*]] = and i32 [[Y:%.*]], -131072
353; CHECK-NEXT:    [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0
354; CHECK-NEXT:    call void @llvm.assume(i1 [[VAL_NZ]])
355; CHECK-NEXT:    ret i1 false
356;
357  %cnt = and i32 %ccnt, 7
358  %val = and i32 %y, -131072
359  %val_nz = icmp ne i32 %val, 0
360  call void @llvm.assume(i1 %val_nz)
361  %shl = ashr i32 %val, %cnt
362  %r = icmp eq i32 %shl, 0
363  ret i1 %r
364}
365
366define i1 @shl_nonzero_and_shift_out_zeros(i32 %ccnt, i32 %y) {
367; CHECK-LABEL: @shl_nonzero_and_shift_out_zeros(
368; CHECK-NEXT:    [[VAL:%.*]] = and i32 [[Y:%.*]], 131071
369; CHECK-NEXT:    [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0
370; CHECK-NEXT:    call void @llvm.assume(i1 [[VAL_NZ]])
371; CHECK-NEXT:    ret i1 false
372;
373  %cnt = and i32 %ccnt, 6
374  %val = and i32 %y, 131071
375  %val_nz = icmp ne i32 %val, 0
376  call void @llvm.assume(i1 %val_nz)
377  %shl = shl i32 %val, %cnt
378  %r = icmp eq i32 %shl, 0
379  ret i1 %r
380}
381
382define i1 @lshr_nonzero_and_shift_out_zeros_fail(i32 %cnt, i32 %y) {
383; CHECK-LABEL: @lshr_nonzero_and_shift_out_zeros_fail(
384; CHECK-NEXT:    [[CNT_ULT:%.*]] = icmp ult i32 [[CNT:%.*]], 19
385; CHECK-NEXT:    call void @llvm.assume(i1 [[CNT_ULT]])
386; CHECK-NEXT:    [[VAL:%.*]] = and i32 [[Y:%.*]], -131072
387; CHECK-NEXT:    [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0
388; CHECK-NEXT:    call void @llvm.assume(i1 [[VAL_NZ]])
389; CHECK-NEXT:    [[SHL:%.*]] = lshr i32 [[VAL]], [[CNT]]
390; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[SHL]], 0
391; CHECK-NEXT:    ret i1 [[R]]
392;
393  %cnt_ult = icmp ult i32 %cnt, 19
394  call void @llvm.assume(i1 %cnt_ult)
395  %val = and i32 %y, -131072
396  %val_nz = icmp ne i32 %val, 0
397  call void @llvm.assume(i1 %val_nz)
398  %shl = lshr i32 %val, %cnt
399  %r = icmp eq i32 %shl, 0
400  ret i1 %r
401}
402
403define i1 @ashr_nonzero_and_shift_out_zeros_fail(i32 %ccnt, i32 %y) {
404; CHECK-LABEL: @ashr_nonzero_and_shift_out_zeros_fail(
405; CHECK-NEXT:    [[CNT:%.*]] = and i32 [[CCNT:%.*]], 18
406; CHECK-NEXT:    [[VAL:%.*]] = and i32 [[Y:%.*]], -131072
407; CHECK-NEXT:    [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0
408; CHECK-NEXT:    call void @llvm.assume(i1 [[VAL_NZ]])
409; CHECK-NEXT:    [[SHL:%.*]] = ashr i32 [[VAL]], [[CNT]]
410; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[SHL]], 0
411; CHECK-NEXT:    ret i1 [[R]]
412;
413  %cnt = and i32 %ccnt, 18
414  %val = and i32 %y, -131072
415  %val_nz = icmp ne i32 %val, 0
416  call void @llvm.assume(i1 %val_nz)
417  %shl = ashr i32 %val, %cnt
418  %r = icmp eq i32 %shl, 0
419  ret i1 %r
420}
421
422define i1 @shl_nonzero_and_shift_out_zeros_fail(i32 %ccnt, i32 %y) {
423; CHECK-LABEL: @shl_nonzero_and_shift_out_zeros_fail(
424; CHECK-NEXT:    [[CNT:%.*]] = and i32 [[CCNT:%.*]], 6
425; CHECK-NEXT:    [[VAL:%.*]] = and i32 [[Y:%.*]], 268435455
426; CHECK-NEXT:    [[VAL_NZ:%.*]] = icmp ne i32 [[VAL]], 0
427; CHECK-NEXT:    call void @llvm.assume(i1 [[VAL_NZ]])
428; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[VAL]], [[CNT]]
429; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[SHL]], 0
430; CHECK-NEXT:    ret i1 [[R]]
431;
432  %cnt = and i32 %ccnt, 6
433  %val = and i32 %y, 268435455
434  %val_nz = icmp ne i32 %val, 0
435  call void @llvm.assume(i1 %val_nz)
436  %shl = shl i32 %val, %cnt
437  %r = icmp eq i32 %shl, 0
438  ret i1 %r
439}
440
441define i1 @sub_nonzero_ops_ne(i8 %xx, i8 %yy, i8 %z) {
442; CHECK-LABEL: @sub_nonzero_ops_ne(
443; CHECK-NEXT:    ret i1 false
444;
445  %x = and i8 %xx, 191
446  %y = or i8 %yy, 64
447  %s = sub i8 %x, %y
448  %exp = or i8 %z, %s
449  %r = icmp eq i8 %exp, 0
450  ret i1 %r
451}
452
453define i1 @sub_nonzero_ops_ne_fail(i8 %xx, i8 %yy, i8 %z) {
454; CHECK-LABEL: @sub_nonzero_ops_ne_fail(
455; CHECK-NEXT:    [[X:%.*]] = and i8 [[XX:%.*]], -64
456; CHECK-NEXT:    [[Y:%.*]] = or i8 [[YY:%.*]], 64
457; CHECK-NEXT:    [[S:%.*]] = sub i8 [[X]], [[Y]]
458; CHECK-NEXT:    [[EXP:%.*]] = or i8 [[Z:%.*]], [[S]]
459; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[EXP]], 0
460; CHECK-NEXT:    ret i1 [[R]]
461;
462  %x = and i8 %xx, 192
463  %y = or i8 %yy, 64
464  %s = sub i8 %x, %y
465  %exp = or i8 %z, %s
466  %r = icmp eq i8 %exp, 0
467  ret i1 %r
468}
469
470define i1 @add_nonzero_nuw(i8 %x, i8 %y) {
471; CHECK-LABEL: @add_nonzero_nuw(
472; CHECK-NEXT:    [[X_NZ:%.*]] = icmp ne i8 [[X:%.*]], 0
473; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
474; CHECK-NEXT:    ret i1 false
475;
476  %x_nz = icmp ne i8 %x, 0
477  call void @llvm.assume(i1 %x_nz)
478  %a = add nuw i8 %x, %y
479  %r = icmp eq i8 %a, 0
480  ret i1 %r
481}
482
483define i1 @add_nonzero_nsw_fail(i8 %x, i8 %y) {
484; CHECK-LABEL: @add_nonzero_nsw_fail(
485; CHECK-NEXT:    [[X_NZ:%.*]] = icmp ne i8 [[X:%.*]], 0
486; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
487; CHECK-NEXT:    [[A:%.*]] = add nsw i8 [[X]], [[Y:%.*]]
488; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[A]], 0
489; CHECK-NEXT:    ret i1 [[R]]
490;
491  %x_nz = icmp ne i8 %x, 0
492  call void @llvm.assume(i1 %x_nz)
493  %a = add nsw i8 %x, %y
494  %r = icmp eq i8 %a, 0
495  ret i1 %r
496}
497
498define i1 @udiv_y_le_x(i8 %xx, i8 %yy, i8 %z) {
499; CHECK-LABEL: @udiv_y_le_x(
500; CHECK-NEXT:    ret i1 false
501;
502  %x = or i8 %xx, 7
503  %y = and i8 %yy, 7
504  %d = udiv i8 %x, %y
505  %o = or i8 %d, %z
506  %r = icmp eq i8 %o, 0
507  ret i1 %r
508}
509
510define i1 @udiv_y_le_x_fail(i8 %xx, i8 %yy, i8 %z) {
511; CHECK-LABEL: @udiv_y_le_x_fail(
512; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], 6
513; CHECK-NEXT:    [[Y:%.*]] = and i8 [[YY:%.*]], 7
514; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[X]], [[Y]]
515; CHECK-NEXT:    [[O:%.*]] = or i8 [[D]], [[Z:%.*]]
516; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[O]], 0
517; CHECK-NEXT:    ret i1 [[R]]
518;
519  %x = or i8 %xx, 6
520  %y = and i8 %yy, 7
521  %d = udiv i8 %x, %y
522  %o = or i8 %d, %z
523  %r = icmp eq i8 %o, 0
524  ret i1 %r
525}
526
527define i1 @fshr_non_zero(i8 %x, i8 %y, i8 %z) {
528; CHECK-LABEL: @fshr_non_zero(
529; CHECK-NEXT:    [[PRED0:%.*]] = icmp ne i8 [[X:%.*]], 0
530; CHECK-NEXT:    call void @llvm.assume(i1 [[PRED0]])
531; CHECK-NEXT:    ret i1 false
532;
533  %pred0 = icmp ne i8 %x, 0
534  call void @llvm.assume(i1 %pred0)
535  %v = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)
536  %or = or i8 %v, %z
537  %r = icmp eq i8 %or, 0
538  ret i1 %r
539}
540
541define i1 @fshr_non_zero_fail(i8 %x, i8 %y, i8 %z, i8 %w) {
542; CHECK-LABEL: @fshr_non_zero_fail(
543; CHECK-NEXT:    [[PRED0:%.*]] = icmp ne i8 [[X:%.*]], 0
544; CHECK-NEXT:    call void @llvm.assume(i1 [[PRED0]])
545; CHECK-NEXT:    [[PRED1:%.*]] = icmp ne i8 [[W:%.*]], 0
546; CHECK-NEXT:    call void @llvm.assume(i1 [[PRED1]])
547; CHECK-NEXT:    [[V:%.*]] = tail call i8 @llvm.fshr.i8(i8 [[X]], i8 [[W]], i8 [[Y:%.*]])
548; CHECK-NEXT:    [[OR:%.*]] = or i8 [[V]], [[Z:%.*]]
549; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[OR]], 0
550; CHECK-NEXT:    ret i1 [[R]]
551;
552  %pred0 = icmp ne i8 %x, 0
553  call void @llvm.assume(i1 %pred0)
554  %pred1 = icmp ne i8 %w, 0
555  call void @llvm.assume(i1 %pred1)
556  %v = tail call i8 @llvm.fshr.i8(i8 %x, i8 %w, i8 %y)
557  %or = or i8 %v, %z
558  %r = icmp eq i8 %or, 0
559  ret i1 %r
560}
561
562define i1 @fshl_non_zero(i8 %x, i8 %y, i8 %z) {
563; CHECK-LABEL: @fshl_non_zero(
564; CHECK-NEXT:    [[PRED0:%.*]] = icmp ne i8 [[X:%.*]], 0
565; CHECK-NEXT:    call void @llvm.assume(i1 [[PRED0]])
566; CHECK-NEXT:    ret i1 false
567;
568  %pred0 = icmp ne i8 %x, 0
569  call void @llvm.assume(i1 %pred0)
570  %v = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)
571  %or = or i8 %v, %z
572  %r = icmp eq i8 %or, 0
573  ret i1 %r
574}
575
576define i1 @fshl_non_zero_fail(i8 %x, i8 %y, i8 %z, i8 %w) {
577; CHECK-LABEL: @fshl_non_zero_fail(
578; CHECK-NEXT:    [[PRED0:%.*]] = icmp ne i8 [[X:%.*]], 0
579; CHECK-NEXT:    call void @llvm.assume(i1 [[PRED0]])
580; CHECK-NEXT:    [[PRED1:%.*]] = icmp ne i8 [[W:%.*]], 0
581; CHECK-NEXT:    call void @llvm.assume(i1 [[PRED1]])
582; CHECK-NEXT:    [[V:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X]], i8 [[W]], i8 [[Y:%.*]])
583; CHECK-NEXT:    [[OR:%.*]] = or i8 [[V]], [[Z:%.*]]
584; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[OR]], 0
585; CHECK-NEXT:    ret i1 [[R]]
586;
587  %pred0 = icmp ne i8 %x, 0
588  call void @llvm.assume(i1 %pred0)
589  %pred1 = icmp ne i8 %w, 0
590  call void @llvm.assume(i1 %pred1)
591  %v = tail call i8 @llvm.fshl.i8(i8 %x, i8 %w, i8 %y)
592  %or = or i8 %v, %z
593  %r = icmp eq i8 %or, 0
594  ret i1 %r
595}
596
597define i1 @bitcast_nonzero(<2 x i8> %xx, i16 %ind) {
598; CHECK-LABEL: @bitcast_nonzero(
599; CHECK-NEXT:    ret i1 false
600;
601  %xa = add nuw nsw <2 x i8> %xx, <i8 1, i8 1>
602  %x = bitcast <2 x i8> %xa to i16
603  %z = or i16 %x, %ind
604  %r = icmp eq i16 %z, 0
605  ret i1 %r
606}
607
608define i1 @bitcast_todo_partial_nonzero_vec_to_int(<2 x i8> %xx, i16 %ind) {
609; CHECK-LABEL: @bitcast_todo_partial_nonzero_vec_to_int(
610; CHECK-NEXT:    [[XA:%.*]] = add nuw nsw <2 x i8> [[XX:%.*]], <i8 1, i8 0>
611; CHECK-NEXT:    [[X:%.*]] = bitcast <2 x i8> [[XA]] to i16
612; CHECK-NEXT:    [[Z:%.*]] = or i16 [[X]], [[IND:%.*]]
613; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[Z]], 0
614; CHECK-NEXT:    ret i1 [[R]]
615;
616  %xa = add nuw nsw <2 x i8> %xx, <i8 1, i8 0>
617  %x = bitcast <2 x i8> %xa to i16
618  %z = or i16 %x, %ind
619  %r = icmp eq i16 %z, 0
620  ret i1 %r
621}
622
623define <2 x i1> @bitcast_fail_nonzero_int_to_vec(i16 %xx, <2 x i8> %ind) {
624; CHECK-LABEL: @bitcast_fail_nonzero_int_to_vec(
625; CHECK-NEXT:    [[XA:%.*]] = add nuw nsw i16 [[XX:%.*]], 1
626; CHECK-NEXT:    [[X:%.*]] = bitcast i16 [[XA]] to <2 x i8>
627; CHECK-NEXT:    [[Z:%.*]] = or <2 x i8> [[X]], [[IND:%.*]]
628; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[Z]], zeroinitializer
629; CHECK-NEXT:    ret <2 x i1> [[R]]
630;
631  %xa = add nuw nsw i16 %xx, 1
632  %x = bitcast i16 %xa to <2 x i8>
633  %z = or <2 x i8> %x, %ind
634  %r = icmp eq <2 x i8> %z, zeroinitializer
635  ret <2 x i1> %r
636}
637
638define <2 x i1> @bitcast_veci8_to_veci16(<4 x i8> %xx, <2 x i16> %ind) {
639; CHECK-LABEL: @bitcast_veci8_to_veci16(
640; CHECK-NEXT:    ret <2 x i1> zeroinitializer
641;
642  %xa = add nuw nsw <4 x i8> %xx, <i8 1, i8 1, i8 1, i8 1>
643  %x = bitcast <4 x i8> %xa to <2 x i16>
644  %z = or <2 x i16> %x, %ind
645  %r = icmp eq <2 x i16> %z, zeroinitializer
646  ret <2 x i1> %r
647}
648
649define <3 x i1> @bitcast_veci3_to_veci4_fail_not_multiple(<4 x i3> %xx, <3 x i4> %ind) {
650; CHECK-LABEL: @bitcast_veci3_to_veci4_fail_not_multiple(
651; CHECK-NEXT:    [[XA:%.*]] = add nuw nsw <4 x i3> [[XX:%.*]], splat (i3 1)
652; CHECK-NEXT:    [[X:%.*]] = bitcast <4 x i3> [[XA]] to <3 x i4>
653; CHECK-NEXT:    [[Z:%.*]] = or <3 x i4> [[X]], [[IND:%.*]]
654; CHECK-NEXT:    [[R:%.*]] = icmp eq <3 x i4> [[Z]], zeroinitializer
655; CHECK-NEXT:    ret <3 x i1> [[R]]
656;
657  %xa = add nuw nsw <4 x i3> %xx, <i3 1, i3 1, i3 1, i3 1>
658  %x = bitcast <4 x i3> %xa to <3 x i4>
659  %z = or <3 x i4> %x, %ind
660  %r = icmp eq <3 x i4> %z, zeroinitializer
661  ret <3 x i1> %r
662}
663
664define <4 x i1> @bitcast_fail_veci16_to_veci8(<2 x i16> %xx, <4 x i8> %ind) {
665; CHECK-LABEL: @bitcast_fail_veci16_to_veci8(
666; CHECK-NEXT:    [[XA:%.*]] = add nuw nsw <2 x i16> [[XX:%.*]], splat (i16 1)
667; CHECK-NEXT:    [[X:%.*]] = bitcast <2 x i16> [[XA]] to <4 x i8>
668; CHECK-NEXT:    [[Z:%.*]] = or <4 x i8> [[X]], [[IND:%.*]]
669; CHECK-NEXT:    [[R:%.*]] = icmp eq <4 x i8> [[Z]], zeroinitializer
670; CHECK-NEXT:    ret <4 x i1> [[R]]
671;
672  %xa = add nuw nsw <2 x i16> %xx, <i16 1, i16 1>
673  %x = bitcast <2 x i16> %xa to <4 x i8>
674  %z = or <4 x i8> %x, %ind
675  %r = icmp eq <4 x i8> %z, zeroinitializer
676  ret <4 x i1> %r
677}
678
679define i1 @bitcast_nonzero_fail_dont_check_float(float %xx, i32 %ind) {
680; CHECK-LABEL: @bitcast_nonzero_fail_dont_check_float(
681; CHECK-NEXT:    [[XA:%.*]] = call float @llvm.maximum.f32(float [[XX:%.*]], float 1.000000e+00)
682; CHECK-NEXT:    [[X:%.*]] = bitcast float [[XA]] to i32
683; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X]], [[IND:%.*]]
684; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[Z]], 0
685; CHECK-NEXT:    ret i1 [[R]]
686;
687  %xa = call float @llvm.maximum.f32(float %xx, float 1.000000e+00)
688  %x = bitcast float %xa to i32
689  %z = or i32 %x, %ind
690  %r = icmp eq i32 %z, 0
691  ret i1 %r
692}
693
694define i1 @ctlz_true_nonzero(i8 %xx, i8 %ind) {
695; CHECK-LABEL: @ctlz_true_nonzero(
696; CHECK-NEXT:    ret i1 false
697;
698  %xs = lshr i8 %xx, 1
699  %x = call i8 @llvm.ctlz.i8(i8 %xs, i1 true)
700  %z = or i8 %x, %ind
701  %r = icmp eq i8 %z, 0
702  ret i1 %r
703}
704
705define i1 @ctlz_false_nonzero(i8 %xx, i8 %ind) {
706; CHECK-LABEL: @ctlz_false_nonzero(
707; CHECK-NEXT:    ret i1 false
708;
709  %xa = and i8 %xx, 127
710  %x = call i8 @llvm.ctlz.i8(i8 %xa, i1 true)
711  %z = or i8 %x, %ind
712  %r = icmp eq i8 %z, 0
713  ret i1 %r
714}
715
716define i1 @ctlz_nonzero_fail_maybe_neg(i8 %xx, i8 %ind) {
717; CHECK-LABEL: @ctlz_nonzero_fail_maybe_neg(
718; CHECK-NEXT:    [[XS:%.*]] = ashr i8 [[XX:%.*]], 1
719; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.ctlz.i8(i8 [[XS]], i1 true)
720; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
721; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
722; CHECK-NEXT:    ret i1 [[R]]
723;
724  %xs = ashr i8 %xx, 1
725  %x = call i8 @llvm.ctlz.i8(i8 %xs, i1 true)
726  %z = or i8 %x, %ind
727  %r = icmp eq i8 %z, 0
728  ret i1 %r
729}
730
731define i1 @cttz_true_nonzero(i8 %xx, i8 %ind) {
732; CHECK-LABEL: @cttz_true_nonzero(
733; CHECK-NEXT:    ret i1 false
734;
735  %xs = shl i8 %xx, 1
736  %x = call i8 @llvm.cttz.i8(i8 %xs, i1 true)
737  %z = or i8 %x, %ind
738  %r = icmp eq i8 %z, 0
739  ret i1 %r
740}
741
742define i1 @cttz_false_nonzero(i8 %xx, i8 %ind) {
743; CHECK-LABEL: @cttz_false_nonzero(
744; CHECK-NEXT:    ret i1 false
745;
746  %xa = and i8 %xx, -2
747  %x = call i8 @llvm.cttz.i8(i8 %xa, i1 true)
748  %z = or i8 %x, %ind
749  %r = icmp eq i8 %z, 0
750  ret i1 %r
751}
752
753define i1 @cttz_nonzero_fail_maybe_odd(i8 %xx, i8 %cnt, i8 %ind) {
754; CHECK-LABEL: @cttz_nonzero_fail_maybe_odd(
755; CHECK-NEXT:    [[XS:%.*]] = shl i8 [[XX:%.*]], [[CNT:%.*]]
756; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.cttz.i8(i8 [[XS]], i1 true)
757; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
758; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
759; CHECK-NEXT:    ret i1 [[R]]
760;
761  %xs = shl i8 %xx, %cnt
762  %x = call i8 @llvm.cttz.i8(i8 %xs, i1 true)
763  %z = or i8 %x, %ind
764  %r = icmp eq i8 %z, 0
765  ret i1 %r
766}
767
768define i1 @mul_nonzero_odd(i8 %xx, i8 %y, i8 %ind) {
769; CHECK-LABEL: @mul_nonzero_odd(
770; CHECK-NEXT:    [[Y_NZ:%.*]] = icmp ne i8 [[Y:%.*]], 0
771; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_NZ]])
772; CHECK-NEXT:    ret i1 false
773;
774  %xo = or i8 %xx, 1
775  %y_nz = icmp ne i8 %y, 0
776  call void @llvm.assume(i1 %y_nz)
777  %x = mul i8 %xo, %y
778  %z = or i8 %x, %ind
779  %r = icmp eq i8 %z, 0
780  ret i1 %r
781}
782
783define i1 @mul_nonzero_odd_fail_y_maybe_zero(i8 %xx, i8 %y, i8 %ind) {
784; CHECK-LABEL: @mul_nonzero_odd_fail_y_maybe_zero(
785; CHECK-NEXT:    [[XO:%.*]] = or i8 [[XX:%.*]], 1
786; CHECK-NEXT:    [[X:%.*]] = mul i8 [[XO]], [[Y:%.*]]
787; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
788; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
789; CHECK-NEXT:    ret i1 [[R]]
790;
791  %xo = or i8 %xx, 1
792  %x = mul i8 %xo, %y
793  %z = or i8 %x, %ind
794  %r = icmp eq i8 %z, 0
795  ret i1 %r
796}
797
798define i1 @sshl_nonzero(i8 %xx, i8 %y, i8 %ind) {
799; CHECK-LABEL: @sshl_nonzero(
800; CHECK-NEXT:    [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0
801; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
802; CHECK-NEXT:    ret i1 false
803;
804  %x_nz = icmp ne i8 %xx, 0
805  call void @llvm.assume(i1 %x_nz)
806  %x = call i8 @llvm.sshl.sat.i8(i8 %xx, i8 %y)
807  %z = or i8 %x, %ind
808  %r = icmp eq i8 %z, 0
809  ret i1 %r
810}
811
812define i1 @sshl_nonzero_fail_x_maybe_z(i8 %xx, i8 %y, i8 %ind) {
813; CHECK-LABEL: @sshl_nonzero_fail_x_maybe_z(
814; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.sshl.sat.i8(i8 [[XX:%.*]], i8 [[Y:%.*]])
815; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
816; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
817; CHECK-NEXT:    ret i1 [[R]]
818;
819  %x = call i8 @llvm.sshl.sat.i8(i8 %xx, i8 %y)
820  %z = or i8 %x, %ind
821  %r = icmp eq i8 %z, 0
822  ret i1 %r
823}
824
825define i1 @ushl_nonzero(i8 %xx, i8 %y, i8 %ind) {
826; CHECK-LABEL: @ushl_nonzero(
827; CHECK-NEXT:    [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0
828; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
829; CHECK-NEXT:    ret i1 false
830;
831  %x_nz = icmp ne i8 %xx, 0
832  call void @llvm.assume(i1 %x_nz)
833  %x = call i8 @llvm.ushl.sat.i8(i8 %xx, i8 %y)
834  %z = or i8 %x, %ind
835  %r = icmp eq i8 %z, 0
836  ret i1 %r
837}
838
839define i1 @ushl_nonzero_fail_x_maybe_z(i8 %xx, i8 %y, i8 %ind) {
840; CHECK-LABEL: @ushl_nonzero_fail_x_maybe_z(
841; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.ushl.sat.i8(i8 [[XX:%.*]], i8 [[Y:%.*]])
842; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
843; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
844; CHECK-NEXT:    ret i1 [[R]]
845;
846  %x = call i8 @llvm.ushl.sat.i8(i8 %xx, i8 %y)
847  %z = or i8 %x, %ind
848  %r = icmp eq i8 %z, 0
849  ret i1 %r
850}
851
852define i1 @ssub_sat_nonzero(i8 %xx, i8 %yy, i8 %ind) {
853; CHECK-LABEL: @ssub_sat_nonzero(
854; CHECK-NEXT:    ret i1 false
855;
856  %xa = and i8 %xx, 191
857  %yo = or i8 %yy, 64
858  %x = call i8 @llvm.ssub.sat.i8(i8 %xa, i8 %yo)
859  %z = or i8 %x, %ind
860  %r = icmp eq i8 %z, 0
861  ret i1 %r
862}
863
864define i1 @ssub_sat_nonzero_ne_known_bits_fail_overlap(i8 %xx, i8 %yy, i8 %ind) {
865; CHECK-LABEL: @ssub_sat_nonzero_ne_known_bits_fail_overlap(
866; CHECK-NEXT:    [[XA:%.*]] = and i8 [[XX:%.*]], -64
867; CHECK-NEXT:    [[YO:%.*]] = or i8 [[YY:%.*]], 64
868; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[XA]], i8 [[YO]])
869; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
870; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
871; CHECK-NEXT:    ret i1 [[R]]
872;
873  %xa = and i8 %xx, 192
874  %yo = or i8 %yy, 64
875  %x = call i8 @llvm.ssub.sat.i8(i8 %xa, i8 %yo)
876  %z = or i8 %x, %ind
877  %r = icmp eq i8 %z, 0
878  ret i1 %r
879}
880
881define i1 @usub_sat_nonzero(i8 %xx, i8 %yy, i8 %ind) {
882; CHECK-LABEL: @usub_sat_nonzero(
883; CHECK-NEXT:    [[Y_ULT_31:%.*]] = icmp ult i8 [[YY:%.*]], 31
884; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_ULT_31]])
885; CHECK-NEXT:    [[XO:%.*]] = or i8 [[XX:%.*]], 34
886; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[XO]], i8 [[YY]])
887; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
888; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
889; CHECK-NEXT:    ret i1 [[R]]
890;
891  %y_ult_31 = icmp ult i8 %yy, 31
892  call void @llvm.assume(i1 %y_ult_31)
893  %xo = or i8 %xx, 34
894  %x = call i8 @llvm.usub.sat.i8(i8 %xo, i8 %yy)
895  %z = or i8 %x, %ind
896  %r = icmp eq i8 %z, 0
897  ret i1 %r
898}
899
900define i1 @usub_sat_nonzero_fail(i8 %xx, i8 %yy, i8 %ind) {
901; CHECK-LABEL: @usub_sat_nonzero_fail(
902; CHECK-NEXT:    [[XA:%.*]] = and i8 [[XX:%.*]], 16
903; CHECK-NEXT:    [[YO:%.*]] = or i8 [[YY:%.*]], 7
904; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[XA]], i8 [[YO]])
905; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
906; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
907; CHECK-NEXT:    ret i1 [[R]]
908;
909  %xa = and i8 %xx, 16
910  %yo = or i8 %yy, 7
911  %x = call i8 @llvm.usub.sat.i8(i8 %xa, i8 %yo)
912  %z = or i8 %x, %ind
913  %r = icmp eq i8 %z, 0
914  ret i1 %r
915}
916
917define i1 @sadd_sat_nonzero(i8 %xx, i8 %yy, i8 %ind) {
918; CHECK-LABEL: @sadd_sat_nonzero(
919; CHECK-NEXT:    [[X_STRICT_POS:%.*]] = icmp sgt i8 [[XX:%.*]], 0
920; CHECK-NEXT:    [[Y_POS:%.*]] = icmp sge i8 [[YY:%.*]], 0
921; CHECK-NEXT:    call void @llvm.assume(i1 [[X_STRICT_POS]])
922; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_POS]])
923; CHECK-NEXT:    ret i1 false
924;
925  %x_strict_pos = icmp sgt i8 %xx, 0
926  %y_pos = icmp sge i8 %yy, 0
927  call void @llvm.assume(i1 %x_strict_pos)
928  call void @llvm.assume(i1 %y_pos)
929  %x = call i8 @llvm.sadd.sat.i8(i8 %xx, i8 %yy)
930  %z = or i8 %x, %ind
931  %r = icmp eq i8 %z, 0
932  ret i1 %r
933}
934
935define i1 @sadd_sat_nonzero_fail_maybe_zz(i8 %xx, i8 %yy, i8 %ind) {
936; CHECK-LABEL: @sadd_sat_nonzero_fail_maybe_zz(
937; CHECK-NEXT:    [[X_POS:%.*]] = icmp sge i8 [[XX:%.*]], 0
938; CHECK-NEXT:    [[Y_POS:%.*]] = icmp sge i8 [[YY:%.*]], 0
939; CHECK-NEXT:    call void @llvm.assume(i1 [[X_POS]])
940; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_POS]])
941; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[XX]], i8 [[YY]])
942; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
943; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
944; CHECK-NEXT:    ret i1 [[R]]
945;
946  %x_pos = icmp sge i8 %xx, 0
947  %y_pos = icmp sge i8 %yy, 0
948  call void @llvm.assume(i1 %x_pos)
949  call void @llvm.assume(i1 %y_pos)
950  %x = call i8 @llvm.sadd.sat.i8(i8 %xx, i8 %yy)
951  %z = or i8 %x, %ind
952  %r = icmp eq i8 %z, 0
953  ret i1 %r
954}
955
956define i1 @umax_nonzero(i8 %xx, i8 %yy, i8 %ind) {
957; CHECK-LABEL: @umax_nonzero(
958; CHECK-NEXT:    [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0
959; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
960; CHECK-NEXT:    ret i1 false
961;
962  %x_nz = icmp ne i8 %xx, 0
963  call void @llvm.assume(i1 %x_nz)
964  %x = call i8 @llvm.umax.i8(i8 %xx, i8 %yy)
965  %z = or i8 %x, %ind
966  %r = icmp eq i8 %z, 0
967  ret i1 %r
968}
969
970define i1 @umax_nonzero_fail_x_maybe_z(i8 %xx, i8 %yy, i8 %ind) {
971; CHECK-LABEL: @umax_nonzero_fail_x_maybe_z(
972; CHECK-NEXT:    [[X_NZ:%.*]] = icmp sge i8 [[XX:%.*]], 0
973; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
974; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.umax.i8(i8 [[XX]], i8 [[YY:%.*]])
975; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
976; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
977; CHECK-NEXT:    ret i1 [[R]]
978;
979  %x_nz = icmp sge i8 %xx, 0
980  call void @llvm.assume(i1 %x_nz)
981  %x = call i8 @llvm.umax.i8(i8 %xx, i8 %yy)
982  %z = or i8 %x, %ind
983  %r = icmp eq i8 %z, 0
984  ret i1 %r
985}
986
987define i1 @umin_nonzero(i8 %xx, i8 %yy, i8 %ind) {
988; CHECK-LABEL: @umin_nonzero(
989; CHECK-NEXT:    [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0
990; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
991; CHECK-NEXT:    [[Y_NZ:%.*]] = icmp ne i8 [[YY:%.*]], 0
992; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_NZ]])
993; CHECK-NEXT:    ret i1 false
994;
995  %x_nz = icmp ne i8 %xx, 0
996  call void @llvm.assume(i1 %x_nz)
997  %y_nz = icmp ne i8 %yy, 0
998  call void @llvm.assume(i1 %y_nz)
999  %x = call i8 @llvm.umin.i8(i8 %xx, i8 %yy)
1000  %z = or i8 %x, %ind
1001  %r = icmp eq i8 %z, 0
1002  ret i1 %r
1003}
1004
1005define i1 @umin_nonzero_fail_y_maybe_z(i8 %xx, i8 %yy, i8 %ind) {
1006; CHECK-LABEL: @umin_nonzero_fail_y_maybe_z(
1007; CHECK-NEXT:    [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0
1008; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
1009; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.umin.i8(i8 [[XX]], i8 [[YY:%.*]])
1010; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
1011; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
1012; CHECK-NEXT:    ret i1 [[R]]
1013;
1014  %x_nz = icmp ne i8 %xx, 0
1015  call void @llvm.assume(i1 %x_nz)
1016  %x = call i8 @llvm.umin.i8(i8 %xx, i8 %yy)
1017  %z = or i8 %x, %ind
1018  %r = icmp eq i8 %z, 0
1019  ret i1 %r
1020}
1021
1022define i1 @smin_nonzero(i8 %xx, i8 %yy, i8 %ind) {
1023; CHECK-LABEL: @smin_nonzero(
1024; CHECK-NEXT:    [[X_NZ:%.*]] = icmp ne i8 [[XX:%.*]], 0
1025; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
1026; CHECK-NEXT:    [[Y_NZ:%.*]] = icmp ne i8 [[YY:%.*]], 0
1027; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_NZ]])
1028; CHECK-NEXT:    ret i1 false
1029;
1030  %x_nz = icmp ne i8 %xx, 0
1031  call void @llvm.assume(i1 %x_nz)
1032  %y_nz = icmp ne i8 %yy, 0
1033  call void @llvm.assume(i1 %y_nz)
1034  %x = call i8 @llvm.umin.i8(i8 %xx, i8 %yy)
1035  %z = or i8 %x, %ind
1036  %r = icmp eq i8 %z, 0
1037  ret i1 %r
1038}
1039
1040define i1 @smin_nonzero_neg_arg(i8 %xx, i8 %yy, i8 %ind) {
1041; CHECK-LABEL: @smin_nonzero_neg_arg(
1042; CHECK-NEXT:    [[X_NEG:%.*]] = icmp slt i8 [[XX:%.*]], 0
1043; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NEG]])
1044; CHECK-NEXT:    ret i1 false
1045;
1046  %x_neg = icmp slt i8 %xx, 0
1047  call void @llvm.assume(i1 %x_neg)
1048  %x = call i8 @llvm.smin.i8(i8 %xx, i8 %yy)
1049  %z = or i8 %x, %ind
1050  %r = icmp eq i8 %z, 0
1051  ret i1 %r
1052}
1053
1054define i1 @smin_nonzero_fail_y_maybe_z(i8 %xx, i8 %yy, i8 %ind) {
1055; CHECK-LABEL: @smin_nonzero_fail_y_maybe_z(
1056; CHECK-NEXT:    [[X_NZ:%.*]] = icmp sle i8 [[XX:%.*]], 0
1057; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NZ]])
1058; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.smin.i8(i8 [[XX]], i8 [[YY:%.*]])
1059; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
1060; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
1061; CHECK-NEXT:    ret i1 [[R]]
1062;
1063  %x_nz = icmp sle i8 %xx, 0
1064  call void @llvm.assume(i1 %x_nz)
1065  %x = call i8 @llvm.smin.i8(i8 %xx, i8 %yy)
1066  %z = or i8 %x, %ind
1067  %r = icmp eq i8 %z, 0
1068  ret i1 %r
1069}
1070
1071define i1 @smax_nonzero_pos_arg(i8 %xx, i8 %yy, i8 %ind) {
1072; CHECK-LABEL: @smax_nonzero_pos_arg(
1073; CHECK-NEXT:    ret i1 false
1074;
1075  %ya = and i8 %yy, 127
1076  %yo = or i8 %ya, 1
1077  %x = call i8 @llvm.smax.i8(i8 %xx, i8 %yo)
1078  %z = or i8 %x, %ind
1079  %r = icmp eq i8 %z, 0
1080  ret i1 %r
1081}
1082
1083define i1 @smax_nonzero_pos_arg_fail_nonstrict_pos(i8 %xx, i8 %yy, i8 %ind) {
1084; CHECK-LABEL: @smax_nonzero_pos_arg_fail_nonstrict_pos(
1085; CHECK-NEXT:    [[Y_POS:%.*]] = icmp sge i8 [[YY:%.*]], 0
1086; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_POS]])
1087; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.smax.i8(i8 [[XX:%.*]], i8 [[YY]])
1088; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[IND:%.*]]
1089; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[Z]], 0
1090; CHECK-NEXT:    ret i1 [[R]]
1091;
1092  %y_pos = icmp sge i8 %yy, 0
1093  call void @llvm.assume(i1 %y_pos)
1094  %x = call i8 @llvm.smax.i8(i8 %xx, i8 %yy)
1095  %z = or i8 %x, %ind
1096  %r = icmp eq i8 %z, 0
1097  ret i1 %r
1098}
1099
1100define i1 @mul_nonzero_contains_nonzero_mul(i8 %x, i8 %y) {
1101; CHECK-LABEL: @mul_nonzero_contains_nonzero_mul(
1102; CHECK-NEXT:    ret i1 true
1103;
1104  %xx = or i8 %x, 16
1105  %yy = or i8 %y, 8
1106  %xy = mul i8 %xx, %yy
1107  %nz = icmp ne i8 %xy, 0
1108  ret i1 %nz
1109}
1110
1111define i1 @src_mul_maybe_zero_no_nonzero_mul(i8 %x, i8 %y) {
1112; CHECK-LABEL: @src_mul_maybe_zero_no_nonzero_mul(
1113; CHECK-NEXT:    [[XX:%.*]] = or i8 [[X:%.*]], 96
1114; CHECK-NEXT:    [[YY:%.*]] = or i8 [[Y:%.*]], 8
1115; CHECK-NEXT:    [[XY:%.*]] = mul i8 [[XX]], [[YY]]
1116; CHECK-NEXT:    [[NZ:%.*]] = icmp ne i8 [[XY]], 0
1117; CHECK-NEXT:    ret i1 [[NZ]]
1118;
1119  %xx = or i8 %x, 96
1120  %yy = or i8 %y, 8
1121  %xy = mul i8 %xx, %yy
1122  %nz = icmp ne i8 %xy, 0
1123  ret i1 %nz
1124}
1125
1126define i1 @sdiv_known_non_zero(i8 %x, i8 %y) {
1127; CHECK-LABEL: @sdiv_known_non_zero(
1128; CHECK-NEXT:    ret i1 true
1129;
1130  %xx0 = or i8 %x, 135
1131  %xx = and i8 %xx0, -2
1132  %xy = sdiv i8 %xx, -2
1133  %nz = icmp ne i8 %xy, 0
1134  ret i1 %nz
1135}
1136
1137define i1 @sdiv_known_non_zero2(i8 %x, i8 %y) {
1138; CHECK-LABEL: @sdiv_known_non_zero2(
1139; CHECK-NEXT:    ret i1 true
1140;
1141  %xx0 = or i8 %x, 15
1142  %xx = and i8 %xx0, -4
1143  %yy = and i8 %y, 3
1144  %xy = sdiv i8 %xx, %yy
1145  %nz = icmp ne i8 %xy, 0
1146  ret i1 %nz
1147}
1148
1149define i1 @sdiv_known_non_zero_fail(i8 %x, i8 %y) {
1150; CHECK-LABEL: @sdiv_known_non_zero_fail(
1151; CHECK-NEXT:    [[XX:%.*]] = or i8 [[X:%.*]], 15
1152; CHECK-NEXT:    [[YY:%.*]] = and i8 [[Y:%.*]], 3
1153; CHECK-NEXT:    [[XY:%.*]] = sdiv i8 [[XX]], [[YY]]
1154; CHECK-NEXT:    [[NZ:%.*]] = icmp ne i8 [[XY]], 0
1155; CHECK-NEXT:    ret i1 [[NZ]]
1156;
1157  %xx = or i8 %x, 15
1158  %yy = and i8 %y, 3
1159  %xy = sdiv i8 %xx, %yy
1160  %nz = icmp ne i8 %xy, 0
1161  ret i1 %nz
1162}
1163
1164define <2 x i1> @cmp_excludes_zero_with_nonsplat_vec(<2 x i8> %a, <2 x i8> %b) {
1165; CHECK-LABEL: @cmp_excludes_zero_with_nonsplat_vec(
1166; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1167;
1168  %c = icmp sge <2 x i8> %a, <i8 1, i8 4>
1169  %s = select <2 x i1> %c, <2 x i8> %a, <2 x i8> <i8 4, i8 5>
1170  %and = or <2 x i8> %s, %b
1171  %r = icmp eq <2 x i8> %and, zeroinitializer
1172  ret <2 x i1> %r
1173}
1174
1175define <2 x i1> @cmp_excludes_zero_with_nonsplat_vec_wundef(<2 x i8> %a, <2 x i8> %b) {
1176; CHECK-LABEL: @cmp_excludes_zero_with_nonsplat_vec_wundef(
1177; CHECK-NEXT:    [[C:%.*]] = icmp sge <2 x i8> [[A:%.*]], <i8 1, i8 undef>
1178; CHECK-NEXT:    [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[A]], <2 x i8> <i8 4, i8 5>
1179; CHECK-NEXT:    [[AND:%.*]] = or <2 x i8> [[S]], [[B:%.*]]
1180; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer
1181; CHECK-NEXT:    ret <2 x i1> [[R]]
1182;
1183  %c = icmp sge <2 x i8> %a, <i8 1, i8 undef>
1184  %s = select <2 x i1> %c, <2 x i8> %a, <2 x i8> <i8 4, i8 5>
1185  %and = or <2 x i8> %s, %b
1186  %r = icmp eq <2 x i8> %and, zeroinitializer
1187  ret <2 x i1> %r
1188}
1189
1190define <2 x i1> @cmp_excludes_zero_with_nonsplat_vec_wpoison(<2 x i8> %a, <2 x i8> %b) {
1191; CHECK-LABEL: @cmp_excludes_zero_with_nonsplat_vec_wpoison(
1192; CHECK-NEXT:    [[C:%.*]] = icmp sge <2 x i8> [[A:%.*]], <i8 1, i8 poison>
1193; CHECK-NEXT:    [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[A]], <2 x i8> <i8 4, i8 5>
1194; CHECK-NEXT:    [[AND:%.*]] = or <2 x i8> [[S]], [[B:%.*]]
1195; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer
1196; CHECK-NEXT:    ret <2 x i1> [[R]]
1197;
1198  %c = icmp sge <2 x i8> %a, <i8 1, i8 poison>
1199  %s = select <2 x i1> %c, <2 x i8> %a, <2 x i8> <i8 4, i8 5>
1200  %and = or <2 x i8> %s, %b
1201  %r = icmp eq <2 x i8> %and, zeroinitializer
1202  ret <2 x i1> %r
1203}
1204
1205define <2 x i1> @cmp_excludes_zero_with_nonsplat_vec_fail(<2 x i8> %a, <2 x i8> %b) {
1206; CHECK-LABEL: @cmp_excludes_zero_with_nonsplat_vec_fail(
1207; CHECK-NEXT:    [[C:%.*]] = icmp sge <2 x i8> [[A:%.*]], <i8 0, i8 4>
1208; CHECK-NEXT:    [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[A]], <2 x i8> <i8 4, i8 5>
1209; CHECK-NEXT:    [[AND:%.*]] = or <2 x i8> [[S]], [[B:%.*]]
1210; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer
1211; CHECK-NEXT:    ret <2 x i1> [[R]]
1212;
1213  %c = icmp sge <2 x i8> %a, <i8 0, i8 4>
1214  %s = select <2 x i1> %c, <2 x i8> %a, <2 x i8> <i8 4, i8 5>
1215  %and = or <2 x i8> %s, %b
1216  %r = icmp eq <2 x i8> %and, zeroinitializer
1217  ret <2 x i1> %r
1218}
1219
1220define i1 @sub_via_non_eq(i8 %x, i8 %y) {
1221; CHECK-LABEL: @sub_via_non_eq(
1222; CHECK-NEXT:    [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
1223; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
1224; CHECK-NEXT:    ret i1 false
1225;
1226  %ne = icmp ne i8 %x, 0
1227  call void @llvm.assume(i1 %ne)
1228  %shl = shl nuw i8 %x, 3
1229  %sub = sub i8 %x, %shl
1230  %cmp = icmp eq i8 %sub, 0
1231  ret i1 %cmp
1232}
1233
1234; Test mismatch of ptrtoints type and pointer size
1235define i1 @recursiveGEP_orcmp_truncPtr(ptr %val1, i32 %val2) {
1236; CHECK-LABEL: @recursiveGEP_orcmp_truncPtr(
1237; CHECK-NEXT:  entry:
1238; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
1239; CHECK:       while.cond.i:
1240; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
1241; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 1
1242; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
1243; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
1244; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
1245; CHECK:       while.end.i:
1246; CHECK-NEXT:    [[SUB_PTR_LHS_CAST_I:%.*]] = ptrtoint ptr [[TEST_0_I]] to i32
1247; CHECK-NEXT:    [[SUB_PTR_RHS_CAST_I:%.*]] = ptrtoint ptr [[VAL1]] to i32
1248; CHECK-NEXT:    [[SUB_PTR_SUB_I:%.*]] = sub i32 [[SUB_PTR_LHS_CAST_I]], [[SUB_PTR_RHS_CAST_I]]
1249; CHECK-NEXT:    [[ORVAL:%.*]] = or i32 [[VAL2:%.*]], [[SUB_PTR_SUB_I]]
1250; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq i32 [[ORVAL]], 0
1251; CHECK-NEXT:    ret i1 [[BOOL]]
1252;
1253entry:
1254  br label %while.cond.i
1255
1256while.cond.i:
1257  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
1258  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
1259  %0 = load i8, ptr %test.0.i, align 2
1260  %cmp3.not.i = icmp eq i8 %0, 0
1261  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
1262
1263while.end.i:
1264  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i32
1265  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i32
1266  %sub.ptr.sub.i = sub i32 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
1267  %orval = or i32 %val2, %sub.ptr.sub.i
1268  %bool = icmp eq i32 %orval, 0
1269  ret i1 %bool
1270}
1271
1272define i1 @check_get_vector_length(i32 %x, i32 %y) {
1273; CHECK-LABEL: @check_get_vector_length(
1274; CHECK-NEXT:    [[NE:%.*]] = icmp ne i32 [[X:%.*]], 0
1275; CHECK-NEXT:    br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1276; CHECK:       true:
1277; CHECK-NEXT:    [[Z:%.*]] = call i32 @llvm.experimental.get.vector.length.i32(i32 [[X]], i32 1, i1 true)
1278; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i32 [[Z]], [[Y:%.*]]
1279; CHECK-NEXT:    ret i1 [[CMP0]]
1280; CHECK:       false:
1281; CHECK-NEXT:    ret i1 [[NE]]
1282;
1283  %ne = icmp ne i32 %x, 0
1284  br i1 %ne, label %true, label %false
1285true:
1286  %z = call i32 @llvm.experimental.get.vector.length.i32(i32 %x, i32 1, i1 true)
1287  %cmp0 = icmp ugt i32 %z, %y
1288  %cmp1 = icmp eq i32 %y, 0
1289  %r = or i1 %cmp0, %cmp1
1290  ret i1 %r
1291false:
1292  ret i1 %ne
1293}
1294
1295define <2 x i1> @range_metadata_vec(ptr %p, <2 x i32> %x) {
1296; CHECK-LABEL: @range_metadata_vec(
1297; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1298;
1299  %v = load <2 x i32>, ptr %p, !range !{i32 1, i32 100}
1300  %or = or <2 x i32> %v, %x
1301  %cmp = icmp ne <2 x i32> %or, zeroinitializer
1302  ret <2 x i1> %cmp
1303}
1304
1305define i1 @range_attr(i8 range(i8 1, 0) %x, i8 %y) {
1306; CHECK-LABEL: @range_attr(
1307; CHECK-NEXT:    ret i1 false
1308;
1309  %or = or i8 %y, %x
1310  %cmp = icmp eq i8 %or, 0
1311  ret i1 %cmp
1312}
1313
1314define i1 @neg_range_attr(i8 range(i8 -1, 1) %x, i8 %y) {
1315; CHECK-LABEL: @neg_range_attr(
1316; CHECK-NEXT:    [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
1317; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[OR]], 0
1318; CHECK-NEXT:    ret i1 [[CMP]]
1319;
1320  %or = or i8 %y, %x
1321  %cmp = icmp eq i8 %or, 0
1322  ret i1 %cmp
1323}
1324
1325declare range(i8 1, 0) i8 @returns_non_zero_range_helper()
1326declare range(i8 -1, 1) i8 @returns_contain_zero_range_helper()
1327
1328define i1 @range_return(i8 %y) {
1329; CHECK-LABEL: @range_return(
1330; CHECK-NEXT:    [[X:%.*]] = call i8 @returns_non_zero_range_helper()
1331; CHECK-NEXT:    ret i1 false
1332;
1333  %x = call i8 @returns_non_zero_range_helper()
1334  %or = or i8 %y, %x
1335  %cmp = icmp eq i8 %or, 0
1336  ret i1 %cmp
1337}
1338
1339define i1 @neg_range_return(i8 %y) {
1340; CHECK-LABEL: @neg_range_return(
1341; CHECK-NEXT:    [[X:%.*]] = call i8 @returns_contain_zero_range_helper()
1342; CHECK-NEXT:    [[OR:%.*]] = or i8 [[Y:%.*]], [[X]]
1343; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[OR]], 0
1344; CHECK-NEXT:    ret i1 [[CMP]]
1345;
1346  %x = call i8 @returns_contain_zero_range_helper()
1347  %or = or i8 %y, %x
1348  %cmp = icmp eq i8 %or, 0
1349  ret i1 %cmp
1350}
1351
1352declare i8 @returns_i8_helper()
1353
1354define i1 @range_call(i8 %y) {
1355; CHECK-LABEL: @range_call(
1356; CHECK-NEXT:    [[X:%.*]] = call range(i8 1, 0) i8 @returns_i8_helper()
1357; CHECK-NEXT:    ret i1 false
1358;
1359  %x = call range(i8 1, 0) i8 @returns_i8_helper()
1360  %or = or i8 %y, %x
1361  %cmp = icmp eq i8 %or, 0
1362  ret i1 %cmp
1363}
1364
1365define i1 @neg_range_call(i8 %y) {
1366; CHECK-LABEL: @neg_range_call(
1367; CHECK-NEXT:    [[X:%.*]] = call range(i8 -1, 1) i8 @returns_i8_helper()
1368; CHECK-NEXT:    [[OR:%.*]] = or i8 [[Y:%.*]], [[X]]
1369; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[OR]], 0
1370; CHECK-NEXT:    ret i1 [[CMP]]
1371;
1372  %x = call range(i8 -1, 1) i8 @returns_i8_helper()
1373  %or = or i8 %y, %x
1374  %cmp = icmp eq i8 %or, 0
1375  ret i1 %cmp
1376}
1377
1378define <2 x i1> @range_attr_vec(<2 x i8> range(i8 1, 0) %x, <2 x i8> %y) {
1379; CHECK-LABEL: @range_attr_vec(
1380; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1381;
1382  %or = or <2 x i8> %y, %x
1383  %cmp = icmp ne <2 x i8> %or, zeroinitializer
1384  ret <2 x i1> %cmp
1385}
1386
1387define <2 x i1> @neg_range_attr_vec(<2 x i8> range(i8 -1, 1) %x, <2 x i8> %y) {
1388; CHECK-LABEL: @neg_range_attr_vec(
1389; CHECK-NEXT:    [[OR:%.*]] = or <2 x i8> [[Y:%.*]], [[X:%.*]]
1390; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], zeroinitializer
1391; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1392;
1393  %or = or <2 x i8> %y, %x
1394  %cmp = icmp ne <2 x i8> %or, zeroinitializer
1395  ret <2 x i1> %cmp
1396}
1397
1398declare range(i8 1, 0) <2 x i8> @returns_non_zero_range_helper_vec()
1399declare range(i8 -1, 1) <2 x i8> @returns_contain_zero_range_helper_vec()
1400
1401define <2 x i1> @range_return_vec(<2 x i8> %y) {
1402; CHECK-LABEL: @range_return_vec(
1403; CHECK-NEXT:    [[X:%.*]] = call <2 x i8> @returns_non_zero_range_helper_vec()
1404; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1405;
1406  %x = call <2 x i8> @returns_non_zero_range_helper_vec()
1407  %or = or <2 x i8> %y, %x
1408  %cmp = icmp ne <2 x i8> %or, zeroinitializer
1409  ret <2 x i1> %cmp
1410}
1411
1412define <2 x i1> @neg_range_return_vec(<2 x i8> %y) {
1413; CHECK-LABEL: @neg_range_return_vec(
1414; CHECK-NEXT:    [[X:%.*]] = call <2 x i8> @returns_contain_zero_range_helper_vec()
1415; CHECK-NEXT:    [[OR:%.*]] = or <2 x i8> [[Y:%.*]], [[X]]
1416; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], zeroinitializer
1417; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1418;
1419  %x = call <2 x i8> @returns_contain_zero_range_helper_vec()
1420  %or = or <2 x i8> %y, %x
1421  %cmp = icmp ne <2 x i8> %or, zeroinitializer
1422  ret <2 x i1> %cmp
1423}
1424
1425declare <2 x i8> @returns_i8_helper_vec()
1426
1427define <2 x i1> @range_call_vec(<2 x i8> %y) {
1428; CHECK-LABEL: @range_call_vec(
1429; CHECK-NEXT:    [[X:%.*]] = call range(i8 1, 0) <2 x i8> @returns_i8_helper_vec()
1430; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1431;
1432  %x = call range(i8 1, 0) <2 x i8> @returns_i8_helper_vec()
1433  %or = or <2 x i8> %y, %x
1434  %cmp = icmp ne <2 x i8> %or, zeroinitializer
1435  ret <2 x i1> %cmp
1436}
1437
1438define <2 x i1> @neg_range_call_vec(<2 x i8> %y) {
1439; CHECK-LABEL: @neg_range_call_vec(
1440; CHECK-NEXT:    [[X:%.*]] = call range(i8 -1, 1) <2 x i8> @returns_i8_helper_vec()
1441; CHECK-NEXT:    [[OR:%.*]] = or <2 x i8> [[Y:%.*]], [[X]]
1442; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], zeroinitializer
1443; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1444;
1445  %x = call range(i8 -1, 1) <2 x i8> @returns_i8_helper_vec()
1446  %or = or <2 x i8> %y, %x
1447  %cmp = icmp ne <2 x i8> %or, zeroinitializer
1448  ret <2 x i1> %cmp
1449}
1450
1451define i1 @trunc_nsw_non_zero(i8 %x) {
1452; CHECK-LABEL: @trunc_nsw_non_zero(
1453; CHECK-NEXT:    [[X_NE_Z:%.*]] = icmp ne i8 [[X:%.*]], 0
1454; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NE_Z]])
1455; CHECK-NEXT:    ret i1 true
1456;
1457  %x_ne_z = icmp ne i8 %x, 0
1458  call void @llvm.assume(i1 %x_ne_z)
1459  %v = trunc nsw i8 %x to i4
1460  %r = icmp ne i4 %v, 0
1461  ret i1 %r
1462}
1463
1464define i1 @trunc_nuw_non_zero(i8 %xx) {
1465; CHECK-LABEL: @trunc_nuw_non_zero(
1466; CHECK-NEXT:    ret i1 false
1467;
1468  %x = add nuw i8 %xx, 1
1469  %v = trunc nuw i8 %x to i4
1470  %r = icmp eq i4 %v, 0
1471  ret i1 %r
1472}
1473
1474define i1 @trunc_non_zero_fail(i8 %x) {
1475; CHECK-LABEL: @trunc_non_zero_fail(
1476; CHECK-NEXT:    [[X_NE_Z:%.*]] = icmp ne i8 [[X:%.*]], 0
1477; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NE_Z]])
1478; CHECK-NEXT:    [[R:%.*]] = trunc i8 [[X]] to i1
1479; CHECK-NEXT:    ret i1 [[R]]
1480;
1481  %x_ne_z = icmp ne i8 %x, 0
1482  call void @llvm.assume(i1 %x_ne_z)
1483  %r = trunc i8 %x to i1
1484  ret i1 %r
1485}
1486
1487define i1 @trunc_nsw_nuw_non_zero_fail(i8 %xx) {
1488; CHECK-LABEL: @trunc_nsw_nuw_non_zero_fail(
1489; CHECK-NEXT:    [[X:%.*]] = add nsw i8 [[XX:%.*]], 1
1490; CHECK-NEXT:    [[V:%.*]] = trunc nuw nsw i8 [[X]] to i4
1491; CHECK-NEXT:    [[R:%.*]] = icmp eq i4 [[V]], 0
1492; CHECK-NEXT:    ret i1 [[R]]
1493;
1494  %x = add nsw i8 %xx, 1
1495  %v = trunc nsw nuw i8 %x to i4
1496  %r = icmp eq i4 %v, 0
1497  ret i1 %r
1498}
1499
1500define <4 x i1> @vec_reverse_non_zero(<4 x i8> %xx) {
1501; CHECK-LABEL: @vec_reverse_non_zero(
1502; CHECK-NEXT:    ret <4 x i1> zeroinitializer
1503;
1504  %x = add nuw <4 x i8> %xx, <i8 1, i8 1, i8 1, i8 1>
1505  %rev = call <4 x i8> @llvm.vector.reverse(<4 x i8> %x)
1506  %r = icmp eq <4 x i8> %rev, zeroinitializer
1507  ret <4 x i1> %r
1508}
1509
1510define <4 x i1> @vec_reverse_non_zero_fail(<4 x i8> %xx) {
1511; CHECK-LABEL: @vec_reverse_non_zero_fail(
1512; CHECK-NEXT:    [[X:%.*]] = add nuw <4 x i8> [[XX:%.*]], <i8 1, i8 0, i8 1, i8 1>
1513; CHECK-NEXT:    [[REV:%.*]] = call <4 x i8> @llvm.vector.reverse.v4i8(<4 x i8> [[X]])
1514; CHECK-NEXT:    [[R:%.*]] = icmp eq <4 x i8> [[REV]], zeroinitializer
1515; CHECK-NEXT:    ret <4 x i1> [[R]]
1516;
1517  %x = add nuw <4 x i8> %xx, <i8 1, i8 0, i8 1, i8 1>
1518  %rev = call <4 x i8> @llvm.vector.reverse(<4 x i8> %x)
1519  %r = icmp eq <4 x i8> %rev, zeroinitializer
1520  ret <4 x i1> %r
1521}
1522
1523define i1 @vec_reverse_non_zero_demanded(<4 x i8> %xx) {
1524; CHECK-LABEL: @vec_reverse_non_zero_demanded(
1525; CHECK-NEXT:    ret i1 false
1526;
1527  %x = add nuw <4 x i8> %xx, <i8 1, i8 0, i8 0, i8 0>
1528  %rev = call <4 x i8> @llvm.vector.reverse(<4 x i8> %x)
1529  %ele = extractelement <4 x i8> %rev, i64 3
1530  %r = icmp eq i8 %ele, 0
1531  ret i1 %r
1532}
1533
1534define i1 @vec_reverse_non_zero_demanded_fail(<4 x i8> %xx) {
1535; CHECK-LABEL: @vec_reverse_non_zero_demanded_fail(
1536; CHECK-NEXT:    [[X:%.*]] = add nuw <4 x i8> [[XX:%.*]], <i8 1, i8 0, i8 0, i8 0>
1537; CHECK-NEXT:    [[REV:%.*]] = call <4 x i8> @llvm.vector.reverse.v4i8(<4 x i8> [[X]])
1538; CHECK-NEXT:    [[ELE:%.*]] = extractelement <4 x i8> [[REV]], i64 2
1539; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[ELE]], 0
1540; CHECK-NEXT:    ret i1 [[R]]
1541;
1542  %x = add nuw <4 x i8> %xx, <i8 1, i8 0, i8 0, i8 0>
1543  %rev = call <4 x i8> @llvm.vector.reverse(<4 x i8> %x)
1544  %ele = extractelement <4 x i8> %rev, i64 2
1545  %r = icmp eq i8 %ele, 0
1546  ret i1 %r
1547}
1548
1549declare i32 @llvm.experimental.get.vector.length.i32(i32, i32, i1)
1550