xref: /llvm-project/llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define <2 x i1> @sub_XY_and_bit0_is_zero(<2 x i8> %x, <2 x i8> %C) nounwind {
5; CHECK-LABEL: @sub_XY_and_bit0_is_zero(
6; CHECK-NEXT:    ret <2 x i1> zeroinitializer
7;
8  %C1 = or <2 x i8> %C, <i8 9, i8 9>
9  %y = sub <2 x i8> %x, %C1
10  %w = and <2 x i8> %x, %y
11  %r = icmp eq <2 x i8> %w, <i8 -1, i8 -1>
12  ret <2 x i1> %r
13}
14
15define i1 @sub_XY_xor_bit0_is_one(i8 %x, i8 %C) nounwind {
16; CHECK-LABEL: @sub_XY_xor_bit0_is_one(
17; CHECK-NEXT:    ret i1 false
18;
19  %C1 = or i8 %C, 1
20  %y = sub i8 %x, %C1
21  %w = xor i8 %x, %y
22  %r = icmp eq i8 %w, 10
23  ret i1 %r
24}
25
26define i1 @sub_XY_or_bit0_is_one(i8 %x, i8 %C) nounwind {
27; CHECK-LABEL: @sub_XY_or_bit0_is_one(
28; CHECK-NEXT:    ret i1 false
29;
30  %C1 = or i8 %C, 1
31  %y = sub i8 %x, %C1
32  %w = or i8 %x, %y
33  %r = icmp eq i8 %w, 10
34  ret i1 %r
35}
36
37define i1 @sub_YX_and_bit0_is_zero(i8 %x, i8 %C) nounwind {
38; CHECK-LABEL: @sub_YX_and_bit0_is_zero(
39; CHECK-NEXT:    ret i1 false
40;
41  %C1 = or i8 %C, 1
42  %y = sub i8 %C1, %x
43  %w = and i8 %x, %y
44  %r = icmp eq i8 %w, -1
45  ret i1 %r
46}
47
48define <2 x i1> @sub_YX_xor_bit0_is_one(<2 x i8> %x, <2 x i8> %C) nounwind {
49; CHECK-LABEL: @sub_YX_xor_bit0_is_one(
50; CHECK-NEXT:    ret <2 x i1> zeroinitializer
51;
52  %C1 = or <2 x i8> %C, <i8 1, i8 1>
53  %y = sub <2 x i8> %C1, %x
54  %w = xor <2 x i8> %x, %y
55  %r = icmp eq <2 x i8> %w, <i8 12, i8 12>
56  ret <2 x i1> %r
57}
58
59define i1 @sub_YX_or_bit0_is_one(i8 %x, i8 %C) nounwind {
60; CHECK-LABEL: @sub_YX_or_bit0_is_one(
61; CHECK-NEXT:    ret i1 false
62;
63  %C1 = or i8 %C, 1
64  %y = sub i8 %C1, %x
65  %w = or i8 %x, %y
66  %r = icmp eq i8 %w, 32
67  ret i1 %r
68}
69
70define i1 @add_YX_xor_bit0_is_one(i8 %x, i8 %C) nounwind {
71; CHECK-LABEL: @add_YX_xor_bit0_is_one(
72; CHECK-NEXT:    ret i1 false
73;
74  %C1 = or i8 %C, 1
75  %y = add i8 %C1, %x
76  %w = xor i8 %x, %y
77  %r = icmp eq i8 %w, 32
78  ret i1 %r
79}
80
81define <2 x i1> @add_XY_or_bit0_is_one(<2 x i8> %x, <2 x i8> %C) nounwind {
82; CHECK-LABEL: @add_XY_or_bit0_is_one(
83; CHECK-NEXT:    ret <2 x i1> zeroinitializer
84;
85  %C1 = or <2 x i8> %C, <i8 1, i8 1>
86  %y = add <2 x i8> %C1, %x
87  %w = or <2 x i8> %x, %y
88  %r = icmp eq <2 x i8> %w, <i8 90, i8 90>
89  ret <2 x i1> %r
90}
91
92define <2 x i1> @sub_XY_and_bit0_is_zero_fail(<2 x i8> %x, <2 x i8> %C) nounwind {
93; CHECK-LABEL: @sub_XY_and_bit0_is_zero_fail(
94; CHECK-NEXT:    [[C1:%.*]] = or <2 x i8> [[C:%.*]], splat (i8 8)
95; CHECK-NEXT:    [[Y:%.*]] = sub <2 x i8> [[X:%.*]], [[C1]]
96; CHECK-NEXT:    [[W:%.*]] = and <2 x i8> [[X]], [[Y]]
97; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[W]], splat (i8 -1)
98; CHECK-NEXT:    ret <2 x i1> [[R]]
99;
100  %C1 = or <2 x i8> %C, <i8 8, i8 8>
101  %y = sub <2 x i8> %x, %C1
102  %w = and <2 x i8> %x, %y
103  %r = icmp eq <2 x i8> %w, <i8 -1, i8 -1>
104  ret <2 x i1> %r
105}
106
107define i1 @sub_XY_xor_bit0_is_one_fail(i8 %x, i8 %C) nounwind {
108; CHECK-LABEL: @sub_XY_xor_bit0_is_one_fail(
109; CHECK-NEXT:    [[C1:%.*]] = xor i8 [[C:%.*]], 1
110; CHECK-NEXT:    [[Y:%.*]] = sub i8 [[X:%.*]], [[C1]]
111; CHECK-NEXT:    [[W:%.*]] = xor i8 [[X]], [[Y]]
112; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[W]], 10
113; CHECK-NEXT:    ret i1 [[R]]
114;
115  %C1 = xor i8 %C, 1
116  %y = sub i8 %x, %C1
117  %w = xor i8 %x, %y
118  %r = icmp eq i8 %w, 10
119  ret i1 %r
120}
121
122define i1 @sub_XY_or_bit0_is_one_fail(i8 %x, i8 %C) nounwind {
123; CHECK-LABEL: @sub_XY_or_bit0_is_one_fail(
124; CHECK-NEXT:    [[Y:%.*]] = sub i8 [[X:%.*]], [[C:%.*]]
125; CHECK-NEXT:    [[W:%.*]] = or i8 [[X]], [[Y]]
126; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[W]], 10
127; CHECK-NEXT:    ret i1 [[R]]
128;
129  %y = sub i8 %x, %C
130  %w = or i8 %x, %y
131  %r = icmp eq i8 %w, 10
132  ret i1 %r
133}
134
135define i1 @sub_YX_and_bit0_is_zero_fail(i8 %x, i8 %C) nounwind {
136; CHECK-LABEL: @sub_YX_and_bit0_is_zero_fail(
137; CHECK-NEXT:    [[Y:%.*]] = sub i8 [[C:%.*]], [[X:%.*]]
138; CHECK-NEXT:    [[W:%.*]] = and i8 [[X]], [[Y]]
139; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[W]], -1
140; CHECK-NEXT:    ret i1 [[R]]
141;
142  %y = sub i8 %C, %x
143  %w = and i8 %x, %y
144  %r = icmp eq i8 %w, -1
145  ret i1 %r
146}
147
148define <2 x i1> @sub_YX_xor_bit0_is_one_fail(<2 x i8> %x, <2 x i8> %C) nounwind {
149; CHECK-LABEL: @sub_YX_xor_bit0_is_one_fail(
150; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> [[X:%.*]], [[C:%.*]]
151; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i8> [[X]], [[TMP1]]
152; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[TMP2]], splat (i8 -13)
153; CHECK-NEXT:    ret <2 x i1> [[R]]
154;
155  %C1 = sub <2 x i8> %C, <i8 1, i8 1>
156  %y = sub <2 x i8> %C1, %x
157  %w = xor <2 x i8> %x, %y
158  %r = icmp eq <2 x i8> %w, <i8 12, i8 12>
159  ret <2 x i1> %r
160}
161
162define i1 @sub_YX_or_bit0_is_one_fail(i8 %x, i8 %C) nounwind {
163; CHECK-LABEL: @sub_YX_or_bit0_is_one_fail(
164; CHECK-NEXT:    [[C1:%.*]] = xor i8 [[C:%.*]], 1
165; CHECK-NEXT:    [[Y:%.*]] = sub i8 [[C1]], [[X:%.*]]
166; CHECK-NEXT:    [[W:%.*]] = or i8 [[X]], [[Y]]
167; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[W]], 32
168; CHECK-NEXT:    ret i1 [[R]]
169;
170  %C1 = xor i8 %C, 1
171  %y = sub i8 %C1, %x
172  %w = or i8 %x, %y
173  %r = icmp eq i8 %w, 32
174  ret i1 %r
175}
176
177define i1 @add_YX_xor_bit0_is_one_fail(i8 %x, i8 %C) nounwind {
178; CHECK-LABEL: @add_YX_xor_bit0_is_one_fail(
179; CHECK-NEXT:    [[C1:%.*]] = and i8 [[C:%.*]], 1
180; CHECK-NEXT:    [[Y:%.*]] = add i8 [[C1]], [[X:%.*]]
181; CHECK-NEXT:    [[W:%.*]] = xor i8 [[X]], [[Y]]
182; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[W]], 32
183; CHECK-NEXT:    ret i1 [[R]]
184;
185  %C1 = and i8 %C, 1
186  %y = add i8 %C1, %x
187  %w = xor i8 %x, %y
188  %r = icmp eq i8 %w, 32
189  ret i1 %r
190}
191
192define <2 x i1> @add_XY_or_bit0_is_one_fail(<2 x i8> %x, <2 x i8> %C) nounwind {
193; CHECK-LABEL: @add_XY_or_bit0_is_one_fail(
194; CHECK-NEXT:    [[C1:%.*]] = add <2 x i8> [[C:%.*]], splat (i8 1)
195; CHECK-NEXT:    [[Y:%.*]] = add <2 x i8> [[C1]], [[X:%.*]]
196; CHECK-NEXT:    [[W:%.*]] = or <2 x i8> [[X]], [[Y]]
197; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[W]], splat (i8 90)
198; CHECK-NEXT:    ret <2 x i1> [[R]]
199;
200  %C1 = add <2 x i8> %C, <i8 1, i8 1>
201  %y = add <2 x i8> %C1, %x
202  %w = or <2 x i8> %x, %y
203  %r = icmp eq <2 x i8> %w, <i8 90, i8 90>
204  ret <2 x i1> %r
205}
206
207;; These tests are just to check if it can simplify using demanded bits path.
208define <2 x i32> @add_and_eval_vec(<2 x i32> %x, <2 x i32> %C) {
209; CHECK-LABEL: @add_and_eval_vec(
210; CHECK-NEXT:    ret <2 x i32> zeroinitializer
211;
212  %y = add <2 x i32> %x, <i32 1, i32 1>
213  %z = and <2 x i32> %x, %y
214  ;; shl so we don't commute the and
215  %b = shl <2 x i32> %z, <i32 31, i32 31>
216  ret <2 x i32> %b
217}
218
219
220define <2 x i32> @add_xor_eval_vec(<2 x i32> %x) {
221; CHECK-LABEL: @add_xor_eval_vec(
222; CHECK-NEXT:    ret <2 x i32> splat (i32 1)
223;
224  %y = add <2 x i32> %x, <i32 1, i32 1>
225  %z = xor <2 x i32> %y, %x
226  %b = and <2 x i32> %z, <i32 1, i32 1>
227  ret <2 x i32> %b
228}
229
230define <2 x i32> @add_or_eval_vec(<2 x i32> %x, <2 x i32> %C) {
231; CHECK-LABEL: @add_or_eval_vec(
232; CHECK-NEXT:    ret <2 x i32> splat (i32 1)
233;
234  %y = add <2 x i32> %x, <i32 1, i32 1>
235  %z = or <2 x i32> %y, %x
236  %b = and <2 x i32> %z, <i32 1, i32 1>
237  ret <2 x i32> %b
238}
239