1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
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.
9 ; or (icmp eq (and X, ?), 0), (icmp eq X, 0) --> icmp eq (and X, ?), 0
11 define 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]]
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
24 ; or (icmp eq X, 0), (icmp eq (and X, ?), 0) --> icmp eq (and X, ?), 0
26 define <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]]
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
39 ; or (icmp eq (and ?, X), 0), (icmp eq X, 0) --> icmp eq (and ?, X), 0
41 define 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]]
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
54 ; or (icmp eq X, 0), (icmp eq (and ?, X), 0) --> icmp eq (and ?, X), 0
56 define <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]]
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
69 ; and (icmp ne (and X, ?), 0), (icmp ne X, 0) --> icmp ne (and X, ?), 0
71 define <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]]
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
84 ; and (icmp ne X, 0), (icmp ne (and X, ?), 0) --> icmp ne (and X, ?), 0
86 define 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]]
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
99 ; and (icmp ne (and ?, X), 0), (icmp ne X, 0) --> icmp ne (and ?, X), 0
101 define <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]]
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
114 ; and (icmp ne X, 0), (icmp ne (and ?, X), 0) --> icmp ne (and ?, X), 0
116 define 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]]
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
129 ; or (icmp eq (and (ptrtoint P), ?), 0), (icmp eq P, 0) --> icmp eq (and (ptrtoint P), ?), 0
131 define 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]]
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
146 ; or (icmp eq P, 0), (icmp eq (and (ptrtoint P), ?), 0) --> icmp eq (and (ptrtoint P), ?), 0
148 define <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]]
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
163 ; or (icmp eq (and ?, (ptrtoint P)), 0), (icmp eq P, 0) --> icmp eq (and ?, (ptrtoint P)), 0
165 define 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]]
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
180 ; or (icmp eq P, 0), (icmp eq (and ?, (ptrtoint P)), 0) --> icmp eq (and ?, (ptrtoint P)), 0
182 define <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]]
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
197 ; and (icmp ne (and (ptrtoint P), ?), 0), (icmp ne P, 0) --> icmp ne (and (ptrtoint P), ?), 0
199 define <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]]
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
214 ; and (icmp ne P, 0), (icmp ne (and (ptrtoint P), ?), 0) --> icmp ne (and (ptrtoint P), ?), 0
216 define 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]]
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
231 ; and (icmp ne (and ?, (ptrtoint P)), 0), (icmp ne P, 0) --> icmp ne (and ?, (ptrtoint P)), 0
233 define <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]]
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
248 ; and (icmp ne P, 0), (icmp ne (and ?, (ptrtoint P)), 0) --> icmp ne (and ?, (ptrtoint P)), 0
250 define 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]]
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