[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstSimplify / and-or-icmp-zero.ll
blob04bf5ace36a33b2675020ebeb4de1ad47956b74a
1 ; RUN: opt < %s -instsimplify -S | FileCheck %s
3 ; In the next 16 tests (4 commutes * 2 (and/or) * 2 optional ptrtoint casts),
4 ; eliminate the simple (not) null check because that compare is implied by the
5 ; masked compare of the same operand.
6 ; Vary types between scalar and vector and weird for extra coverage.
8 ; or (icmp eq (and X, ?), 0), (icmp eq X, 0) --> icmp eq (and X, ?), 0
10 define i1 @or_cmps_eq_zero_with_mask_commute1(i64 %x, i64 %y) {
11 ; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute1(
12 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i64 %x, %y
13 ; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i64 [[SOMEBITS]], 0
14 ; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_ZERO]]
16   %isnull = icmp eq i64 %x, 0
17   %somebits = and i64 %x, %y
18   %somebits_are_zero = icmp eq i64 %somebits, 0
19   %r = or i1 %somebits_are_zero, %isnull
20   ret i1 %r
23 ; or (icmp eq X, 0), (icmp eq (and X, ?), 0) --> icmp eq (and X, ?), 0
25 define <2 x i1> @or_cmps_eq_zero_with_mask_commute2(<2 x i64> %x, <2 x i64> %y) {
26 ; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute2(
27 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <2 x i64> %x, %y
28 ; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i64> [[SOMEBITS]], zeroinitializer
29 ; CHECK-NEXT:    ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
31   %isnull = icmp eq <2 x i64> %x, zeroinitializer
32   %somebits = and <2 x i64> %x, %y
33   %somebits_are_zero = icmp eq <2 x i64> %somebits, zeroinitializer
34   %r = or <2 x i1> %isnull, %somebits_are_zero
35   ret <2 x i1> %r
38 ; or (icmp eq (and ?, X), 0), (icmp eq X, 0) --> icmp eq (and ?, X), 0
40 define i1 @or_cmps_eq_zero_with_mask_commute3(i4 %x, i4 %y) {
41 ; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute3(
42 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i4 %y, %x
43 ; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i4 [[SOMEBITS]], 0
44 ; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_ZERO]]
46   %isnull = icmp eq i4 %x, 0
47   %somebits = and i4 %y, %x
48   %somebits_are_zero = icmp eq i4 %somebits, 0
49   %r = or i1 %somebits_are_zero, %isnull
50   ret i1 %r
53 ; or (icmp eq X, 0), (icmp eq (and ?, X), 0) --> icmp eq (and ?, X), 0
55 define <2 x i1> @or_cmps_eq_zero_with_mask_commute4(<2 x i4> %x, <2 x i4> %y) {
56 ; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute4(
57 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <2 x i4> %y, %x
58 ; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[SOMEBITS]], zeroinitializer
59 ; CHECK-NEXT:    ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
61   %isnull = icmp eq <2 x i4> %x, zeroinitializer
62   %somebits = and <2 x i4> %y, %x
63   %somebits_are_zero = icmp eq <2 x i4> %somebits, zeroinitializer
64   %r = or <2 x i1> %isnull, %somebits_are_zero
65   ret <2 x i1> %r
68 ; and (icmp ne (and X, ?), 0), (icmp ne X, 0) --> icmp ne (and X, ?), 0
70 define <3 x i1> @and_cmps_eq_zero_with_mask_commute1(<3 x i4> %x, <3 x i4> %y) {
71 ; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute1(
72 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <3 x i4> %x, %y
73 ; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i4> [[SOMEBITS]], zeroinitializer
74 ; CHECK-NEXT:    ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
76   %isnotnull = icmp ne <3 x i4> %x, zeroinitializer
77   %somebits = and <3 x i4> %x, %y
78   %somebits_are_not_zero = icmp ne <3 x i4> %somebits, zeroinitializer
79   %r = and <3 x i1> %somebits_are_not_zero, %isnotnull
80   ret <3 x i1> %r
83 ; and (icmp ne X, 0), (icmp ne (and X, ?), 0) --> icmp ne (and X, ?), 0
85 define i1 @and_cmps_eq_zero_with_mask_commute2(i4 %x, i4 %y) {
86 ; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute2(
87 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i4 %x, %y
88 ; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i4 [[SOMEBITS]], 0
89 ; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
91   %isnotnull = icmp ne i4 %x, 0
92   %somebits = and i4 %x, %y
93   %somebits_are_not_zero = icmp ne i4 %somebits, 0
94   %r = and i1 %isnotnull, %somebits_are_not_zero
95   ret i1 %r
98 ; and (icmp ne (and ?, X), 0), (icmp ne X, 0) --> icmp ne (and ?, X), 0
100 define <3 x i1> @and_cmps_eq_zero_with_mask_commute3(<3 x i64> %x, <3 x i64> %y) {
101 ; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute3(
102 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <3 x i64> %y, %x
103 ; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i64> [[SOMEBITS]], zeroinitializer
104 ; CHECK-NEXT:    ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
106   %isnotnull = icmp ne <3 x i64> %x, zeroinitializer
107   %somebits = and <3 x i64> %y, %x
108   %somebits_are_not_zero = icmp ne <3 x i64> %somebits, zeroinitializer
109   %r = and <3 x i1> %somebits_are_not_zero, %isnotnull
110   ret <3 x i1> %r
113 ; and (icmp ne X, 0), (icmp ne (and ?, X), 0) --> icmp ne (and ?, X), 0
115 define i1 @and_cmps_eq_zero_with_mask_commute4(i64 %x, i64 %y) {
116 ; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute4(
117 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i64 %y, %x
118 ; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i64 [[SOMEBITS]], 0
119 ; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
121   %isnotnull = icmp ne i64 %x, 0
122   %somebits = and i64 %y, %x
123   %somebits_are_not_zero = icmp ne i64 %somebits, 0
124   %r = and i1 %isnotnull, %somebits_are_not_zero
125   ret i1 %r
128 ; or (icmp eq (and (ptrtoint P), ?), 0), (icmp eq P, 0) --> icmp eq (and (ptrtoint P), ?), 0
130 define i1 @or_cmps_ptr_eq_zero_with_mask_commute1(i64* %p, i64 %y) {
131 ; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute1(
132 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint i64* %p to i64
133 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i64 [[X]], %y
134 ; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i64 [[SOMEBITS]], 0
135 ; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_ZERO]]
137   %isnull = icmp eq i64* %p, null
138   %x = ptrtoint i64* %p to i64
139   %somebits = and i64 %x, %y
140   %somebits_are_zero = icmp eq i64 %somebits, 0
141   %r = or i1 %somebits_are_zero, %isnull
142   ret i1 %r
145 ; or (icmp eq P, 0), (icmp eq (and (ptrtoint P), ?), 0) --> icmp eq (and (ptrtoint P), ?), 0
147 define <2 x i1> @or_cmps_ptr_eq_zero_with_mask_commute2(<2 x i64*> %p, <2 x i64> %y) {
148 ; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute2(
149 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint <2 x i64*> %p to <2 x i64>
150 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <2 x i64> [[X]], %y
151 ; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i64> [[SOMEBITS]], zeroinitializer
152 ; CHECK-NEXT:    ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
154   %isnull = icmp eq <2 x i64*> %p, zeroinitializer
155   %x = ptrtoint <2 x i64*> %p to <2 x i64>
156   %somebits = and <2 x i64> %x, %y
157   %somebits_are_zero = icmp eq <2 x i64> %somebits, zeroinitializer
158   %r = or <2 x i1> %isnull, %somebits_are_zero
159   ret <2 x i1> %r
162 ; or (icmp eq (and ?, (ptrtoint P)), 0), (icmp eq P, 0) --> icmp eq (and ?, (ptrtoint P)), 0
164 define i1 @or_cmps_ptr_eq_zero_with_mask_commute3(i4* %p, i4 %y) {
165 ; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute3(
166 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint i4* %p to i4
167 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i4 %y, [[X]]
168 ; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i4 [[SOMEBITS]], 0
169 ; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_ZERO]]
171   %isnull = icmp eq i4* %p, null
172   %x = ptrtoint i4* %p to i4
173   %somebits = and i4 %y, %x
174   %somebits_are_zero = icmp eq i4 %somebits, 0
175   %r = or i1 %somebits_are_zero, %isnull
176   ret i1 %r
179 ; or (icmp eq P, 0), (icmp eq (and ?, (ptrtoint P)), 0) --> icmp eq (and ?, (ptrtoint P)), 0
181 define <2 x i1> @or_cmps_ptr_eq_zero_with_mask_commute4(<2 x i4*> %p, <2 x i4> %y) {
182 ; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute4(
183 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint <2 x i4*> %p to <2 x i4>
184 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <2 x i4> %y, [[X]]
185 ; CHECK-NEXT:    [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[SOMEBITS]], zeroinitializer
186 ; CHECK-NEXT:    ret <2 x i1> [[SOMEBITS_ARE_ZERO]]
188   %isnull = icmp eq <2 x i4*> %p, zeroinitializer
189   %x = ptrtoint <2 x i4*> %p to <2 x i4>
190   %somebits = and <2 x i4> %y, %x
191   %somebits_are_zero = icmp eq <2 x i4> %somebits, zeroinitializer
192   %r = or <2 x i1> %isnull, %somebits_are_zero
193   ret <2 x i1> %r
196 ; and (icmp ne (and (ptrtoint P), ?), 0), (icmp ne P, 0) --> icmp ne (and (ptrtoint P), ?), 0
198 define <3 x i1> @and_cmps_ptr_eq_zero_with_mask_commute1(<3 x i4*> %p, <3 x i4> %y) {
199 ; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute1(
200 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint <3 x i4*> %p to <3 x i4>
201 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <3 x i4> [[X]], %y
202 ; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i4> [[SOMEBITS]], zeroinitializer
203 ; CHECK-NEXT:    ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
205   %isnotnull = icmp ne <3 x i4*> %p, zeroinitializer
206   %x = ptrtoint <3 x i4*> %p to <3 x i4>
207   %somebits = and <3 x i4> %x, %y
208   %somebits_are_not_zero = icmp ne <3 x i4> %somebits, zeroinitializer
209   %r = and <3 x i1> %somebits_are_not_zero, %isnotnull
210   ret <3 x i1> %r
213 ; and (icmp ne P, 0), (icmp ne (and (ptrtoint P), ?), 0) --> icmp ne (and (ptrtoint P), ?), 0
215 define i1 @and_cmps_ptr_eq_zero_with_mask_commute2(i4* %p, i4 %y) {
216 ; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute2(
217 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint i4* %p to i4
218 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i4 [[X]], %y
219 ; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i4 [[SOMEBITS]], 0
220 ; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
222   %isnotnull = icmp ne i4* %p, null
223   %x = ptrtoint i4* %p to i4
224   %somebits = and i4 %x, %y
225   %somebits_are_not_zero = icmp ne i4 %somebits, 0
226   %r = and i1 %isnotnull, %somebits_are_not_zero
227   ret i1 %r
230 ; and (icmp ne (and ?, (ptrtoint P)), 0), (icmp ne P, 0) --> icmp ne (and ?, (ptrtoint P)), 0
232 define <3 x i1> @and_cmps_ptr_eq_zero_with_mask_commute3(<3 x i64*> %p, <3 x i64> %y) {
233 ; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute3(
234 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint <3 x i64*> %p to <3 x i64>
235 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and <3 x i64> %y, [[X]]
236 ; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i64> [[SOMEBITS]], zeroinitializer
237 ; CHECK-NEXT:    ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]]
239   %isnotnull = icmp ne <3 x i64*> %p, zeroinitializer
240   %x = ptrtoint <3 x i64*> %p to <3 x i64>
241   %somebits = and <3 x i64> %y, %x
242   %somebits_are_not_zero = icmp ne <3 x i64> %somebits, zeroinitializer
243   %r = and <3 x i1> %somebits_are_not_zero, %isnotnull
244   ret <3 x i1> %r
247 ; and (icmp ne P, 0), (icmp ne (and ?, (ptrtoint P)), 0) --> icmp ne (and ?, (ptrtoint P)), 0
249 define i1 @and_cmps_ptr_eq_zero_with_mask_commute4(i64* %p, i64 %y) {
250 ; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute4(
251 ; CHECK-NEXT:    [[X:%.*]] = ptrtoint i64* %p to i64
252 ; CHECK-NEXT:    [[SOMEBITS:%.*]] = and i64 %y, [[X]]
253 ; CHECK-NEXT:    [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i64 [[SOMEBITS]], 0
254 ; CHECK-NEXT:    ret i1 [[SOMEBITS_ARE_NOT_ZERO]]
256   %isnotnull = icmp ne i64* %p, null
257   %x = ptrtoint i64* %p to i64
258   %somebits = and i64 %y, %x
259   %somebits_are_not_zero = icmp ne i64 %somebits, 0
260   %r = and i1 %isnotnull, %somebits_are_not_zero
261   ret i1 %r