xref: /llvm-project/llvm/test/Transforms/InstSimplify/and-or-icmp-zero.ll (revision 4ea883cbbbddc6374f1d54619fb6c8f5aea8bcdc)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3
4; In the next 16 tests (4 commutes * 2 (and/or) * 2 optional ptrtoint casts),
5; eliminate the simple (not) null check because that compare is implied by the
6; masked compare of the same operand.
7; Vary types between scalar and vector and weird for extra coverage.
8
9; or (icmp eq (and X, ?), 0), (icmp eq X, 0) --> icmp eq (and X, ?), 0
10
11define i1 @or_cmps_eq_zero_with_mask_commute1(i64 %x, i64 %y) {
12; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute1(
13; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i64 [[X:%.*]], [[Y:%.*]]
14; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i64 [[SOMEBITS]], 0
15; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_ZERO]]
16;
17  %isnull = icmp eq i64 %x, 0
18  %somebits = and i64 %x, %y
19  %somebits_are_zero = icmp eq i64 %somebits, 0
20  %r = or i1 %somebits_are_zero, %isnull
21  ret i1 %r
22}
23
24; or (icmp eq X, 0), (icmp eq (and X, ?), 0) --> icmp eq (and X, ?), 0
25
26define <2 x i1> @or_cmps_eq_zero_with_mask_commute2(<2 x i64> %x, <2 x i64> %y) {
27; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute2(
28; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <2 x i64> [[X:%.*]], [[Y:%.*]]
29; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i64> [[SOMEBITS]], zeroinitializer
30; CHECK-NEXT:    ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
31;
32  %isnull = icmp eq <2 x i64> %x, zeroinitializer
33  %somebits = and <2 x i64> %x, %y
34  %somebits_are_zero = icmp eq <2 x i64> %somebits, zeroinitializer
35  %r = or <2 x i1> %isnull, %somebits_are_zero
36  ret <2 x i1> %r
37}
38
39; or (icmp eq (and ?, X), 0), (icmp eq X, 0) --> icmp eq (and ?, X), 0
40
41define i1 @or_cmps_eq_zero_with_mask_commute3(i4 %x, i4 %y) {
42; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute3(
43; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i4 [[Y:%.*]], [[X:%.*]]
44; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i4 [[SOMEBITS]], 0
45; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_ZERO]]
46;
47  %isnull = icmp eq i4 %x, 0
48  %somebits = and i4 %y, %x
49  %somebits_are_zero = icmp eq i4 %somebits, 0
50  %r = or i1 %somebits_are_zero, %isnull
51  ret i1 %r
52}
53
54; or (icmp eq X, 0), (icmp eq (and ?, X), 0) --> icmp eq (and ?, X), 0
55
56define <2 x i1> @or_cmps_eq_zero_with_mask_commute4(<2 x i4> %x, <2 x i4> %y) {
57; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute4(
58; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <2 x i4> [[Y:%.*]], [[X:%.*]]
59; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[SOMEBITS]], zeroinitializer
60; CHECK-NEXT:    ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
61;
62  %isnull = icmp eq <2 x i4> %x, zeroinitializer
63  %somebits = and <2 x i4> %y, %x
64  %somebits_are_zero = icmp eq <2 x i4> %somebits, zeroinitializer
65  %r = or <2 x i1> %isnull, %somebits_are_zero
66  ret <2 x i1> %r
67}
68
69; and (icmp ne (and X, ?), 0), (icmp ne X, 0) --> icmp ne (and X, ?), 0
70
71define <3 x i1> @and_cmps_eq_zero_with_mask_commute1(<3 x i4> %x, <3 x i4> %y) {
72; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute1(
73; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <3 x i4> [[X:%.*]], [[Y:%.*]]
74; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i4> [[SOMEBITS]], zeroinitializer
75; CHECK-NEXT:    ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
76;
77  %isnotnull = icmp ne <3 x i4> %x, zeroinitializer
78  %somebits = and <3 x i4> %x, %y
79  %somebits_are_not_zero = icmp ne <3 x i4> %somebits, zeroinitializer
80  %r = and <3 x i1> %somebits_are_not_zero, %isnotnull
81  ret <3 x i1> %r
82}
83
84; and (icmp ne X, 0), (icmp ne (and X, ?), 0) --> icmp ne (and X, ?), 0
85
86define i1 @and_cmps_eq_zero_with_mask_commute2(i4 %x, i4 %y) {
87; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute2(
88; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i4 [[X:%.*]], [[Y:%.*]]
89; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i4 [[SOMEBITS]], 0
90; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
91;
92  %isnotnull = icmp ne i4 %x, 0
93  %somebits = and i4 %x, %y
94  %somebits_are_not_zero = icmp ne i4 %somebits, 0
95  %r = and i1 %isnotnull, %somebits_are_not_zero
96  ret i1 %r
97}
98
99; and (icmp ne (and ?, X), 0), (icmp ne X, 0) --> icmp ne (and ?, X), 0
100
101define <3 x i1> @and_cmps_eq_zero_with_mask_commute3(<3 x i64> %x, <3 x i64> %y) {
102; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute3(
103; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <3 x i64> [[Y:%.*]], [[X:%.*]]
104; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i64> [[SOMEBITS]], zeroinitializer
105; CHECK-NEXT:    ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
106;
107  %isnotnull = icmp ne <3 x i64> %x, zeroinitializer
108  %somebits = and <3 x i64> %y, %x
109  %somebits_are_not_zero = icmp ne <3 x i64> %somebits, zeroinitializer
110  %r = and <3 x i1> %somebits_are_not_zero, %isnotnull
111  ret <3 x i1> %r
112}
113
114; and (icmp ne X, 0), (icmp ne (and ?, X), 0) --> icmp ne (and ?, X), 0
115
116define i1 @and_cmps_eq_zero_with_mask_commute4(i64 %x, i64 %y) {
117; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute4(
118; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i64 [[Y:%.*]], [[X:%.*]]
119; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i64 [[SOMEBITS]], 0
120; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
121;
122  %isnotnull = icmp ne i64 %x, 0
123  %somebits = and i64 %y, %x
124  %somebits_are_not_zero = icmp ne i64 %somebits, 0
125  %r = and i1 %isnotnull, %somebits_are_not_zero
126  ret i1 %r
127}
128
129; or (icmp eq (and (ptrtoint P), ?), 0), (icmp eq P, 0) --> icmp eq (and (ptrtoint P), ?), 0
130
131define i1 @or_cmps_ptr_eq_zero_with_mask_commute1(ptr %p, i64 %y) {
132; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute1(
133; CHECK-NEXT:    [[X:%.*]] = ptrtoint ptr [[P:%.*]] to i64
134; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i64 [[X]], [[Y:%.*]]
135; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i64 [[SOMEBITS]], 0
136; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_ZERO]]
137;
138  %isnull = icmp eq ptr %p, null
139  %x = ptrtoint ptr %p to i64
140  %somebits = and i64 %x, %y
141  %somebits_are_zero = icmp eq i64 %somebits, 0
142  %r = or i1 %somebits_are_zero, %isnull
143  ret i1 %r
144}
145
146; or (icmp eq P, 0), (icmp eq (and (ptrtoint P), ?), 0) --> icmp eq (and (ptrtoint P), ?), 0
147
148define <2 x i1> @or_cmps_ptr_eq_zero_with_mask_commute2(<2 x ptr> %p, <2 x i64> %y) {
149; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute2(
150; CHECK-NEXT:    [[X:%.*]] = ptrtoint <2 x ptr> [[P:%.*]] to <2 x i64>
151; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <2 x i64> [[X]], [[Y:%.*]]
152; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i64> [[SOMEBITS]], zeroinitializer
153; CHECK-NEXT:    ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
154;
155  %isnull = icmp eq <2 x ptr> %p, zeroinitializer
156  %x = ptrtoint <2 x ptr> %p to <2 x i64>
157  %somebits = and <2 x i64> %x, %y
158  %somebits_are_zero = icmp eq <2 x i64> %somebits, zeroinitializer
159  %r = or <2 x i1> %isnull, %somebits_are_zero
160  ret <2 x i1> %r
161}
162
163; or (icmp eq (and ?, (ptrtoint P)), 0), (icmp eq P, 0) --> icmp eq (and ?, (ptrtoint P)), 0
164
165define i1 @or_cmps_ptr_eq_zero_with_mask_commute3(ptr %p, i4 %y) {
166; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute3(
167; CHECK-NEXT:    [[X:%.*]] = ptrtoint ptr [[P:%.*]] to i4
168; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i4 [[Y:%.*]], [[X]]
169; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i4 [[SOMEBITS]], 0
170; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_ZERO]]
171;
172  %isnull = icmp eq ptr %p, null
173  %x = ptrtoint ptr %p to i4
174  %somebits = and i4 %y, %x
175  %somebits_are_zero = icmp eq i4 %somebits, 0
176  %r = or i1 %somebits_are_zero, %isnull
177  ret i1 %r
178}
179
180; or (icmp eq P, 0), (icmp eq (and ?, (ptrtoint P)), 0) --> icmp eq (and ?, (ptrtoint P)), 0
181
182define <2 x i1> @or_cmps_ptr_eq_zero_with_mask_commute4(<2 x ptr> %p, <2 x i4> %y) {
183; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute4(
184; CHECK-NEXT:    [[X:%.*]] = ptrtoint <2 x ptr> [[P:%.*]] to <2 x i4>
185; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <2 x i4> [[Y:%.*]], [[X]]
186; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[SOMEBITS]], zeroinitializer
187; CHECK-NEXT:    ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
188;
189  %isnull = icmp eq <2 x ptr> %p, zeroinitializer
190  %x = ptrtoint <2 x ptr> %p to <2 x i4>
191  %somebits = and <2 x i4> %y, %x
192  %somebits_are_zero = icmp eq <2 x i4> %somebits, zeroinitializer
193  %r = or <2 x i1> %isnull, %somebits_are_zero
194  ret <2 x i1> %r
195}
196
197; and (icmp ne (and (ptrtoint P), ?), 0), (icmp ne P, 0) --> icmp ne (and (ptrtoint P), ?), 0
198
199define <3 x i1> @and_cmps_ptr_eq_zero_with_mask_commute1(<3 x ptr> %p, <3 x i4> %y) {
200; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute1(
201; CHECK-NEXT:    [[X:%.*]] = ptrtoint <3 x ptr> [[P:%.*]] to <3 x i4>
202; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <3 x i4> [[X]], [[Y:%.*]]
203; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i4> [[SOMEBITS]], zeroinitializer
204; CHECK-NEXT:    ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
205;
206  %isnotnull = icmp ne <3 x ptr> %p, zeroinitializer
207  %x = ptrtoint <3 x ptr> %p to <3 x i4>
208  %somebits = and <3 x i4> %x, %y
209  %somebits_are_not_zero = icmp ne <3 x i4> %somebits, zeroinitializer
210  %r = and <3 x i1> %somebits_are_not_zero, %isnotnull
211  ret <3 x i1> %r
212}
213
214; and (icmp ne P, 0), (icmp ne (and (ptrtoint P), ?), 0) --> icmp ne (and (ptrtoint P), ?), 0
215
216define i1 @and_cmps_ptr_eq_zero_with_mask_commute2(ptr %p, i4 %y) {
217; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute2(
218; CHECK-NEXT:    [[X:%.*]] = ptrtoint ptr [[P:%.*]] to i4
219; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i4 [[X]], [[Y:%.*]]
220; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i4 [[SOMEBITS]], 0
221; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
222;
223  %isnotnull = icmp ne ptr %p, null
224  %x = ptrtoint ptr %p to i4
225  %somebits = and i4 %x, %y
226  %somebits_are_not_zero = icmp ne i4 %somebits, 0
227  %r = and i1 %isnotnull, %somebits_are_not_zero
228  ret i1 %r
229}
230
231; and (icmp ne (and ?, (ptrtoint P)), 0), (icmp ne P, 0) --> icmp ne (and ?, (ptrtoint P)), 0
232
233define <3 x i1> @and_cmps_ptr_eq_zero_with_mask_commute3(<3 x ptr> %p, <3 x i64> %y) {
234; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute3(
235; CHECK-NEXT:    [[X:%.*]] = ptrtoint <3 x ptr> [[P:%.*]] to <3 x i64>
236; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <3 x i64> [[Y:%.*]], [[X]]
237; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i64> [[SOMEBITS]], zeroinitializer
238; CHECK-NEXT:    ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
239;
240  %isnotnull = icmp ne <3 x ptr> %p, zeroinitializer
241  %x = ptrtoint <3 x ptr> %p to <3 x i64>
242  %somebits = and <3 x i64> %y, %x
243  %somebits_are_not_zero = icmp ne <3 x i64> %somebits, zeroinitializer
244  %r = and <3 x i1> %somebits_are_not_zero, %isnotnull
245  ret <3 x i1> %r
246}
247
248; and (icmp ne P, 0), (icmp ne (and ?, (ptrtoint P)), 0) --> icmp ne (and ?, (ptrtoint P)), 0
249
250define i1 @and_cmps_ptr_eq_zero_with_mask_commute4(ptr %p, i64 %y) {
251; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute4(
252; CHECK-NEXT:    [[X:%.*]] = ptrtoint ptr [[P:%.*]] to i64
253; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i64 [[Y:%.*]], [[X]]
254; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i64 [[SOMEBITS]], 0
255; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
256;
257  %isnotnull = icmp ne ptr %p, null
258  %x = ptrtoint ptr %p to i64
259  %somebits = and i64 %y, %x
260  %somebits_are_not_zero = icmp ne i64 %somebits, 0
261  %r = and i1 %isnotnull, %somebits_are_not_zero
262  ret i1 %r
263}
264