1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4
5define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) {
6; CHECK-LABEL: @foo(
7; CHECK-NEXT:    [[E:%.*]] = icmp slt i32 %a, %b
8; CHECK-NEXT:    [[J:%.*]] = select i1 [[E]], i32 %c, i32 %d
9; CHECK-NEXT:    ret i32 [[J]]
10;
11  %e = icmp slt i32 %a, %b
12  %f = sext i1 %e to i32
13  %g = and i32 %c, %f
14  %h = xor i32 %f, -1
15  %i = and i32 %d, %h
16  %j = or i32 %g, %i
17  ret i32 %j
18}
19
20define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) {
21; CHECK-LABEL: @bar(
22; CHECK-NEXT:    [[E:%.*]] = icmp slt i32 %a, %b
23; CHECK-NEXT:    [[J:%.*]] = select i1 [[E]], i32 %c, i32 %d
24; CHECK-NEXT:    ret i32 [[J]]
25;
26  %e = icmp slt i32 %a, %b
27  %f = sext i1 %e to i32
28  %g = and i32 %c, %f
29  %h = xor i32 %f, -1
30  %i = and i32 %d, %h
31  %j = or i32 %i, %g
32  ret i32 %j
33}
34
35define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) {
36; CHECK-LABEL: @goo(
37; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 %a, %b
38; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d
39; CHECK-NEXT:    ret i32 [[T3]]
40;
41  %t0 = icmp slt i32 %a, %b
42  %iftmp.0.0 = select i1 %t0, i32 -1, i32 0
43  %t1 = and i32 %iftmp.0.0, %c
44  %not = xor i32 %iftmp.0.0, -1
45  %t2 = and i32 %not, %d
46  %t3 = or i32 %t1, %t2
47  ret i32 %t3
48}
49
50define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) {
51; CHECK-LABEL: @poo(
52; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 %a, %b
53; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d
54; CHECK-NEXT:    ret i32 [[T3]]
55;
56  %t0 = icmp slt i32 %a, %b
57  %iftmp.0.0 = select i1 %t0, i32 -1, i32 0
58  %t1 = and i32 %iftmp.0.0, %c
59  %iftmp = select i1 %t0, i32 0, i32 -1
60  %t2 = and i32 %iftmp, %d
61  %t3 = or i32 %t1, %t2
62  ret i32 %t3
63}
64
65define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) {
66; CHECK-LABEL: @par(
67; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 %a, %b
68; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d
69; CHECK-NEXT:    ret i32 [[T3]]
70;
71  %t0 = icmp slt i32 %a, %b
72  %iftmp.1.0 = select i1 %t0, i32 -1, i32 0
73  %t1 = and i32 %iftmp.1.0, %c
74  %not = xor i32 %iftmp.1.0, -1
75  %t2 = and i32 %not, %d
76  %t3 = or i32 %t1, %t2
77  ret i32 %t3
78}
79
80; In the following tests (8 commutation variants), verify that a bitcast doesn't get
81; in the way of a select transform. These bitcasts are common in SSE/AVX and possibly
82; other vector code because of canonicalization to i64 elements for vectors.
83
84; The fptosi instructions are included to avoid commutation canonicalization based on
85; operator weight. Using another cast operator ensures that both operands of all logic
86; ops are equally weighted, and this ensures that we're testing all commutation
87; possibilities.
88
89define <2 x i64> @bitcast_select_swap0(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
90; CHECK-LABEL: @bitcast_select_swap0(
91; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
92; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
93; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
94; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
95; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
96; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
97; CHECK-NEXT:    ret <2 x i64> [[OR]]
98;
99  %sia = fptosi <2 x double> %a to <2 x i64>
100  %sib = fptosi <2 x double> %b to <2 x i64>
101  %sext = sext <4 x i1> %cmp to <4 x i32>
102  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
103  %and1 = and <2 x i64> %bc1, %sia
104  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
105  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
106  %and2 = and <2 x i64> %bc2, %sib
107  %or = or <2 x i64> %and1, %and2
108  ret <2 x i64> %or
109}
110
111define <2 x i64> @bitcast_select_swap1(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
112; CHECK-LABEL: @bitcast_select_swap1(
113; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
114; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
115; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
116; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
117; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
118; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
119; CHECK-NEXT:    ret <2 x i64> [[OR]]
120;
121  %sia = fptosi <2 x double> %a to <2 x i64>
122  %sib = fptosi <2 x double> %b to <2 x i64>
123  %sext = sext <4 x i1> %cmp to <4 x i32>
124  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
125  %and1 = and <2 x i64> %bc1, %sia
126  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
127  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
128  %and2 = and <2 x i64> %bc2, %sib
129  %or = or <2 x i64> %and2, %and1
130  ret <2 x i64> %or
131}
132
133define <2 x i64> @bitcast_select_swap2(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
134; CHECK-LABEL: @bitcast_select_swap2(
135; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
136; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
137; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
138; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
139; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
140; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
141; CHECK-NEXT:    ret <2 x i64> [[OR]]
142;
143  %sia = fptosi <2 x double> %a to <2 x i64>
144  %sib = fptosi <2 x double> %b to <2 x i64>
145  %sext = sext <4 x i1> %cmp to <4 x i32>
146  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
147  %and1 = and <2 x i64> %bc1, %sia
148  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
149  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
150  %and2 = and <2 x i64> %sib, %bc2
151  %or = or <2 x i64> %and1, %and2
152  ret <2 x i64> %or
153}
154
155define <2 x i64> @bitcast_select_swap3(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
156; CHECK-LABEL: @bitcast_select_swap3(
157; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
158; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
159; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
160; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
161; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
162; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
163; CHECK-NEXT:    ret <2 x i64> [[OR]]
164;
165  %sia = fptosi <2 x double> %a to <2 x i64>
166  %sib = fptosi <2 x double> %b to <2 x i64>
167  %sext = sext <4 x i1> %cmp to <4 x i32>
168  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
169  %and1 = and <2 x i64> %bc1, %sia
170  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
171  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
172  %and2 = and <2 x i64> %sib, %bc2
173  %or = or <2 x i64> %and2, %and1
174  ret <2 x i64> %or
175}
176
177define <2 x i64> @bitcast_select_swap4(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
178; CHECK-LABEL: @bitcast_select_swap4(
179; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
180; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
181; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
182; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
183; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
184; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
185; CHECK-NEXT:    ret <2 x i64> [[OR]]
186;
187  %sia = fptosi <2 x double> %a to <2 x i64>
188  %sib = fptosi <2 x double> %b to <2 x i64>
189  %sext = sext <4 x i1> %cmp to <4 x i32>
190  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
191  %and1 = and <2 x i64> %sia, %bc1
192  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
193  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
194  %and2 = and <2 x i64> %bc2, %sib
195  %or = or <2 x i64> %and1, %and2
196  ret <2 x i64> %or
197}
198
199define <2 x i64> @bitcast_select_swap5(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
200; CHECK-LABEL: @bitcast_select_swap5(
201; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
202; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
203; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
204; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
205; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
206; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
207; CHECK-NEXT:    ret <2 x i64> [[OR]]
208;
209  %sia = fptosi <2 x double> %a to <2 x i64>
210  %sib = fptosi <2 x double> %b to <2 x i64>
211  %sext = sext <4 x i1> %cmp to <4 x i32>
212  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
213  %and1 = and <2 x i64> %sia, %bc1
214  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
215  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
216  %and2 = and <2 x i64> %bc2, %sib
217  %or = or <2 x i64> %and2, %and1
218  ret <2 x i64> %or
219}
220
221define <2 x i64> @bitcast_select_swap6(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
222; CHECK-LABEL: @bitcast_select_swap6(
223; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
224; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
225; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
226; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
227; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
228; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
229; CHECK-NEXT:    ret <2 x i64> [[OR]]
230;
231  %sia = fptosi <2 x double> %a to <2 x i64>
232  %sib = fptosi <2 x double> %b to <2 x i64>
233  %sext = sext <4 x i1> %cmp to <4 x i32>
234  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
235  %and1 = and <2 x i64> %sia, %bc1
236  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
237  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
238  %and2 = and <2 x i64> %sib, %bc2
239  %or = or <2 x i64> %and1, %and2
240  ret <2 x i64> %or
241}
242
243define <2 x i64> @bitcast_select_swap7(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
244; CHECK-LABEL: @bitcast_select_swap7(
245; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64>
246; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64>
247; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
248; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
249; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
250; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
251; CHECK-NEXT:    ret <2 x i64> [[OR]]
252;
253  %sia = fptosi <2 x double> %a to <2 x i64>
254  %sib = fptosi <2 x double> %b to <2 x i64>
255  %sext = sext <4 x i1> %cmp to <4 x i32>
256  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
257  %and1 = and <2 x i64> %sia, %bc1
258  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
259  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
260  %and2 = and <2 x i64> %sib, %bc2
261  %or = or <2 x i64> %and2, %and1
262  ret <2 x i64> %or
263}
264
265define <2 x i64> @bitcast_select_multi_uses(<4 x i1> %cmp, <2 x i64> %a, <2 x i64> %b) {
266; CHECK-LABEL: @bitcast_select_multi_uses(
267; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> %cmp to <4 x i32>
268; CHECK-NEXT:    [[BC1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64>
269; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i64> [[BC1]], %a
270; CHECK-NEXT:    [[NEG:%.*]] = xor <4 x i32> [[SEXT]], <i32 -1, i32 -1, i32 -1, i32 -1>
271; CHECK-NEXT:    [[BC2:%.*]] = bitcast <4 x i32> [[NEG]] to <2 x i64>
272; CHECK-NEXT:    [[AND2:%.*]] = and <2 x i64> [[BC2]], %b
273; CHECK-NEXT:    [[OR:%.*]] = or <2 x i64> [[AND2]], [[AND1]]
274; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i64> [[AND2]], [[BC2]]
275; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i64> [[OR]], [[ADD]]
276; CHECK-NEXT:    ret <2 x i64> [[SUB]]
277;
278  %sext = sext <4 x i1> %cmp to <4 x i32>
279  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
280  %and1 = and <2 x i64> %a, %bc1
281  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
282  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
283  %and2 = and <2 x i64> %b, %bc2
284  %or = or <2 x i64> %and2, %and1
285  %add = add <2 x i64> %and2, %bc2
286  %sub = sub <2 x i64> %or, %add
287  ret <2 x i64> %sub
288}
289
290define i1 @bools(i1 %a, i1 %b, i1 %c) {
291; CHECK-LABEL: @bools(
292; CHECK-NEXT:    [[TMP1:%.*]] = select i1 %c, i1 %b, i1 %a
293; CHECK-NEXT:    ret i1 [[TMP1]]
294;
295  %not = xor i1 %c, -1
296  %and1 = and i1 %not, %a
297  %and2 = and i1 %c, %b
298  %or = or i1 %and1, %and2
299  ret i1 %or
300}
301
302; Form a select if we know we can get replace 2 simple logic ops.
303
304define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) {
305; CHECK-LABEL: @bools_multi_uses1(
306; CHECK-NEXT:    [[NOT:%.*]] = xor i1 %c, true
307; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[NOT]], %a
308; CHECK-NEXT:    [[TMP1:%.*]] = select i1 %c, i1 %b, i1 %a
309; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[TMP1]], [[AND1]]
310; CHECK-NEXT:    ret i1 [[XOR]]
311;
312  %not = xor i1 %c, -1
313  %and1 = and i1 %not, %a
314  %and2 = and i1 %c, %b
315  %or = or i1 %and1, %and2
316  %xor = xor i1 %or, %and1
317  ret i1 %xor
318}
319
320; Don't replace a cheap logic op with a potentially expensive select
321; unless we can also eliminate one of the other original ops.
322
323define i1 @bools_multi_uses2(i1 %a, i1 %b, i1 %c) {
324; CHECK-LABEL: @bools_multi_uses2(
325; CHECK-NEXT:    [[NOT:%.*]] = xor i1 %c, true
326; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[NOT]], %a
327; CHECK-NEXT:    [[AND2:%.*]] = and i1 %c, %b
328; CHECK-NEXT:    [[ADD:%.*]] = xor i1 [[AND1]], [[AND2]]
329; CHECK-NEXT:    ret i1 [[ADD]]
330;
331  %not = xor i1 %c, -1
332  %and1 = and i1 %not, %a
333  %and2 = and i1 %c, %b
334  %or = or i1 %and1, %and2
335  %add = add i1 %and1, %and2
336  %and3 = and i1 %or, %add
337  ret i1 %and3
338}
339
340define <4 x i1> @vec_of_bools(<4 x i1> %a, <4 x i1> %b, <4 x i1> %c) {
341; CHECK-LABEL: @vec_of_bools(
342; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> %c, <4 x i1> %b, <4 x i1> %a
343; CHECK-NEXT:    ret <4 x i1> [[TMP1]]
344;
345  %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true>
346  %and1 = and <4 x i1> %not, %a
347  %and2 = and <4 x i1> %b, %c
348  %or = or <4 x i1> %and2, %and1
349  ret <4 x i1> %or
350}
351
352define i4 @vec_of_casted_bools(i4 %a, i4 %b, <4 x i1> %c) {
353; CHECK-LABEL: @vec_of_casted_bools(
354; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i4 %a to <4 x i1>
355; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i4 %b to <4 x i1>
356; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> %c, <4 x i1> [[TMP2]], <4 x i1> [[TMP1]]
357; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <4 x i1> [[TMP3]] to i4
358; CHECK-NEXT:    ret i4 [[TMP4]]
359;
360  %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true>
361  %bc1 = bitcast <4 x i1> %not to i4
362  %bc2 = bitcast <4 x i1> %c to i4
363  %and1 = and i4 %a, %bc1
364  %and2 = and i4 %bc2, %b
365  %or = or i4 %and1, %and2
366  ret i4 %or
367}
368
369; Inverted 'and' constants mean this is a select.
370
371define <4 x i32> @vec_sel_consts(<4 x i32> %a, <4 x i32> %b) {
372; CHECK-LABEL: @vec_sel_consts(
373; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> %a, <4 x i32> %b
374; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
375;
376  %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 -1>
377  %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 -1, i32 0>
378  %or = or <4 x i32> %and1, %and2
379  ret <4 x i32> %or
380}
381
382; The select condition constant is always derived from the first operand of the 'or'.
383
384define <3 x i129> @vec_sel_consts_weird(<3 x i129> %a, <3 x i129> %b) {
385; CHECK-LABEL: @vec_sel_consts_weird(
386; CHECK-NEXT:    [[TMP1:%.*]] = select <3 x i1> <i1 false, i1 true, i1 false>, <3 x i129> %b, <3 x i129> %a
387; CHECK-NEXT:    ret <3 x i129> [[TMP1]]
388;
389  %and1 = and <3 x i129> %a, <i129 -1, i129 0, i129 -1>
390  %and2 = and <3 x i129> %b, <i129 0, i129 -1, i129 0>
391  %or = or <3 x i129> %and2, %and1
392  ret <3 x i129> %or
393}
394
395; The mask elements must be inverted for this to be a select.
396
397define <4 x i32> @vec_not_sel_consts(<4 x i32> %a, <4 x i32> %b) {
398; CHECK-LABEL: @vec_not_sel_consts(
399; CHECK-NEXT:    [[AND1:%.*]] = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0>
400; CHECK-NEXT:    [[AND2:%.*]] = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 -1>
401; CHECK-NEXT:    [[OR:%.*]] = or <4 x i32> [[AND1]], [[AND2]]
402; CHECK-NEXT:    ret <4 x i32> [[OR]]
403;
404  %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0>
405  %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 -1>
406  %or = or <4 x i32> %and1, %and2
407  ret <4 x i32> %or
408}
409
410; The inverted constants may be operands of xor instructions.
411
412define <4 x i32> @vec_sel_xor(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) {
413; CHECK-LABEL: @vec_sel_xor(
414; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> %c, <i1 false, i1 true, i1 true, i1 true>
415; CHECK-NEXT:    [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> %a, <4 x i32> %b
416; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
417;
418  %mask = sext <4 x i1> %c to <4 x i32>
419  %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0>
420  %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1>
421  %and1 = and <4 x i32> %not_mask_flip1, %a
422  %and2 = and <4 x i32> %mask_flip1, %b
423  %or = or <4 x i32> %and1, %and2
424  ret <4 x i32> %or
425}
426
427; Allow the transform even if the mask values have multiple uses because
428; there's still a net reduction of instructions from removing the and/and/or.
429
430define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) {
431; CHECK-LABEL: @vec_sel_xor_multi_use(
432; CHECK-NEXT:    [[MASK:%.*]] = sext <4 x i1> %c to <4 x i32>
433; CHECK-NEXT:    [[MASK_FLIP1:%.*]] = xor <4 x i32> [[MASK]], <i32 -1, i32 0, i32 0, i32 0>
434; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> %c, <i1 false, i1 true, i1 true, i1 true>
435; CHECK-NEXT:    [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> %a, <4 x i32> %b
436; CHECK-NEXT:    [[ADD:%.*]] = add <4 x i32> [[TMP2]], [[MASK_FLIP1]]
437; CHECK-NEXT:    ret <4 x i32> [[ADD]]
438;
439  %mask = sext <4 x i1> %c to <4 x i32>
440  %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0>
441  %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1>
442  %and1 = and <4 x i32> %not_mask_flip1, %a
443  %and2 = and <4 x i32> %mask_flip1, %b
444  %or = or <4 x i32> %and1, %and2
445  %add = add <4 x i32> %or, %mask_flip1
446  ret <4 x i32> %add
447}
448
449