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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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