Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / InstSimplify / and-or-icmp-zero.ll
blobd4e0d776391aebc273133da598e203a66f36e352
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
21   ret i1 %r
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
36   ret <2 x i1> %r
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
51   ret i1 %r
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
66   ret <2 x i1> %r
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
81   ret <3 x i1> %r
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
96   ret i1 %r
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
111   ret <3 x i1> %r
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
126   ret i1 %r
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
143   ret i1 %r
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
160   ret <2 x i1> %r
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
177   ret i1 %r
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
194   ret <2 x i1> %r
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
211   ret <3 x i1> %r
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
228   ret i1 %r
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
245   ret <3 x i1> %r
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
262   ret i1 %r