[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-of-and-x.ll
blob0bcbc3bcb050b00bd0aef5bfa58cfc9618ddc172
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare i1 @barrier()
5 declare void @llvm.assume(i1)
6 declare void @use.i8(i8)
8 define i1 @icmp_ult_x_y(i8 %x, i8 %y) {
9 ; CHECK-LABEL: @icmp_ult_x_y(
10 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
11 ; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[AND]], [[X]]
12 ; CHECK-NEXT:    ret i1 [[Z]]
14   %and = and i8 %x, %y
15   %z = icmp ult i8 %and, %x
16   ret i1 %z
19 define i1 @icmp_ult_x_y_2(i8 %xx, i8 %y) {
20 ; CHECK-LABEL: @icmp_ult_x_y_2(
21 ; CHECK-NEXT:    [[X:%.*]] = mul i8 [[XX:%.*]], [[XX]]
22 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y:%.*]]
23 ; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[AND]], [[X]]
24 ; CHECK-NEXT:    ret i1 [[Z]]
26   %x = mul i8 %xx, %xx
27   %and = and i8 %x, %y
28   %z = icmp ugt i8 %x, %and
29   ret i1 %z
32 define <2 x i1> @icmp_uge_x_y(<2 x i8> %x, <2 x i8> %y) {
33 ; CHECK-LABEL: @icmp_uge_x_y(
34 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
35 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq <2 x i8> [[AND]], [[X]]
36 ; CHECK-NEXT:    ret <2 x i1> [[Z]]
38   %and = and <2 x i8> %x, %y
39   %z = icmp uge <2 x i8> %and, %x
40   ret <2 x i1> %z
43 define i1 @icmp_uge_x_y_2(i8 %xx, i8 %y) {
44 ; CHECK-LABEL: @icmp_uge_x_y_2(
45 ; CHECK-NEXT:    [[X:%.*]] = mul i8 [[XX:%.*]], [[XX]]
46 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y:%.*]]
47 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq i8 [[AND]], [[X]]
48 ; CHECK-NEXT:    ret i1 [[Z]]
50   %x = mul i8 %xx, %xx
51   %and = and i8 %x, %y
52   %z = icmp ule i8 %x, %and
53   ret i1 %z
56 define i1 @icmp_sge_x_negy(i8 %x, i8 %y) {
57 ; CHECK-LABEL: @icmp_sge_x_negy(
58 ; CHECK-NEXT:    [[CY:%.*]] = icmp slt i8 [[Y:%.*]], 0
59 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CY]])
60 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y]]
61 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq i8 [[AND]], [[X]]
62 ; CHECK-NEXT:    ret i1 [[Z]]
64   %cy = icmp slt i8 %y, 0
65   call void @llvm.assume(i1 %cy)
66   %and = and i8 %x, %y
67   %z = icmp sge i8 %and, %x
68   ret i1 %z
71 define i1 @icmp_slt_x_negy(i8 %x, i8 %y) {
72 ; CHECK-LABEL: @icmp_slt_x_negy(
73 ; CHECK-NEXT:    [[CY:%.*]] = icmp slt i8 [[Y:%.*]], 0
74 ; CHECK-NEXT:    br i1 [[CY]], label [[NEGY:%.*]], label [[POSY:%.*]]
75 ; CHECK:       negy:
76 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y]]
77 ; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[AND]], [[X]]
78 ; CHECK-NEXT:    ret i1 [[Z]]
79 ; CHECK:       posy:
80 ; CHECK-NEXT:    [[R:%.*]] = call i1 @barrier()
81 ; CHECK-NEXT:    ret i1 [[R]]
83   %cy = icmp slt i8 %y, 0
84   br i1 %cy, label %negy, label %posy
85 negy:
86   %and = and i8 %x, %y
87   %z = icmp slt i8 %and, %x
88   ret i1 %z
89 posy:
90   %r = call i1 @barrier()
91   ret i1 %r
94 define i1 @icmp_slt_x_negy_fail_maybe_zero(i8 %x, i8 %y) {
95 ; CHECK-LABEL: @icmp_slt_x_negy_fail_maybe_zero(
96 ; CHECK-NEXT:    [[CY:%.*]] = icmp slt i8 [[Y:%.*]], 1
97 ; CHECK-NEXT:    br i1 [[CY]], label [[NEGY:%.*]], label [[POSY:%.*]]
98 ; CHECK:       negy:
99 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y]]
100 ; CHECK-NEXT:    [[Z:%.*]] = icmp slt i8 [[AND]], [[X]]
101 ; CHECK-NEXT:    ret i1 [[Z]]
102 ; CHECK:       posy:
103 ; CHECK-NEXT:    [[R:%.*]] = call i1 @barrier()
104 ; CHECK-NEXT:    ret i1 [[R]]
106   %cy = icmp sle i8 %y, 0
107   br i1 %cy, label %negy, label %posy
108 negy:
109   %and = and i8 %x, %y
110   %z = icmp slt i8 %and, %x
111   ret i1 %z
112 posy:
113   %r = call i1 @barrier()
114   ret i1 %r
117 define i1 @icmp_sle_x_negy(i8 %x, i8 %yy) {
118 ; CHECK-LABEL: @icmp_sle_x_negy(
119 ; CHECK-NEXT:    ret i1 true
121   %y = or i8 %yy, 128
122   %and = and i8 %y, %x
123   %z = icmp sle i8 %and, %x
124   ret i1 %z
127 define <2 x i1> @icmp_sgt_x_negy(<2 x i8> %x, <2 x i8> %yy) {
128 ; CHECK-LABEL: @icmp_sgt_x_negy(
129 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
131   %y = or <2 x i8> %yy, <i8 128, i8 128>
132   %and = and <2 x i8> %y, %x
133   %z = icmp sgt <2 x i8> %and, %x
134   ret <2 x i1> %z
137 define <2 x i1> @icmp_sgt_x_negy_fail_partial(<2 x i8> %x, <2 x i8> %yy) {
138 ; CHECK-LABEL: @icmp_sgt_x_negy_fail_partial(
139 ; CHECK-NEXT:    [[Y:%.*]] = or <2 x i8> [[YY:%.*]], <i8 -128, i8 4>
140 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[Y]], [[X:%.*]]
141 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt <2 x i8> [[AND]], [[X]]
142 ; CHECK-NEXT:    ret <2 x i1> [[Z]]
144   %y = or <2 x i8> %yy, <i8 128, i8 4>
145   %and = and <2 x i8> %y, %x
146   %z = icmp sgt <2 x i8> %and, %x
147   ret <2 x i1> %z
150 define <2 x i1> @icmp_sle_x_posy(<2 x i8> %x, <2 x i8> %yy) {
151 ; CHECK-LABEL: @icmp_sle_x_posy(
152 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)
153 ; CHECK-NEXT:    ret <2 x i1> [[Z]]
155   %y = and <2 x i8> %yy, <i8 127, i8 127>
156   %and = and <2 x i8> %y, %x
157   %z = icmp sle <2 x i8> %and, %x
158   ret <2 x i1> %z
161 define <2 x i1> @icmp_sle_x_posy_fail_partial(<2 x i8> %x, <2 x i8> %yy) {
162 ; CHECK-LABEL: @icmp_sle_x_posy_fail_partial(
163 ; CHECK-NEXT:    [[Y:%.*]] = and <2 x i8> [[YY:%.*]], <i8 127, i8 -65>
164 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[Y]], [[X:%.*]]
165 ; CHECK-NEXT:    [[Z:%.*]] = icmp sle <2 x i8> [[AND]], [[X]]
166 ; CHECK-NEXT:    ret <2 x i1> [[Z]]
168   %y = and <2 x i8> %yy, <i8 127, i8 191>
169   %and = and <2 x i8> %y, %x
170   %z = icmp sle <2 x i8> %and, %x
171   ret <2 x i1> %z
174 define i1 @icmp_sgt_x_posy(i8 %x, i8 %y) {
175 ; CHECK-LABEL: @icmp_sgt_x_posy(
176 ; CHECK-NEXT:    [[CY:%.*]] = icmp sgt i8 [[Y:%.*]], -1
177 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CY]])
178 ; CHECK-NEXT:    [[Z:%.*]] = icmp slt i8 [[X:%.*]], 0
179 ; CHECK-NEXT:    ret i1 [[Z]]
181   %cy = icmp sge i8 %y, 0
182   call void @llvm.assume(i1 %cy)
183   %and = and i8 %x, %y
184   %z = icmp sgt i8 %and, %x
185   ret i1 %z
188 define <2 x i1> @icmp_sgt_negx_y(<2 x i8> %xx, <2 x i8> %y) {
189 ; CHECK-LABEL: @icmp_sgt_negx_y(
190 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt <2 x i8> [[Y:%.*]], splat (i8 -1)
191 ; CHECK-NEXT:    ret <2 x i1> [[Z]]
193   %x = or <2 x i8> %xx, <i8 128, i8 128>
194   %and = and <2 x i8> %x, %y
195   %z = icmp sgt <2 x i8> %and, %x
196   ret <2 x i1> %z
199 define i1 @icmp_sle_negx_y(i8 %x, i8 %y) {
200 ; CHECK-LABEL: @icmp_sle_negx_y(
201 ; CHECK-NEXT:    [[CX:%.*]] = icmp slt i8 [[X:%.*]], 0
202 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CX]])
203 ; CHECK-NEXT:    [[Z:%.*]] = icmp slt i8 [[Y:%.*]], 0
204 ; CHECK-NEXT:    ret i1 [[Z]]
206   %cx = icmp slt i8 %x, 0
207   call void @llvm.assume(i1 %cx)
208   %and = and i8 %x, %y
209   %z = icmp sle i8 %and, %x
210   ret i1 %z
213 define i1 @icmp_sle_negx_y_fail_maybe_zero(i8 %x, i8 %y) {
214 ; CHECK-LABEL: @icmp_sle_negx_y_fail_maybe_zero(
215 ; CHECK-NEXT:    [[CX:%.*]] = icmp slt i8 [[X:%.*]], 1
216 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CX]])
217 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y:%.*]]
218 ; CHECK-NEXT:    [[Z:%.*]] = icmp sle i8 [[AND]], [[X]]
219 ; CHECK-NEXT:    ret i1 [[Z]]
221   %cx = icmp sle i8 %x, 0
222   call void @llvm.assume(i1 %cx)
223   %and = and i8 %x, %y
224   %z = icmp sle i8 %and, %x
225   ret i1 %z
228 define i1 @icmp_eq_x_invertable_y_todo(i8 %x, i1 %y) {
229 ; CHECK-LABEL: @icmp_eq_x_invertable_y_todo(
230 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[Y:%.*]], i8 -8, i8 -25
231 ; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
232 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP2]], 0
233 ; CHECK-NEXT:    ret i1 [[R]]
235   %yy = select i1 %y, i8 7, i8 24
236   %and = and i8 %x, %yy
237   %r = icmp eq i8 %x, %and
238   ret i1 %r
241 define i1 @icmp_eq_x_invertable_y(i8 %x, i8 %y) {
242 ; CHECK-LABEL: @icmp_eq_x_invertable_y(
243 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
244 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], 0
245 ; CHECK-NEXT:    ret i1 [[R]]
247   %yy = xor i8 %y, -1
248   %and = and i8 %x, %yy
249   %r = icmp eq i8 %x, %and
250   ret i1 %r
253 define i1 @icmp_eq_x_invertable_y_fail_multiuse(i8 %x, i8 %y) {
254 ; CHECK-LABEL: @icmp_eq_x_invertable_y_fail_multiuse(
255 ; CHECK-NEXT:    [[YY:%.*]] = xor i8 [[Y:%.*]], -1
256 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[YY]]
257 ; CHECK-NEXT:    call void @use.i8(i8 [[AND]])
258 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X]], [[AND]]
259 ; CHECK-NEXT:    ret i1 [[R]]
261   %yy = xor i8 %y, -1
262   %and = and i8 %x, %yy
263   call void @use.i8(i8 %and)
264   %r = icmp eq i8 %x, %and
265   ret i1 %r
268 define i1 @icmp_eq_x_invertable_y2_todo(i8 %x, i1 %y) {
269 ; CHECK-LABEL: @icmp_eq_x_invertable_y2_todo(
270 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[Y:%.*]], i8 -8, i8 -25
271 ; CHECK-NEXT:    [[TMP2:%.*]] = or i8 [[X:%.*]], [[TMP1]]
272 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP2]], -1
273 ; CHECK-NEXT:    ret i1 [[R]]
275   %yy = select i1 %y, i8 7, i8 24
276   %and = and i8 %x, %yy
277   %r = icmp eq i8 %yy, %and
278   ret i1 %r
281 define i1 @icmp_eq_x_invertable_y2(i8 %x, i8 %y) {
282 ; CHECK-LABEL: @icmp_eq_x_invertable_y2(
283 ; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
284 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], -1
285 ; CHECK-NEXT:    ret i1 [[R]]
287   %yy = xor i8 %y, -1
288   %and = and i8 %x, %yy
289   %r = icmp eq i8 %yy, %and
290   ret i1 %r
293 define i1 @icmp_eq_x_invertable_y_fail_immconstant(i8 %x, i8 %y) {
294 ; CHECK-LABEL: @icmp_eq_x_invertable_y_fail_immconstant(
295 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], 7
296 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AND]], 7
297 ; CHECK-NEXT:    ret i1 [[R]]
299   %and = and i8 %x, 7
300   %r = icmp eq i8 %and, 7
301   ret i1 %r