1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -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(i8* %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 i8*> %ptr1vec, i8* %ptr2) {
10; CHECK-LABEL: @bitcast_from_single_element_pointer_vector_to_pointer(
11; CHECK-NEXT:    [[PTR1:%.*]] = bitcast <1 x i8*> [[PTR1VEC:%.*]] to i8*
12; CHECK-NEXT:    call void @usei8ptr(i8* [[PTR1]])
13; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8* [[PTR1]], [[PTR2:%.*]]
14; CHECK-NEXT:    ret i1 [[CMP]]
15;
16  %ptr1 = bitcast <1 x i8*> %ptr1vec to i8*
17  call void @usei8ptr(i8* %ptr1)
18  %cmp = icmp eq i8* %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