xref: /llvm-project/llvm/test/Transforms/InstSimplify/icmp.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3
4target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
5
6declare void @usei8ptr(ptr %ptr)
7
8; Ensure that we do not crash when looking at such a weird bitcast.
9define i1 @bitcast_from_single_element_pointer_vector_to_pointer(<1 x ptr> %ptr1vec, ptr %ptr2) {
10; CHECK-LABEL: @bitcast_from_single_element_pointer_vector_to_pointer(
11; CHECK-NEXT:    [[PTR1:%.*]] = bitcast <1 x ptr> [[PTR1VEC:%.*]] to ptr
12; CHECK-NEXT:    call void @usei8ptr(ptr [[PTR1]])
13; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[PTR1]], [[PTR2:%.*]]
14; CHECK-NEXT:    ret i1 [[CMP]]
15;
16  %ptr1 = bitcast <1 x ptr> %ptr1vec to ptr
17  call void @usei8ptr(ptr %ptr1)
18  %cmp = icmp eq ptr %ptr1, %ptr2
19  ret i1 %cmp
20}
21
22define i1 @poison(i32 %x) {
23; CHECK-LABEL: @poison(
24; CHECK-NEXT:    ret i1 poison
25;
26  %v = icmp eq i32 %x, poison
27  ret i1 %v
28}
29
30define i1 @poison2(i32 %x) {
31; CHECK-LABEL: @poison2(
32; CHECK-NEXT:    ret i1 poison
33;
34  %v = icmp slt i32 %x, poison
35  ret i1 %v
36}
37
38define i1 @mul_div_cmp_smaller(i8 %x) {
39; CHECK-LABEL: @mul_div_cmp_smaller(
40; CHECK-NEXT:    ret i1 true
41;
42  %mul = mul i8 %x, 3
43  %div = udiv i8 %mul, 4
44  %cmp = icmp ule i8 %div, %x
45  ret i1 %cmp
46}
47
48define i1 @mul_div_cmp_equal(i8 %x) {
49; CHECK-LABEL: @mul_div_cmp_equal(
50; CHECK-NEXT:    ret i1 true
51;
52  %mul = mul i8 %x, 3
53  %div = udiv i8 %mul, 3
54  %cmp = icmp ule i8 %div, %x
55  ret i1 %cmp
56}
57
58; Negative test: 3>2
59define i1 @mul_div_cmp_greater(i8 %x) {
60; CHECK-LABEL: @mul_div_cmp_greater(
61; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 3
62; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[MUL]], 2
63; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[DIV]], [[X]]
64; CHECK-NEXT:    ret i1 [[CMP]]
65;
66  %mul = mul i8 %x, 3
67  %div = udiv i8 %mul, 2
68  %cmp = icmp ule i8 %div, %x
69  ret i1 %cmp
70}
71define i1 @mul_div_cmp_ugt(i8 %x) {
72; CHECK-LABEL: @mul_div_cmp_ugt(
73; CHECK-NEXT:    ret i1 false
74;
75  %mul = mul i8 %x, 3
76  %div = udiv i8 %mul, 4
77  %cmp = icmp ugt i8 %div, %x
78  ret i1 %cmp
79}
80
81; Negative test: Wrong predicate
82define i1 @mul_div_cmp_uge(i8 %x) {
83; CHECK-LABEL: @mul_div_cmp_uge(
84; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 3
85; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[MUL]], 4
86; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[DIV]], [[X]]
87; CHECK-NEXT:    ret i1 [[CMP]]
88;
89  %mul = mul i8 %x, 3
90  %div = udiv i8 %mul, 4
91  %cmp = icmp uge i8 %div, %x
92  ret i1 %cmp
93}
94
95; Negative test: Wrong predicate
96define i1 @mul_div_cmp_ult(i8 %x) {
97; CHECK-LABEL: @mul_div_cmp_ult(
98; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 3
99; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[MUL]], 4
100; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[DIV]], [[X]]
101; CHECK-NEXT:    ret i1 [[CMP]]
102;
103  %mul = mul i8 %x, 3
104  %div = udiv i8 %mul, 4
105  %cmp = icmp ult i8 %div, %x
106  ret i1 %cmp
107}
108
109; Negative test: Wrong icmp operand
110define i1 @mul_div_cmp_wrong_operand(i8 %x, i8 %y) {
111; CHECK-LABEL: @mul_div_cmp_wrong_operand(
112; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 3
113; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[MUL]], 4
114; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[DIV]], [[Y:%.*]]
115; CHECK-NEXT:    ret i1 [[CMP]]
116;
117  %mul = mul i8 %x, 3
118  %div = udiv i8 %mul, 4
119  %cmp = icmp ule i8 %div, %y
120  ret i1 %cmp
121}
122
123define i1 @mul_lshr_cmp_smaller(i8 %x) {
124; CHECK-LABEL: @mul_lshr_cmp_smaller(
125; CHECK-NEXT:    ret i1 true
126;
127  %mul = mul i8 %x, 3
128  %div = lshr i8 %mul, 2
129  %cmp = icmp ule i8 %div, %x
130  ret i1 %cmp
131}
132
133define i1 @mul_lshr_cmp_equal(i8 %x) {
134; CHECK-LABEL: @mul_lshr_cmp_equal(
135; CHECK-NEXT:    ret i1 true
136;
137  %mul = mul i8 %x, 4
138  %div = lshr i8 %mul, 2
139  %cmp = icmp ule i8 %div, %x
140  ret i1 %cmp
141}
142
143define i1 @mul_lshr_cmp_greater(i8 %x) {
144; CHECK-LABEL: @mul_lshr_cmp_greater(
145; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 5
146; CHECK-NEXT:    [[DIV:%.*]] = lshr i8 [[MUL]], 2
147; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[DIV]], [[X]]
148; CHECK-NEXT:    ret i1 [[CMP]]
149;
150  %mul = mul i8 %x, 5
151  %div = lshr i8 %mul, 2
152  %cmp = icmp ule i8 %div, %x
153  ret i1 %cmp
154}
155
156define i1 @shl_div_cmp_smaller(i8 %x) {
157; CHECK-LABEL: @shl_div_cmp_smaller(
158; CHECK-NEXT:    ret i1 true
159;
160  %mul = shl i8 %x, 2
161  %div = udiv i8 %mul, 5
162  %cmp = icmp ule i8 %div, %x
163  ret i1 %cmp
164}
165
166define i1 @shl_div_cmp_equal(i8 %x) {
167; CHECK-LABEL: @shl_div_cmp_equal(
168; CHECK-NEXT:    ret i1 true
169;
170  %mul = shl i8 %x, 2
171  %div = udiv i8 %mul, 4
172  %cmp = icmp ule i8 %div, %x
173  ret i1 %cmp
174}
175
176define i1 @shl_div_cmp_greater(i8 %x) {
177; CHECK-LABEL: @shl_div_cmp_greater(
178; CHECK-NEXT:    [[MUL:%.*]] = shl i8 [[X:%.*]], 2
179; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[MUL]], 3
180; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[DIV]], [[X]]
181; CHECK-NEXT:    ret i1 [[CMP]]
182;
183  %mul = shl i8 %x, 2
184  %div = udiv i8 %mul, 3
185  %cmp = icmp ule i8 %div, %x
186  ret i1 %cmp
187}
188
189; Don't crash matching recurrences/invertible ops.
190
191define void @PR50191(i32 %x) {
192; CHECK-LABEL: @PR50191(
193; CHECK-NEXT:  entry:
194; CHECK-NEXT:    br label [[LOOP:%.*]]
195; CHECK:       loop:
196; CHECK-NEXT:    [[P1:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[SUB1:%.*]], [[LOOP]] ]
197; CHECK-NEXT:    [[P2:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[SUB2:%.*]], [[LOOP]] ]
198; CHECK-NEXT:    [[SUB1]] = sub i32 [[P1]], [[P2]]
199; CHECK-NEXT:    [[SUB2]] = sub i32 42, [[P2]]
200; CHECK-NEXT:    br label [[LOOP]]
201;
202entry:
203  br label %loop
204
205loop:
206  %p1 = phi i32 [ %x, %entry ], [ %sub1, %loop ]
207  %p2 = phi i32 [ %x, %entry ], [ %sub2, %loop ]
208  %cmp = icmp eq i32 %p1, %p2
209  %user = zext i1 %cmp to i32
210  %sub1 = sub i32 %p1, %p2
211  %sub2 = sub i32 42, %p2
212  br label %loop
213}
214
215define i1 @sub_false(i32 %x) {
216; CHECK-LABEL: @sub_false(
217; CHECK-NEXT:    ret i1 false
218;
219  %sub = sub i32 1, %x
220  %cmp = icmp eq i32 %sub, %x
221  ret i1 %cmp
222}
223
224define i1 @sub_swap(i8 %x) {
225; CHECK-LABEL: @sub_swap(
226; CHECK-NEXT:    ret i1 true
227;
228  %sub = sub i8 3, %x
229  %cmp = icmp ne i8 %x, %sub
230  ret i1 %cmp
231}
232
233define <2 x i1> @sub_odd(<2 x i8> %x) {
234; CHECK-LABEL: @sub_odd(
235; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
236;
237  %sub = sub <2 x i8> <i8 3, i8 3>, %x
238  %cmp = icmp ne <2 x i8> %sub, %x
239  ret <2 x i1> %cmp
240}
241
242define <2 x i1> @sub_odd_poison(<2 x i8> %x) {
243; CHECK-LABEL: @sub_odd_poison(
244; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
245;
246  %sub = sub <2 x i8> <i8 poison, i8 1>, %x
247  %cmp = icmp ne <2 x i8> %sub, %x
248  ret <2 x i1> %cmp
249}
250
251define i1 @sub_even(i8 %x) {
252; CHECK-LABEL: @sub_even(
253; CHECK-NEXT:    [[SUB:%.*]] = sub i8 2, [[X:%.*]]
254; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[SUB]], [[X]]
255; CHECK-NEXT:    ret i1 [[CMP]]
256;
257  %sub = sub i8 2, %x
258  %cmp = icmp ne i8 %sub, %x
259  ret i1 %cmp
260}
261
262define i1 @load_ptr(ptr %p) {
263; CHECK-LABEL: @load_ptr(
264; CHECK-NEXT:    ret i1 true
265;
266  %load_p = load ptr, ptr %p, !dereferenceable !{i64 8}
267  %r = icmp ne ptr %load_p, null
268  ret i1 %r
269}
270
271define i1 @load_ptr_null_valid(ptr %p) null_pointer_is_valid {
272; CHECK-LABEL: @load_ptr_null_valid(
273; CHECK-NEXT:    [[LOAD_P:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable [[META0:![0-9]+]]
274; CHECK-NEXT:    [[R:%.*]] = icmp ne ptr [[LOAD_P]], null
275; CHECK-NEXT:    ret i1 [[R]]
276;
277  %load_p = load ptr, ptr %p, !dereferenceable !{i64 8}
278  %r = icmp ne ptr %load_p, null
279  ret i1 %r
280}
281
282define i1 @non_eq_disjoint_or_common_op(i8 %x, i8 %y, i8 %ww, i8 %a) {
283; CHECK-LABEL: @non_eq_disjoint_or_common_op(
284; CHECK-NEXT:    ret i1 false
285;
286  %w = add nuw i8 %ww, 1
287  %z = add i8 %y, %w
288
289  %xy = or disjoint i8 %x, %y
290  %xz = or disjoint i8 %x, %z
291
292  %axy = add i8 %a, %xy
293  %axz = add i8 %a, %xz
294  %r = icmp eq i8 %axy, %axz
295  ret i1 %r
296}
297
298define i1 @non_eq_disjoint_or_common_op_fail(i8 %x, i8 %y, i8 %ww, i8 %a) {
299; CHECK-LABEL: @non_eq_disjoint_or_common_op_fail(
300; CHECK-NEXT:    [[W:%.*]] = add nuw i8 [[WW:%.*]], 1
301; CHECK-NEXT:    [[Z:%.*]] = add i8 [[Y:%.*]], [[W]]
302; CHECK-NEXT:    [[XY:%.*]] = or i8 [[X:%.*]], [[Y]]
303; CHECK-NEXT:    [[XZ:%.*]] = or disjoint i8 [[X]], [[Z]]
304; CHECK-NEXT:    [[AXY:%.*]] = add i8 [[A:%.*]], [[XY]]
305; CHECK-NEXT:    [[AXZ:%.*]] = add i8 [[A]], [[XZ]]
306; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AXY]], [[AXZ]]
307; CHECK-NEXT:    ret i1 [[R]]
308;
309  %w = add nuw i8 %ww, 1
310  %z = add i8 %y, %w
311
312  %xy = or i8 %x, %y
313  %xz = or disjoint i8 %x, %z
314
315  %axy = add i8 %a, %xy
316  %axz = add i8 %a, %xz
317  %r = icmp eq i8 %axy, %axz
318  ret i1 %r
319}
320
321define i1 @non_eq_xor_common_op(i8 %x, i8 %y, i8 %ww, i8 %a) {
322; CHECK-LABEL: @non_eq_xor_common_op(
323; CHECK-NEXT:    ret i1 false
324;
325  %w = add nuw i8 %ww, 1
326  %z = add i8 %y, %w
327
328  %xy = xor i8 %y, %x
329  %xz = xor i8 %x, %z
330
331  %axy = add i8 %a, %xy
332  %axz = add i8 %a, %xz
333  %r = icmp eq i8 %axy, %axz
334  ret i1 %r
335}
336
337define i1 @non_eq_xor_common_op_fail(i8 %x, i8 %y, i8 %ww, i8 %a) {
338; CHECK-LABEL: @non_eq_xor_common_op_fail(
339; CHECK-NEXT:    [[W:%.*]] = add nsw i8 [[WW:%.*]], 1
340; CHECK-NEXT:    [[Z:%.*]] = add i8 [[Y:%.*]], [[W]]
341; CHECK-NEXT:    [[XY:%.*]] = xor i8 [[Y]], [[X:%.*]]
342; CHECK-NEXT:    [[XZ:%.*]] = xor i8 [[X]], [[Z]]
343; CHECK-NEXT:    [[AXY:%.*]] = add i8 [[A:%.*]], [[XY]]
344; CHECK-NEXT:    [[AXZ:%.*]] = add i8 [[A]], [[XZ]]
345; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AXY]], [[AXZ]]
346; CHECK-NEXT:    ret i1 [[R]]
347;
348  %w = add nsw i8 %ww, 1
349  %z = add i8 %y, %w
350
351  %xy = xor i8 %y, %x
352  %xz = xor i8 %x, %z
353
354  %axy = add i8 %a, %xy
355  %axz = add i8 %a, %xz
356  %r = icmp eq i8 %axy, %axz
357  ret i1 %r
358}
359
360define i1 @non_eq_disjoint_or(i8 %x, i8 %yy, i8 %w) {
361; CHECK-LABEL: @non_eq_disjoint_or(
362; CHECK-NEXT:    ret i1 false
363;
364  %y = add nuw i8 %yy, 1
365  %lhs = add i8 %x, %w
366  %val = or disjoint i8 %y, %w
367  %rhs = add i8 %x, %val
368  %r = icmp eq i8 %lhs, %rhs
369  ret i1 %r
370}
371
372define i1 @non_eq_or_fail(i8 %x, i8 %yy, i8 %w) {
373; CHECK-LABEL: @non_eq_or_fail(
374; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
375; CHECK-NEXT:    [[LHS:%.*]] = add i8 [[X:%.*]], [[W:%.*]]
376; CHECK-NEXT:    [[VAL:%.*]] = or i8 [[Y]], [[W]]
377; CHECK-NEXT:    [[RHS:%.*]] = add i8 [[X]], [[VAL]]
378; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[LHS]], [[RHS]]
379; CHECK-NEXT:    ret i1 [[R]]
380;
381  %y = add nuw i8 %yy, 1
382  %lhs = add i8 %x, %w
383  %val = or i8 %y, %w
384  %rhs = add i8 %x, %val
385  %r = icmp eq i8 %lhs, %rhs
386  ret i1 %r
387}
388
389define i1 @non_eq_xor(i8 %x, i8 %yy, i8 %w) {
390; CHECK-LABEL: @non_eq_xor(
391; CHECK-NEXT:    ret i1 false
392;
393  %y = add nuw i8 %yy, 1
394  %lhs = add i8 %x, %w
395  %val = xor i8 %y, %w
396  %rhs = add i8 %x, %val
397  %r = icmp eq i8 %lhs, %rhs
398  ret i1 %r
399}
400
401define i1 @non_eq_xor_fail(i8 %x, i8 %yy, i8 %w) {
402; CHECK-LABEL: @non_eq_xor_fail(
403; CHECK-NEXT:    [[Y:%.*]] = add nsw i8 [[YY:%.*]], 1
404; CHECK-NEXT:    [[LHS:%.*]] = add i8 [[X:%.*]], [[W:%.*]]
405; CHECK-NEXT:    [[VAL:%.*]] = xor i8 [[Y]], [[W]]
406; CHECK-NEXT:    [[RHS:%.*]] = add i8 [[X]], [[VAL]]
407; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[LHS]], [[RHS]]
408; CHECK-NEXT:    ret i1 [[R]]
409;
410  %y = add nsw i8 %yy, 1
411  %lhs = add i8 %x, %w
412  %val = xor i8 %y, %w
413  %rhs = add i8 %x, %val
414  %r = icmp eq i8 %lhs, %rhs
415  ret i1 %r
416}
417