xref: /llvm-project/llvm/test/Transforms/InstSimplify/select_or_and.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
3
4; select(Y | X == 0, X, Y | X)
5define i32 @select_or_1(i32 %x, i32 %y) {
6; CHECK-LABEL: @select_or_1(
7; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
8; CHECK-NEXT:    ret i32 [[OR]]
9;
10  %or = or i32 %y, %x
11  %cmp = icmp eq i32 %or, 0
12  %ret = select i1 %cmp, i32 %x, i32 %or
13  ret i32 %ret
14}
15
16; select(Y | X == 0, Y, Y | X)
17define i32 @select_or_2(i32 %x, i32 %y) {
18; CHECK-LABEL: @select_or_2(
19; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
20; CHECK-NEXT:    ret i32 [[OR]]
21;
22  %or = or i32 %y, %x
23  %cmp = icmp eq i32 %or, 0
24  %ret = select i1 %cmp, i32 %y, i32 %or
25  ret i32 %ret
26}
27
28; select(Y | X != 0, Y | X, X)
29define i32 @select_or_3(i32 %x, i32 %y) {
30; CHECK-LABEL: @select_or_3(
31; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
32; CHECK-NEXT:    ret i32 [[OR]]
33;
34  %or = or i32 %y, %x
35  %cmp = icmp ne i32 %or, 0
36  %ret = select i1 %cmp, i32 %or, i32 %x
37  ret i32 %ret
38}
39
40; select(Y | X != 0, Y | X, Y)
41define i32 @select_or_4(i32 %x, i32 %y) {
42; CHECK-LABEL: @select_or_4(
43; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
44; CHECK-NEXT:    ret i32 [[OR]]
45;
46  %or = or i32 %y, %x
47  %cmp = icmp ne i32 %or, 0
48  %ret = select i1 %cmp, i32 %or, i32 %y
49  ret i32 %ret
50}
51
52; select(Y | X != 0, Y | X, Y)
53define <4 x i32> @select_or_vec(<4 x i32> %x, <4 x i32> %y) {
54; CHECK-LABEL: @select_or_vec(
55; CHECK-NEXT:    [[OR:%.*]] = or <4 x i32> [[Y:%.*]], [[X:%.*]]
56; CHECK-NEXT:    ret <4 x i32> [[OR]]
57;
58  %or = or <4 x i32> %y, %x
59  %cmp = icmp ne <4 x i32> %or, zeroinitializer
60  %ret = select <4 x i1> %cmp, <4 x i32> %or, <4 x i32> %y
61  ret <4 x i32> %ret
62}
63
64; select(Y | X == 0, Y | X, Y)
65define i32 @select_or_not_1(i32 %x, i32 %y) {
66; CHECK-LABEL: @select_or_not_1(
67; CHECK-NEXT:    ret i32 [[Y:%.*]]
68;
69  %or = or i32 %y, %x
70  %cmp = icmp eq i32 %or, 0
71  %ret = select i1 %cmp, i32 %or, i32 %y
72  ret i32 %ret
73}
74; select(Y | X != 0, Y, Y | X)
75define i32 @select_or_not_2(i32 %x, i32 %y) {
76; CHECK-LABEL: @select_or_not_2(
77; CHECK-NEXT:    ret i32 [[Y:%.*]]
78;
79  %or = or i32 %y, %x
80  %cmp = icmp ne i32 %or, 0
81  %ret = select i1 %cmp, i32 %y, i32 %or
82  ret i32 %ret
83}
84; select(Y | X != 1, Y, Y | X)
85define i32 @select_or_not_3(i32 %x, i32 %y) {
86; CHECK-LABEL: @select_or_not_3(
87; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
88; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[OR]], 1
89; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]]
90; CHECK-NEXT:    ret i32 [[RET]]
91;
92  %or = or i32 %y, %x
93  %cmp = icmp ne i32 %or, 1
94  %ret = select i1 %cmp, i32 %y, i32 %or
95  ret i32 %ret
96}
97
98; select(Y & X == -1, X, Y & X)
99define i32 @select_and_1(i32 %x, i32 %y) {
100; CHECK-LABEL: @select_and_1(
101; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
102; CHECK-NEXT:    ret i32 [[AND]]
103;
104  %and = and i32 %y, %x
105  %cmp = icmp eq i32 %and, -1
106  %ret = select i1 %cmp, i32 %x, i32 %and
107  ret i32 %ret
108}
109
110; select(Y & X == -1, Y, Y & X)
111define i32 @select_and_2(i32 %x, i32 %y) {
112; CHECK-LABEL: @select_and_2(
113; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
114; CHECK-NEXT:    ret i32 [[AND]]
115;
116  %and = and i32 %y, %x
117  %cmp = icmp eq i32 %and, -1
118  %ret = select i1 %cmp, i32 %y, i32 %and
119  ret i32 %ret
120}
121
122
123; select(Y & X != -1, Y & X, X)
124define i32 @select_and_3(i32 %x, i32 %y) {
125; CHECK-LABEL: @select_and_3(
126; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
127; CHECK-NEXT:    ret i32 [[AND]]
128;
129  %and = and i32 %y, %x
130  %cmp = icmp ne i32 %and, -1
131  %ret = select i1 %cmp, i32 %and, i32 %x
132  ret i32 %ret
133}
134
135; select(Y & X != -1, Y & X, Y)
136define i32 @select_and_4(i32 %x, i32 %y) {
137; CHECK-LABEL: @select_and_4(
138; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
139; CHECK-NEXT:    ret i32 [[AND]]
140;
141  %and = and i32 %y, %x
142  %cmp = icmp ne i32 %and, -1
143  %ret = select i1 %cmp, i32 %and, i32 %y
144  ret i32 %ret
145}
146
147; select(Y & X != -1, Y, Y & X)
148define i32 @select_and_not_1(i32 %x, i32 %y) {
149; CHECK-LABEL: @select_and_not_1(
150; CHECK-NEXT:    ret i32 [[Y:%.*]]
151;
152  %and = and i32 %y, %x
153  %cmp = icmp eq i32 %and, -1
154  %ret = select i1 %cmp, i32 %and, i32 %y
155  ret i32 %ret
156}
157
158; select(Y & X != -1, Y, Y & X)
159define i32 @select_and_not_2(i32 %x, i32 %y) {
160; CHECK-LABEL: @select_and_not_2(
161; CHECK-NEXT:    ret i32 [[Y:%.*]]
162;
163  %and = and i32 %y, %x
164  %cmp = icmp ne i32 %and, -1
165  %ret = select i1 %cmp, i32 %y, i32 %and
166  ret i32 %ret
167}
168
169; select(Y & X != 123, Y, Y & X)
170define i32 @select_and_not_3(i32 %x, i32 %y) {
171; CHECK-LABEL: @select_and_not_3(
172; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
173; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 123
174; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND]]
175; CHECK-NEXT:    ret i32 [[RET]]
176;
177  %and = and i32 %y, %x
178  %cmp = icmp ne i32 %and, 123
179  %ret = select i1 %cmp, i32 %y, i32 %and
180  ret i32 %ret
181}
182
183; https://alive2.llvm.org/ce/z/1ILbih
184define i32 @select_icmp_and_eq(i32 %a, i32 %b) {
185; CHECK-LABEL: @select_icmp_and_eq(
186; CHECK-NEXT:    ret i32 -1
187;
188  %and = and i32 %a, %b
189  %tobool = icmp eq i32 %and, -1
190  %cond = select i1 %tobool, i32 %a, i32 -1
191  ret i32 %cond
192}
193
194define i32 @select_icmp_and_eq_commuted(i32 %a, i32 %b) {
195; CHECK-LABEL: @select_icmp_and_eq_commuted(
196; CHECK-NEXT:    ret i32 -1
197;
198  %and = and i32 %a, %b
199  %tobool = icmp eq i32 %and, -1
200  %cond = select i1 %tobool, i32 %b, i32 -1
201  ret i32 %cond
202}
203
204; https://alive2.llvm.org/ce/z/HfYXvx
205define <2 x i16> @select_icmp_and_eq_vec(<2 x i16> %a, <2 x i16> %b) {
206; CHECK-LABEL: @select_icmp_and_eq_vec(
207; CHECK-NEXT:    ret <2 x i16> splat (i16 -1)
208;
209  %and = and <2 x i16> %a, %b
210  %tobool = icmp eq <2 x i16> %and, <i16 -1, i16 -1>
211  %cond = select <2 x i1> %tobool, <2 x i16> %a, <2 x i16> <i16 -1, i16 -1>
212  ret <2 x i16> %cond
213}
214
215; The ne should also be macthed
216define i32 @select_icmp_and_ne(i32 %a, i32 %b) {
217; CHECK-LABEL: @select_icmp_and_ne(
218; CHECK-NEXT:    ret i32 -1
219;
220  %and = and i32 %a, %b
221  %tobool = icmp ne i32 %and, -1
222  %cond = select i1 %tobool, i32 -1, i32 %a
223  ret i32 %cond
224}
225
226; Negative test: Incorrect const value for icmp
227define i32 @select_icmp_and_eq_incorrect_const(i32 %a, i32 %b) {
228; CHECK-LABEL: @select_icmp_and_eq_incorrect_const(
229; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
230; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
231; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 -1
232; CHECK-NEXT:    ret i32 [[COND]]
233;
234  %and = and i32 %a, %b
235  %tobool = icmp eq i32 %and, 0  ; Incorrect const value
236  %cond = select i1 %tobool, i32 %a, i32 -1
237  ret i32 %cond
238}
239
240; https://alive2.llvm.org/ce/z/hSyCuR
241define i32 @select_icmp_or_eq(i32 %a, i32 %b) {
242; CHECK-LABEL: @select_icmp_or_eq(
243; CHECK-NEXT:    ret i32 0
244;
245  %or = or i32 %a, %b
246  %tobool = icmp eq i32 %or, 0
247  %cond = select i1 %tobool, i32 %a, i32 0
248  ret i32 %cond
249}
250
251define i32 @select_icmp_or_eq_commuted(i32 %a, i32 %b) {
252; CHECK-LABEL: @select_icmp_or_eq_commuted(
253; CHECK-NEXT:    ret i32 0
254;
255  %or = or i32 %a, %b
256  %tobool = icmp eq i32 %or, 0
257  %cond = select i1 %tobool, i32 %b, i32 0
258  ret i32 %cond
259}
260
261; https://alive2.llvm.org/ce/z/S_pQek
262define <2 x i16> @select_icmp_or_eq_vec(<2 x i16> %a, <2 x i16> %b) {
263; CHECK-LABEL: @select_icmp_or_eq_vec(
264; CHECK-NEXT:    ret <2 x i16> zeroinitializer
265;
266  %or = or <2 x i16> %a, %b
267  %tobool = icmp eq <2 x i16> %or, <i16 0, i16 0>
268  %cond = select <2 x i1> %tobool, <2 x i16> %a, <2 x i16> zeroinitializer
269  ret <2 x i16> %cond
270}
271
272; The ne will also be matched
273define i32 @select_icmp_or_ne(i32 %a, i32 %b) {
274; CHECK-LABEL: @select_icmp_or_ne(
275; CHECK-NEXT:    ret i32 0
276;
277  %or = or i32 %a, %b
278  %tobool = icmp ne i32 %or, 0
279  %cond = select i1 %tobool, i32 0, i32 %a
280  ret i32 %cond
281}
282
283; Negative test: Incorrect const value for icmp
284define i32 @select_icmp_or_eq_incorrect_const(i32 %a, i32 %b) {
285; CHECK-LABEL: @select_icmp_or_eq_incorrect_const(
286; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
287; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[OR]], -1
288; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 0
289; CHECK-NEXT:    ret i32 [[COND]]
290;
291  %or = or i32 %a, %b
292  %tobool = icmp eq i32 %or, -1
293  %cond = select i1 %tobool, i32 %a, i32 0
294  ret i32 %cond
295}
296