xref: /llvm-project/llvm/test/Transforms/InstCombine/logical-select.ll (revision a6fefc82450e054336a52a5d2d915b780b8c3ef7)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare i1 @gen()
5
6declare void @use(i8)
7declare void @use1(i1)
8declare void @use2(<2 x i1>)
9
10define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) {
11; CHECK-LABEL: @foo(
12; CHECK-NEXT:    [[E_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
13; CHECK-NEXT:    [[J:%.*]] = select i1 [[E_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]
14; CHECK-NEXT:    ret i32 [[J]]
15;
16  %e = icmp slt i32 %a, %b
17  %f = sext i1 %e to i32
18  %g = and i32 %c, %f
19  %h = xor i32 %f, -1
20  %i = and i32 %d, %h
21  %j = or i32 %g, %i
22  ret i32 %j
23}
24
25define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) {
26; CHECK-LABEL: @bar(
27; CHECK-NEXT:    [[E_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
28; CHECK-NEXT:    [[J:%.*]] = select i1 [[E_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]
29; CHECK-NEXT:    ret i32 [[J]]
30;
31  %e = icmp slt i32 %a, %b
32  %f = sext i1 %e to i32
33  %g = and i32 %c, %f
34  %h = xor i32 %f, -1
35  %i = and i32 %d, %h
36  %j = or i32 %i, %g
37  ret i32 %j
38}
39
40define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) {
41; CHECK-LABEL: @goo(
42; CHECK-NEXT:    [[T0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
43; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]
44; CHECK-NEXT:    ret i32 [[T3]]
45;
46  %t0 = icmp slt i32 %a, %b
47  %iftmp.0.0 = select i1 %t0, i32 -1, i32 0
48  %t1 = and i32 %iftmp.0.0, %c
49  %not = xor i32 %iftmp.0.0, -1
50  %t2 = and i32 %not, %d
51  %t3 = or i32 %t1, %t2
52  ret i32 %t3
53}
54
55define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) {
56; CHECK-LABEL: @poo(
57; CHECK-NEXT:    [[T0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
58; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]
59; CHECK-NEXT:    ret i32 [[T3]]
60;
61  %t0 = icmp slt i32 %a, %b
62  %iftmp.0.0 = select i1 %t0, i32 -1, i32 0
63  %t1 = and i32 %iftmp.0.0, %c
64  %iftmp = select i1 %t0, i32 0, i32 -1
65  %t2 = and i32 %iftmp, %d
66  %t3 = or i32 %t1, %t2
67  ret i32 %t3
68}
69
70; PR32791 - https://bugs.llvm.org//show_bug.cgi?id=32791
71; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this.
72
73define i32 @fold_inverted_icmp_preds(i32 %a, i32 %b, i32 %c, i32 %d) {
74; CHECK-LABEL: @fold_inverted_icmp_preds(
75; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
76; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[C:%.*]], i32 0
77; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]]
78; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 0, i32 [[D:%.*]]
79; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]
80; CHECK-NEXT:    ret i32 [[OR]]
81;
82  %cmp1 = icmp slt i32 %a, %b
83  %sel1 = select i1 %cmp1, i32 %c, i32 0
84  %cmp2 = icmp sge i32 %a, %b
85  %sel2 = select i1 %cmp2, i32 %d, i32 0
86  %or = or i32 %sel1, %sel2
87  ret i32 %or
88}
89
90; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this.
91
92define i32 @fold_inverted_icmp_preds_reverse(i32 %a, i32 %b, i32 %c, i32 %d) {
93; CHECK-LABEL: @fold_inverted_icmp_preds_reverse(
94; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
95; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 [[C:%.*]]
96; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]]
97; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 [[D:%.*]], i32 0
98; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]
99; CHECK-NEXT:    ret i32 [[OR]]
100;
101  %cmp1 = icmp slt i32 %a, %b
102  %sel1 = select i1 %cmp1, i32 0, i32 %c
103  %cmp2 = icmp sge i32 %a, %b
104  %sel2 = select i1 %cmp2, i32 0, i32 %d
105  %or = or i32 %sel1, %sel2
106  ret i32 %or
107}
108
109; TODO: Should fcmp have the same sort of predicate canonicalization as icmp?
110
111define i32 @fold_inverted_fcmp_preds(float %a, float %b, i32 %c, i32 %d) {
112; CHECK-LABEL: @fold_inverted_fcmp_preds(
113; CHECK-NEXT:    [[CMP1:%.*]] = fcmp olt float [[A:%.*]], [[B:%.*]]
114; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[C:%.*]], i32 0
115; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uge float [[A]], [[B]]
116; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CMP2]], i32 [[D:%.*]], i32 0
117; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]
118; CHECK-NEXT:    ret i32 [[OR]]
119;
120  %cmp1 = fcmp olt float %a, %b
121  %sel1 = select i1 %cmp1, i32 %c, i32 0
122  %cmp2 = fcmp uge float %a, %b
123  %sel2 = select i1 %cmp2, i32 %d, i32 0
124  %or = or i32 %sel1, %sel2
125  ret i32 %or
126}
127
128; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this.
129
130define <2 x i32> @fold_inverted_icmp_vector_preds(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c, <2 x i32> %d) {
131; CHECK-LABEL: @fold_inverted_icmp_vector_preds(
132; CHECK-NEXT:    [[CMP1_NOT:%.*]] = icmp eq <2 x i32> [[A:%.*]], [[B:%.*]]
133; CHECK-NEXT:    [[SEL1:%.*]] = select <2 x i1> [[CMP1_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[C:%.*]]
134; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq <2 x i32> [[A]], [[B]]
135; CHECK-NEXT:    [[SEL2:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[D:%.*]], <2 x i32> zeroinitializer
136; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[SEL1]], [[SEL2]]
137; CHECK-NEXT:    ret <2 x i32> [[OR]]
138;
139  %cmp1 = icmp ne <2 x i32> %a, %b
140  %sel1 = select <2 x i1> %cmp1, <2 x i32> %c, <2 x i32> <i32 0, i32 0>
141  %cmp2 = icmp eq <2 x i32> %a, %b
142  %sel2 = select <2 x i1> %cmp2, <2 x i32> %d, <2 x i32> <i32 0, i32 0>
143  %or = or <2 x i32> %sel1, %sel2
144  ret <2 x i32> %or
145}
146
147define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) {
148; CHECK-LABEL: @par(
149; CHECK-NEXT:    [[T0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
150; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]
151; CHECK-NEXT:    ret i32 [[T3]]
152;
153  %t0 = icmp slt i32 %a, %b
154  %iftmp.1.0 = select i1 %t0, i32 -1, i32 0
155  %t1 = and i32 %iftmp.1.0, %c
156  %not = xor i32 %iftmp.1.0, -1
157  %t2 = and i32 %not, %d
158  %t3 = or i32 %t1, %t2
159  ret i32 %t3
160}
161
162; In the following tests (8 commutation variants), verify that a bitcast doesn't get
163; in the way of a select transform. These bitcasts are common in SSE/AVX and possibly
164; other vector code because of canonicalization to i64 elements for vectors.
165
166; The fptosi instructions are included to avoid commutation canonicalization based on
167; operator weight. Using another cast operator ensures that both operands of all logic
168; ops are equally weighted, and this ensures that we're testing all commutation
169; possibilities.
170
171define <2 x i64> @bitcast_select_swap0(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
172; CHECK-LABEL: @bitcast_select_swap0(
173; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>
174; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>
175; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
176; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
177; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
178; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
179; CHECK-NEXT:    ret <2 x i64> [[OR]]
180;
181  %sia = fptosi <2 x double> %a to <2 x i64>
182  %sib = fptosi <2 x double> %b to <2 x i64>
183  %sext = sext <4 x i1> %cmp to <4 x i32>
184  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
185  %and1 = and <2 x i64> %bc1, %sia
186  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
187  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
188  %and2 = and <2 x i64> %bc2, %sib
189  %or = or <2 x i64> %and1, %and2
190  ret <2 x i64> %or
191}
192
193define <2 x i64> @bitcast_select_swap1(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
194; CHECK-LABEL: @bitcast_select_swap1(
195; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>
196; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>
197; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
198; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
199; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
200; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
201; CHECK-NEXT:    ret <2 x i64> [[OR]]
202;
203  %sia = fptosi <2 x double> %a to <2 x i64>
204  %sib = fptosi <2 x double> %b to <2 x i64>
205  %sext = sext <4 x i1> %cmp to <4 x i32>
206  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
207  %and1 = and <2 x i64> %bc1, %sia
208  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
209  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
210  %and2 = and <2 x i64> %bc2, %sib
211  %or = or <2 x i64> %and2, %and1
212  ret <2 x i64> %or
213}
214
215define <2 x i64> @bitcast_select_swap2(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
216; CHECK-LABEL: @bitcast_select_swap2(
217; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>
218; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>
219; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
220; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
221; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
222; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
223; CHECK-NEXT:    ret <2 x i64> [[OR]]
224;
225  %sia = fptosi <2 x double> %a to <2 x i64>
226  %sib = fptosi <2 x double> %b to <2 x i64>
227  %sext = sext <4 x i1> %cmp to <4 x i32>
228  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
229  %and1 = and <2 x i64> %bc1, %sia
230  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
231  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
232  %and2 = and <2 x i64> %sib, %bc2
233  %or = or <2 x i64> %and1, %and2
234  ret <2 x i64> %or
235}
236
237define <2 x i64> @bitcast_select_swap3(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
238; CHECK-LABEL: @bitcast_select_swap3(
239; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>
240; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>
241; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
242; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
243; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
244; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
245; CHECK-NEXT:    ret <2 x i64> [[OR]]
246;
247  %sia = fptosi <2 x double> %a to <2 x i64>
248  %sib = fptosi <2 x double> %b to <2 x i64>
249  %sext = sext <4 x i1> %cmp to <4 x i32>
250  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
251  %and1 = and <2 x i64> %bc1, %sia
252  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
253  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
254  %and2 = and <2 x i64> %sib, %bc2
255  %or = or <2 x i64> %and2, %and1
256  ret <2 x i64> %or
257}
258
259define <2 x i64> @bitcast_select_swap4(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
260; CHECK-LABEL: @bitcast_select_swap4(
261; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>
262; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>
263; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
264; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
265; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
266; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
267; CHECK-NEXT:    ret <2 x i64> [[OR]]
268;
269  %sia = fptosi <2 x double> %a to <2 x i64>
270  %sib = fptosi <2 x double> %b to <2 x i64>
271  %sext = sext <4 x i1> %cmp to <4 x i32>
272  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
273  %and1 = and <2 x i64> %sia, %bc1
274  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
275  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
276  %and2 = and <2 x i64> %bc2, %sib
277  %or = or <2 x i64> %and1, %and2
278  ret <2 x i64> %or
279}
280
281define <2 x i64> @bitcast_select_swap5(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
282; CHECK-LABEL: @bitcast_select_swap5(
283; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>
284; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>
285; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
286; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
287; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
288; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
289; CHECK-NEXT:    ret <2 x i64> [[OR]]
290;
291  %sia = fptosi <2 x double> %a to <2 x i64>
292  %sib = fptosi <2 x double> %b to <2 x i64>
293  %sext = sext <4 x i1> %cmp to <4 x i32>
294  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
295  %and1 = and <2 x i64> %sia, %bc1
296  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
297  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
298  %and2 = and <2 x i64> %bc2, %sib
299  %or = or <2 x i64> %and2, %and1
300  ret <2 x i64> %or
301}
302
303define <2 x i64> @bitcast_select_swap6(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
304; CHECK-LABEL: @bitcast_select_swap6(
305; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>
306; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>
307; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
308; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
309; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
310; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
311; CHECK-NEXT:    ret <2 x i64> [[OR]]
312;
313  %sia = fptosi <2 x double> %a to <2 x i64>
314  %sib = fptosi <2 x double> %b to <2 x i64>
315  %sext = sext <4 x i1> %cmp to <4 x i32>
316  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
317  %and1 = and <2 x i64> %sia, %bc1
318  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
319  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
320  %and2 = and <2 x i64> %sib, %bc2
321  %or = or <2 x i64> %and1, %and2
322  ret <2 x i64> %or
323}
324
325define <2 x i64> @bitcast_select_swap7(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
326; CHECK-LABEL: @bitcast_select_swap7(
327; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>
328; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>
329; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>
330; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>
331; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]
332; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>
333; CHECK-NEXT:    ret <2 x i64> [[OR]]
334;
335  %sia = fptosi <2 x double> %a to <2 x i64>
336  %sib = fptosi <2 x double> %b to <2 x i64>
337  %sext = sext <4 x i1> %cmp to <4 x i32>
338  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
339  %and1 = and <2 x i64> %sia, %bc1
340  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
341  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
342  %and2 = and <2 x i64> %sib, %bc2
343  %or = or <2 x i64> %and2, %and1
344  ret <2 x i64> %or
345}
346
347define <2 x i64> @bitcast_select_multi_uses(<4 x i1> %cmp, <2 x i64> %a, <2 x i64> %b) {
348; CHECK-LABEL: @bitcast_select_multi_uses(
349; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[CMP:%.*]] to <4 x i32>
350; CHECK-NEXT:    [[BC1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64>
351; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i64> [[A:%.*]], [[BC1]]
352; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64>
353; CHECK-NEXT:    [[BC2:%.*]] = xor <2 x i64> [[TMP1]], splat (i64 -1)
354; CHECK-NEXT:    [[AND2:%.*]] = and <2 x i64> [[B:%.*]], [[BC2]]
355; CHECK-NEXT:    [[OR:%.*]] = or <2 x i64> [[AND2]], [[AND1]]
356; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i64> [[AND2]], [[BC2]]
357; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i64> [[OR]], [[ADD]]
358; CHECK-NEXT:    ret <2 x i64> [[SUB]]
359;
360  %sext = sext <4 x i1> %cmp to <4 x i32>
361  %bc1 = bitcast <4 x i32> %sext to <2 x i64>
362  %and1 = and <2 x i64> %a, %bc1
363  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>
364  %bc2 = bitcast <4 x i32> %neg to <2 x i64>
365  %and2 = and <2 x i64> %b, %bc2
366  %or = or <2 x i64> %and2, %and1
367  %add = add <2 x i64> %and2, %bc2
368  %sub = sub <2 x i64> %or, %add
369  ret <2 x i64> %sub
370}
371
372define i1 @bools(i1 %a, i1 %b, i1 %c) {
373; CHECK-LABEL: @bools(
374; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
375; CHECK-NEXT:    ret i1 [[OR]]
376;
377  %not = xor i1 %c, -1
378  %and1 = and i1 %not, %a
379  %and2 = and i1 %c, %b
380  %or = or i1 %and1, %and2
381  ret i1 %or
382}
383
384define i1 @bools_logical(i1 %a, i1 %b, i1 %c) {
385; CHECK-LABEL: @bools_logical(
386; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
387; CHECK-NEXT:    ret i1 [[OR]]
388;
389  %not = xor i1 %c, -1
390  %and1 = select i1 %not, i1 %a, i1 false
391  %and2 = select i1 %c, i1 %b, i1 false
392  %or = select i1 %and1, i1 true, i1 %and2
393  ret i1 %or
394}
395
396; Form a select if we know we can replace 2 simple logic ops.
397
398define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) {
399; CHECK-LABEL: @bools_multi_uses1(
400; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true
401; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[A:%.*]], [[NOT]]
402; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 [[A]]
403; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[OR]], [[AND1]]
404; CHECK-NEXT:    ret i1 [[XOR]]
405;
406  %not = xor i1 %c, -1
407  %and1 = and i1 %not, %a
408  %and2 = and i1 %c, %b
409  %or = or i1 %and1, %and2
410  %xor = xor i1 %or, %and1
411  ret i1 %xor
412}
413
414define i1 @bools_multi_uses1_logical(i1 %a, i1 %b, i1 %c) {
415; CHECK-LABEL: @bools_multi_uses1_logical(
416; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true
417; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[NOT]], i1 [[A:%.*]], i1 false
418; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 [[A]]
419; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[OR]], [[AND1]]
420; CHECK-NEXT:    ret i1 [[XOR]]
421;
422  %not = xor i1 %c, -1
423  %and1 = select i1 %not, i1 %a, i1 false
424  %and2 = select i1 %c, i1 %b, i1 false
425  %or = select i1 %and1, i1 true, i1 %and2
426  %xor = xor i1 %or, %and1
427  ret i1 %xor
428}
429
430; Don't replace a cheap logic op with a potentially expensive select
431; unless we can also eliminate one of the other original ops.
432
433define i1 @bools_multi_uses2(i1 %a, i1 %b, i1 %c) {
434; CHECK-LABEL: @bools_multi_uses2(
435; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
436; CHECK-NEXT:    ret i1 [[OR]]
437;
438  %not = xor i1 %c, -1
439  %and1 = and i1 %not, %a
440  %and2 = and i1 %c, %b
441  %or = or i1 %and1, %and2
442  %add = add i1 %and1, %and2
443  %and3 = and i1 %or, %add
444  ret i1 %and3
445}
446
447define i1 @bools_multi_uses2_logical(i1 %a, i1 %b, i1 %c) {
448; CHECK-LABEL: @bools_multi_uses2_logical(
449; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true
450; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[NOT]], i1 [[A:%.*]], i1 false
451; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false
452; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C]], i1 [[B]], i1 [[A]]
453; CHECK-NEXT:    [[ADD:%.*]] = xor i1 [[AND1]], [[AND2]]
454; CHECK-NEXT:    [[AND3:%.*]] = select i1 [[OR]], i1 [[ADD]], i1 false
455; CHECK-NEXT:    ret i1 [[AND3]]
456;
457  %not = xor i1 %c, -1
458  %and1 = select i1 %not, i1 %a, i1 false
459  %and2 = select i1 %c, i1 %b, i1 false
460  %or = select i1 %and1, i1 true, i1 %and2
461  %add = add i1 %and1, %and2
462  %and3 = select i1 %or, i1 %add, i1 false
463  ret i1 %and3
464}
465
466define <4 x i1> @vec_of_bools(<4 x i1> %a, <4 x i1> %b, <4 x i1> %c) {
467; CHECK-LABEL: @vec_of_bools(
468; CHECK-NEXT:    [[OR:%.*]] = select <4 x i1> [[C:%.*]], <4 x i1> [[B:%.*]], <4 x i1> [[A:%.*]]
469; CHECK-NEXT:    ret <4 x i1> [[OR]]
470;
471  %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true>
472  %and1 = and <4 x i1> %not, %a
473  %and2 = and <4 x i1> %b, %c
474  %or = or <4 x i1> %and2, %and1
475  ret <4 x i1> %or
476}
477
478define <vscale x 1 x i1> @vec_of_bools_scalable(<vscale x 1 x i1> %a, <vscale x 1 x i1> %c, <vscale x 1 x i1> %d) {
479; CHECK-LABEL: @vec_of_bools_scalable(
480; CHECK-NEXT:    [[R:%.*]] = select <vscale x 1 x i1> [[A:%.*]], <vscale x 1 x i1> [[C:%.*]], <vscale x 1 x i1> [[D:%.*]]
481; CHECK-NEXT:    ret <vscale x 1 x i1> [[R]]
482;
483  %b = xor <vscale x 1 x i1> %a, splat (i1 true)
484  %t11 = and <vscale x 1 x i1> %a, %c
485  %t12 = and <vscale x 1 x i1> %b, %d
486  %r = or <vscale x 1 x i1> %t11, %t12
487  ret <vscale x 1 x i1> %r
488}
489
490define i4 @vec_of_casted_bools(i4 %a, i4 %b, <4 x i1> %c) {
491; CHECK-LABEL: @vec_of_casted_bools(
492; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i4 [[B:%.*]] to <4 x i1>
493; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i4 [[A:%.*]] to <4 x i1>
494; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[C:%.*]], <4 x i1> [[TMP1]], <4 x i1> [[TMP2]]
495; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i1> [[TMP3]] to i4
496; CHECK-NEXT:    ret i4 [[OR]]
497;
498  %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true>
499  %bc1 = bitcast <4 x i1> %not to i4
500  %bc2 = bitcast <4 x i1> %c to i4
501  %and1 = and i4 %a, %bc1
502  %and2 = and i4 %bc2, %b
503  %or = or i4 %and1, %and2
504  ret i4 %or
505}
506
507define <vscale x 1 x i64> @vec_of_casted_bools_scalable(<vscale x 1 x i64> %a, <vscale x 1 x i64> %b, <vscale x 8 x i1> %cond) {
508; CHECK-LABEL: @vec_of_casted_bools_scalable(
509; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <vscale x 1 x i64> [[A:%.*]] to <vscale x 8 x i8>
510; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <vscale x 1 x i64> [[B:%.*]] to <vscale x 8 x i8>
511; CHECK-NEXT:    [[TMP3:%.*]] = select <vscale x 8 x i1> [[COND:%.*]], <vscale x 8 x i8> [[TMP1]], <vscale x 8 x i8> [[TMP2]]
512; CHECK-NEXT:    [[OR:%.*]] = bitcast <vscale x 8 x i8> [[TMP3]] to <vscale x 1 x i64>
513; CHECK-NEXT:    ret <vscale x 1 x i64> [[OR]]
514;
515  %scond = sext <vscale x 8 x i1> %cond to <vscale x 8 x i8>
516  %notcond = xor <vscale x 8 x i1> %cond, splat (i1 true)
517  %snotcond = sext <vscale x 8 x i1> %notcond to <vscale x 8 x i8>
518  %bc1 = bitcast <vscale x 8 x i8> %scond to <vscale x 1 x i64>
519  %bc2 = bitcast <vscale x 8 x i8> %snotcond to <vscale x 1 x i64>
520  %and1 = and <vscale x 1 x i64> %a, %bc1
521  %and2 = and <vscale x 1 x i64> %bc2, %b
522  %or = or <vscale x 1 x i64> %and1, %and2
523  ret <vscale x 1 x i64> %or
524}
525
526; Inverted 'and' constants mean this is a select which is canonicalized to a shuffle.
527
528define <4 x i32> @vec_sel_consts(<4 x i32> %a, <4 x i32> %b) {
529; CHECK-LABEL: @vec_sel_consts(
530; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>
531; CHECK-NEXT:    ret <4 x i32> [[OR]]
532;
533  %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 -1>
534  %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 -1, i32 0>
535  %or = or <4 x i32> %and1, %and2
536  ret <4 x i32> %or
537}
538
539define <3 x i129> @vec_sel_consts_weird(<3 x i129> %a, <3 x i129> %b) {
540; CHECK-LABEL: @vec_sel_consts_weird(
541; CHECK-NEXT:    [[OR:%.*]] = shufflevector <3 x i129> [[A:%.*]], <3 x i129> [[B:%.*]], <3 x i32> <i32 0, i32 4, i32 2>
542; CHECK-NEXT:    ret <3 x i129> [[OR]]
543;
544  %and1 = and <3 x i129> %a, <i129 -1, i129 0, i129 -1>
545  %and2 = and <3 x i129> %b, <i129 0, i129 -1, i129 0>
546  %or = or <3 x i129> %and2, %and1
547  ret <3 x i129> %or
548}
549
550; The mask elements must be inverted for this to be a select.
551
552define <4 x i32> @vec_not_sel_consts(<4 x i32> %a, <4 x i32> %b) {
553; CHECK-LABEL: @vec_not_sel_consts(
554; CHECK-NEXT:    [[AND1:%.*]] = and <4 x i32> [[A:%.*]], <i32 -1, i32 0, i32 0, i32 0>
555; CHECK-NEXT:    [[AND2:%.*]] = and <4 x i32> [[B:%.*]], <i32 0, i32 -1, i32 0, i32 -1>
556; CHECK-NEXT:    [[OR:%.*]] = or <4 x i32> [[AND1]], [[AND2]]
557; CHECK-NEXT:    ret <4 x i32> [[OR]]
558;
559  %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0>
560  %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 -1>
561  %or = or <4 x i32> %and1, %and2
562  ret <4 x i32> %or
563}
564
565define <4 x i32> @vec_not_sel_consts_undef_elts(<4 x i32> %a, <4 x i32> %b) {
566; CHECK-LABEL: @vec_not_sel_consts_undef_elts(
567; CHECK-NEXT:    [[AND1:%.*]] = and <4 x i32> [[A:%.*]], <i32 -1, i32 undef, i32 0, i32 0>
568; CHECK-NEXT:    [[AND2:%.*]] = and <4 x i32> [[B:%.*]], <i32 0, i32 -1, i32 0, i32 undef>
569; CHECK-NEXT:    [[OR:%.*]] = or <4 x i32> [[AND1]], [[AND2]]
570; CHECK-NEXT:    ret <4 x i32> [[OR]]
571;
572  %and1 = and <4 x i32> %a, <i32 -1, i32 undef, i32 0, i32 0>
573  %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 undef>
574  %or = or <4 x i32> %and1, %and2
575  ret <4 x i32> %or
576}
577
578; The inverted constants may be operands of xor instructions.
579
580define <4 x i32> @vec_sel_xor(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) {
581; CHECK-LABEL: @vec_sel_xor(
582; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> [[C:%.*]], <i1 false, i1 true, i1 true, i1 true>
583; CHECK-NEXT:    [[OR:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]
584; CHECK-NEXT:    ret <4 x i32> [[OR]]
585;
586  %mask = sext <4 x i1> %c to <4 x i32>
587  %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0>
588  %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1>
589  %and1 = and <4 x i32> %not_mask_flip1, %a
590  %and2 = and <4 x i32> %mask_flip1, %b
591  %or = or <4 x i32> %and1, %and2
592  ret <4 x i32> %or
593}
594
595; Allow the transform even if the mask values have multiple uses because
596; there's still a net reduction of instructions from removing the and/and/or.
597
598define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) {
599; CHECK-LABEL: @vec_sel_xor_multi_use(
600; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> [[C:%.*]], <i1 true, i1 false, i1 false, i1 false>
601; CHECK-NEXT:    [[MASK_FLIP1:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i32>
602; CHECK-NEXT:    [[TMP2:%.*]] = xor <4 x i1> [[C]], <i1 false, i1 true, i1 true, i1 true>
603; CHECK-NEXT:    [[OR:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]
604; CHECK-NEXT:    [[ADD:%.*]] = add <4 x i32> [[OR]], [[MASK_FLIP1]]
605; CHECK-NEXT:    ret <4 x i32> [[ADD]]
606;
607  %mask = sext <4 x i1> %c to <4 x i32>
608  %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0>
609  %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1>
610  %and1 = and <4 x i32> %not_mask_flip1, %a
611  %and2 = and <4 x i32> %mask_flip1, %b
612  %or = or <4 x i32> %and1, %and2
613  %add = add <4 x i32> %or, %mask_flip1
614  ret <4 x i32> %add
615}
616
617; The 'ashr' guarantees that we have a bitmask, so this is select with truncated condition.
618
619define i32 @allSignBits(i32 %cond, i32 %tval, i32 %fval) {
620; CHECK-LABEL: @allSignBits(
621; CHECK-NEXT:    [[ISNEG1:%.*]] = icmp slt i32 [[COND:%.*]], 0
622; CHECK-NEXT:    [[A1:%.*]] = select i1 [[ISNEG1]], i32 [[TVAL:%.*]], i32 0
623; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[COND]], 0
624; CHECK-NEXT:    [[A2:%.*]] = select i1 [[ISNEG]], i32 0, i32 [[FVAL:%.*]]
625; CHECK-NEXT:    [[SEL:%.*]] = or i32 [[A1]], [[A2]]
626; CHECK-NEXT:    ret i32 [[SEL]]
627;
628  %bitmask = ashr i32 %cond, 31
629  %not_bitmask = xor i32 %bitmask, -1
630  %a1 = and i32 %tval, %bitmask
631  %a2 = and i32 %not_bitmask, %fval
632  %sel = or i32 %a1, %a2
633  ret i32 %sel
634}
635
636define <4 x i8> @allSignBits_vec(<4 x i8> %cond, <4 x i8> %tval, <4 x i8> %fval) {
637; CHECK-LABEL: @allSignBits_vec(
638; CHECK-NEXT:    [[ISNEG1:%.*]] = icmp slt <4 x i8> [[COND:%.*]], zeroinitializer
639; CHECK-NEXT:    [[A1:%.*]] = select <4 x i1> [[ISNEG1]], <4 x i8> [[TVAL:%.*]], <4 x i8> zeroinitializer
640; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <4 x i8> [[COND]], zeroinitializer
641; CHECK-NEXT:    [[A2:%.*]] = select <4 x i1> [[ISNEG]], <4 x i8> zeroinitializer, <4 x i8> [[FVAL:%.*]]
642; CHECK-NEXT:    [[SEL:%.*]] = or <4 x i8> [[A2]], [[A1]]
643; CHECK-NEXT:    ret <4 x i8> [[SEL]]
644;
645  %bitmask = ashr <4 x i8> %cond, <i8 7, i8 7, i8 7, i8 7>
646  %not_bitmask = xor <4 x i8> %bitmask, <i8 -1, i8 -1, i8 -1, i8 -1>
647  %a1 = and <4 x i8> %tval, %bitmask
648  %a2 = and <4 x i8> %fval, %not_bitmask
649  %sel = or <4 x i8> %a2, %a1
650  ret <4 x i8> %sel
651}
652
653; Negative test - make sure that bitcasts from FP do not cause a crash.
654
655define <2 x i64> @fp_bitcast(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {
656; CHECK-LABEL: @fp_bitcast(
657; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>
658; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>
659; CHECK-NEXT:    [[BC1:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
660; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i64> [[SIA]], [[BC1]]
661; CHECK-NEXT:    [[BC2:%.*]] = bitcast <2 x double> [[B]] to <2 x i64>
662; CHECK-NEXT:    [[AND2:%.*]] = and <2 x i64> [[SIB]], [[BC2]]
663; CHECK-NEXT:    [[OR:%.*]] = or <2 x i64> [[AND2]], [[AND1]]
664; CHECK-NEXT:    ret <2 x i64> [[OR]]
665;
666  %sia = fptosi <2 x double> %a to <2 x i64>
667  %sib = fptosi <2 x double> %b to <2 x i64>
668  %bc1 = bitcast <2 x double> %a to <2 x i64>
669  %and1 = and <2 x i64> %sia, %bc1
670  %bc2 = bitcast <2 x double> %b to <2 x i64>
671  %and2 = and <2 x i64> %sib, %bc2
672  %or = or <2 x i64> %and2, %and1
673  ret <2 x i64> %or
674}
675
676define <4 x i32> @computesignbits_through_shuffles(<4 x float> %x, <4 x float> %y, <4 x float> %z) {
677; CHECK-LABEL: @computesignbits_through_shuffles(
678; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole <4 x float> [[X:%.*]], [[Y:%.*]]
679; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[CMP]] to <4 x i32>
680; CHECK-NEXT:    [[S1:%.*]] = shufflevector <4 x i32> [[SEXT]], <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
681; CHECK-NEXT:    [[S2:%.*]] = shufflevector <4 x i32> [[SEXT]], <4 x i32> poison, <4 x i32> <i32 2, i32 2, i32 3, i32 3>
682; CHECK-NEXT:    [[SHUF_OR1:%.*]] = or <4 x i32> [[S1]], [[S2]]
683; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x i32> [[SHUF_OR1]], <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
684; CHECK-NEXT:    [[S4:%.*]] = shufflevector <4 x i32> [[SHUF_OR1]], <4 x i32> poison, <4 x i32> <i32 2, i32 2, i32 3, i32 3>
685; CHECK-NEXT:    [[SHUF_OR2:%.*]] = or <4 x i32> [[S3]], [[S4]]
686; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw <4 x i32> [[SHUF_OR2]] to <4 x i1>
687; CHECK-NEXT:    [[SEL_V:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[Z:%.*]], <4 x float> [[X]]
688; CHECK-NEXT:    [[SEL:%.*]] = bitcast <4 x float> [[SEL_V]] to <4 x i32>
689; CHECK-NEXT:    ret <4 x i32> [[SEL]]
690;
691  %cmp = fcmp ole <4 x float> %x, %y
692  %sext = sext <4 x i1> %cmp to <4 x i32>
693  %s1 = shufflevector <4 x i32> %sext, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
694  %s2 = shufflevector <4 x i32> %sext, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3>
695  %shuf_or1 = or <4 x i32> %s1, %s2
696  %s3 = shufflevector <4 x i32> %shuf_or1, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
697  %s4 = shufflevector <4 x i32> %shuf_or1, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3>
698  %shuf_or2 = or <4 x i32> %s3, %s4
699  %not_or2 = xor <4 x i32> %shuf_or2, <i32 -1, i32 -1, i32 -1, i32 -1>
700  %xbc = bitcast <4 x float> %x to <4 x i32>
701  %zbc = bitcast <4 x float> %z to <4 x i32>
702  %and1 = and <4 x i32> %not_or2, %xbc
703  %and2 = and <4 x i32> %shuf_or2, %zbc
704  %sel = or <4 x i32> %and1, %and2
705  ret <4 x i32> %sel
706}
707
708define <4 x i32> @computesignbits_through_two_input_shuffle(<4 x i32> %x, <4 x i32> %y, <4 x i1> %cond1, <4 x i1> %cond2) {
709; CHECK-LABEL: @computesignbits_through_two_input_shuffle(
710; CHECK-NEXT:    [[COND:%.*]] = shufflevector <4 x i1> [[COND1:%.*]], <4 x i1> [[COND2:%.*]], <4 x i32> <i32 0, i32 2, i32 4, i32 6>
711; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> [[COND]], <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]]
712; CHECK-NEXT:    ret <4 x i32> [[SEL]]
713;
714  %sext1 = sext <4 x i1> %cond1 to <4 x i32>
715  %sext2 = sext <4 x i1> %cond2 to <4 x i32>
716  %cond = shufflevector <4 x i32> %sext1, <4 x i32> %sext2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
717  %notcond = xor <4 x i32> %cond, <i32 -1, i32 -1, i32 -1, i32 -1>
718  %and1 = and <4 x i32> %notcond, %x
719  %and2 = and <4 x i32> %cond, %y
720  %sel = or <4 x i32> %and1, %and2
721  ret <4 x i32> %sel
722}
723
724; Bitcast of condition from narrow source element type can be converted to select.
725
726define <2 x i64> @bitcast_vec_cond(<16 x i1> %cond, <2 x i64> %c, <2 x i64> %d) {
727; CHECK-LABEL: @bitcast_vec_cond(
728; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[D:%.*]] to <16 x i8>
729; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[C:%.*]] to <16 x i8>
730; CHECK-NEXT:    [[TMP3:%.*]] = select <16 x i1> [[COND:%.*]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]
731; CHECK-NEXT:    [[R:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x i64>
732; CHECK-NEXT:    ret <2 x i64> [[R]]
733;
734  %s = sext <16 x i1> %cond to <16 x i8>
735  %t9 = bitcast <16 x i8> %s to <2 x i64>
736  %nott9 = xor <2 x i64> %t9, <i64 -1, i64 -1>
737  %t11 = and <2 x i64> %nott9, %c
738  %t12 = and <2 x i64> %t9, %d
739  %r = or <2 x i64> %t11, %t12
740  ret <2 x i64> %r
741}
742
743define <vscale x 2 x i64> @bitcast_vec_cond_scalable(<vscale x 16 x i1> %cond, <vscale x 2 x i64> %c, <vscale x 2 x i64> %d) {
744; CHECK-LABEL: @bitcast_vec_cond_scalable(
745; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <vscale x 2 x i64> [[D:%.*]] to <vscale x 16 x i8>
746; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <vscale x 2 x i64> [[C:%.*]] to <vscale x 16 x i8>
747; CHECK-NEXT:    [[TMP3:%.*]] = select <vscale x 16 x i1> [[COND:%.*]], <vscale x 16 x i8> [[TMP1]], <vscale x 16 x i8> [[TMP2]]
748; CHECK-NEXT:    [[R:%.*]] = bitcast <vscale x 16 x i8> [[TMP3]] to <vscale x 2 x i64>
749; CHECK-NEXT:    ret <vscale x 2 x i64> [[R]]
750;
751  %s = sext <vscale x 16 x i1> %cond to <vscale x 16 x i8>
752  %t9 = bitcast <vscale x 16 x i8> %s to <vscale x 2 x i64>
753  %nott9 = xor <vscale x 2 x i64> %t9, splat (i64 -1)
754  %t11 = and <vscale x 2 x i64> %nott9, %c
755  %t12 = and <vscale x 2 x i64> %t9, %d
756  %r = or <vscale x 2 x i64> %t11, %t12
757  ret <vscale x 2 x i64> %r
758}
759
760; Negative test - bitcast of condition from wide source element type cannot be converted to select.
761
762define <8 x i3> @bitcast_vec_cond_commute1(<3 x i1> noundef %cond, <8 x i3> %pc, <8 x i3> %d) {
763; CHECK-LABEL: @bitcast_vec_cond_commute1(
764; CHECK-NEXT:    [[C:%.*]] = mul <8 x i3> [[PC:%.*]], [[PC]]
765; CHECK-NEXT:    [[S:%.*]] = sext <3 x i1> [[COND:%.*]] to <3 x i8>
766; CHECK-NEXT:    [[T9:%.*]] = bitcast <3 x i8> [[S]] to <8 x i3>
767; CHECK-NEXT:    [[NOTT9:%.*]] = xor <8 x i3> [[T9]], splat (i3 -1)
768; CHECK-NEXT:    [[T11:%.*]] = and <8 x i3> [[C]], [[NOTT9]]
769; CHECK-NEXT:    [[T12:%.*]] = and <8 x i3> [[D:%.*]], [[T9]]
770; CHECK-NEXT:    [[R:%.*]] = or disjoint <8 x i3> [[T11]], [[T12]]
771; CHECK-NEXT:    ret <8 x i3> [[R]]
772;
773  %c = mul <8 x i3> %pc, %pc ; thwart complexity-based canonicalization
774  %s = sext <3 x i1> %cond to <3 x i8>
775  %t9 = bitcast <3 x i8> %s to <8 x i3>
776  %nott9 = xor <8 x i3> %t9, <i3 -1, i3 -1, i3 -1, i3 -1, i3 -1, i3 -1, i3 -1, i3 -1>
777  %t11 = and <8 x i3> %c, %nott9
778  %t12 = and <8 x i3> %t9, %d
779  %r = or <8 x i3> %t11, %t12
780  ret <8 x i3> %r
781}
782
783define <2 x i16> @bitcast_vec_cond_commute2(<4 x i1> %cond, <2 x i16> %pc, <2 x i16> %pd) {
784; CHECK-LABEL: @bitcast_vec_cond_commute2(
785; CHECK-NEXT:    [[C:%.*]] = mul <2 x i16> [[PC:%.*]], [[PC]]
786; CHECK-NEXT:    [[D:%.*]] = mul <2 x i16> [[PD:%.*]], [[PD]]
787; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i16> [[D]] to <4 x i8>
788; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i16> [[C]] to <4 x i8>
789; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[COND:%.*]], <4 x i8> [[TMP1]], <4 x i8> [[TMP2]]
790; CHECK-NEXT:    [[R:%.*]] = bitcast <4 x i8> [[TMP3]] to <2 x i16>
791; CHECK-NEXT:    ret <2 x i16> [[R]]
792;
793  %c = mul <2 x i16> %pc, %pc ; thwart complexity-based canonicalization
794  %d = mul <2 x i16> %pd, %pd ; thwart complexity-based canonicalization
795  %s = sext <4 x i1> %cond to <4 x i8>
796  %t9 = bitcast <4 x i8> %s to <2 x i16>
797  %nott9 = xor <2 x i16> %t9, <i16 -1, i16 -1>
798  %t11 = and <2 x i16> %c, %nott9
799  %t12 = and <2 x i16> %d, %t9
800  %r = or <2 x i16> %t11, %t12
801  ret <2 x i16> %r
802}
803
804; Condition doesn't have to be a bool vec - just all signbits.
805
806define <2 x i16> @bitcast_vec_cond_commute3(<4 x i8> %cond, <2 x i16> %pc, <2 x i16> %pd) {
807; CHECK-LABEL: @bitcast_vec_cond_commute3(
808; CHECK-NEXT:    [[C:%.*]] = mul <2 x i16> [[PC:%.*]], [[PC]]
809; CHECK-NEXT:    [[D:%.*]] = mul <2 x i16> [[PD:%.*]], [[PD]]
810; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i16> [[D]] to <4 x i8>
811; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i16> [[C]] to <4 x i8>
812; CHECK-NEXT:    [[DOTNOT2:%.*]] = icmp slt <4 x i8> [[COND:%.*]], zeroinitializer
813; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[DOTNOT2]], <4 x i8> [[TMP1]], <4 x i8> [[TMP2]]
814; CHECK-NEXT:    [[R:%.*]] = bitcast <4 x i8> [[TMP3]] to <2 x i16>
815; CHECK-NEXT:    ret <2 x i16> [[R]]
816;
817  %c = mul <2 x i16> %pc, %pc ; thwart complexity-based canonicalization
818  %d = mul <2 x i16> %pd, %pd ; thwart complexity-based canonicalization
819  %s = ashr <4 x i8> %cond, <i8 7, i8 7, i8 7, i8 7>
820  %t9 = bitcast <4 x i8> %s to <2 x i16>
821  %nott9 = xor <2 x i16> %t9, <i16 -1, i16 -1>
822  %t11 = and <2 x i16> %c, %nott9
823  %t12 = and <2 x i16> %d, %t9
824  %r = or <2 x i16> %t11, %t12
825  ret <2 x i16> %r
826}
827
828; Don't crash on invalid type for compute signbits.
829
830define <2 x i64> @bitcast_fp_vec_cond(<2 x double> noundef %s, <2 x i64> %c, <2 x i64> %d) {
831; CHECK-LABEL: @bitcast_fp_vec_cond(
832; CHECK-NEXT:    [[T9:%.*]] = bitcast <2 x double> [[S:%.*]] to <2 x i64>
833; CHECK-NEXT:    [[NOTT9:%.*]] = xor <2 x i64> [[T9]], splat (i64 -1)
834; CHECK-NEXT:    [[T11:%.*]] = and <2 x i64> [[C:%.*]], [[NOTT9]]
835; CHECK-NEXT:    [[T12:%.*]] = and <2 x i64> [[D:%.*]], [[T9]]
836; CHECK-NEXT:    [[R:%.*]] = or disjoint <2 x i64> [[T11]], [[T12]]
837; CHECK-NEXT:    ret <2 x i64> [[R]]
838;
839  %t9 = bitcast <2 x double> %s to <2 x i64>
840  %nott9 = xor <2 x i64> %t9, <i64 -1, i64 -1>
841  %t11 = and <2 x i64> %nott9, %c
842  %t12 = and <2 x i64> %t9, %d
843  %r = or <2 x i64> %t11, %t12
844  ret <2 x i64> %r
845}
846
847; Wider source type would be ok except poison could leak across elements.
848
849define <2 x i64> @bitcast_int_vec_cond(i1 noundef %b, <2 x i64> %c, <2 x i64> %d) {
850; CHECK-LABEL: @bitcast_int_vec_cond(
851; CHECK-NEXT:    [[S:%.*]] = sext i1 [[B:%.*]] to i128
852; CHECK-NEXT:    [[T9:%.*]] = bitcast i128 [[S]] to <2 x i64>
853; CHECK-NEXT:    [[NOTT9:%.*]] = xor <2 x i64> [[T9]], splat (i64 -1)
854; CHECK-NEXT:    [[T11:%.*]] = and <2 x i64> [[C:%.*]], [[NOTT9]]
855; CHECK-NEXT:    [[T12:%.*]] = and <2 x i64> [[D:%.*]], [[T9]]
856; CHECK-NEXT:    [[R:%.*]] = or disjoint <2 x i64> [[T11]], [[T12]]
857; CHECK-NEXT:    ret <2 x i64> [[R]]
858;
859  %s = sext i1 %b to i128
860  %t9 = bitcast i128 %s to <2 x i64>
861  %nott9 = xor <2 x i64> %t9, <i64 -1, i64 -1>
862  %t11 = and <2 x i64> %nott9, %c
863  %t12 = and <2 x i64> %t9, %d
864  %r = or <2 x i64> %t11, %t12
865  ret <2 x i64> %r
866}
867
868; Converting integer logic ops to vector select is allowed.
869
870define i64 @bitcast_int_scalar_cond(<2 x i1> %b, i64 %c, i64 %d) {
871; CHECK-LABEL: @bitcast_int_scalar_cond(
872; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i64 [[D:%.*]] to <2 x i32>
873; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i64 [[C:%.*]] to <2 x i32>
874; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[B:%.*]], <2 x i32> [[TMP1]], <2 x i32> [[TMP2]]
875; CHECK-NEXT:    [[R:%.*]] = bitcast <2 x i32> [[TMP3]] to i64
876; CHECK-NEXT:    ret i64 [[R]]
877;
878  %s = sext <2 x i1> %b to <2 x i32>
879  %t9 = bitcast <2 x i32> %s to i64
880  %nott9 = xor i64 %t9, -1
881  %t11 = and i64 %nott9, %c
882  %t12 = and i64 %t9, %d
883  %r = or i64 %t11, %t12
884  ret i64 %r
885}
886
887; Peek through bitcasts and sexts to find negated bool condition.
888
889define <1 x i6> @bitcast_sext_cond(<2 x i1> %cmp, <1 x i6> %a, <1 x i6> %b) {
890; CHECK-LABEL: @bitcast_sext_cond(
891; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <1 x i6> [[A:%.*]] to <2 x i3>
892; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <1 x i6> [[B:%.*]] to <2 x i3>
893; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i3> [[TMP1]], <2 x i3> [[TMP2]]
894; CHECK-NEXT:    [[OR:%.*]] = bitcast <2 x i3> [[TMP3]] to <1 x i6>
895; CHECK-NEXT:    ret <1 x i6> [[OR]]
896;
897  %sext = sext <2 x i1> %cmp to <2 x i3>
898  %bc1 = bitcast <2 x i3> %sext to <1 x i6>
899  %neg = xor <2 x i1> %cmp, <i1 -1, i1 -1>
900  %sext2 = sext <2 x i1> %neg to <2 x i3>
901  %bc2 = bitcast <2 x i3> %sext2 to <1 x i6>
902  %and1 = and <1 x i6> %bc1, %a
903  %and2 = and <1 x i6> %bc2, %b
904  %or = or <1 x i6> %and1, %and2
905  ret <1 x i6> %or
906}
907
908; Extra uses may prevent other transforms from creating the canonical patterns.
909
910define i8 @sext_cond_extra_uses(i1 %cmp, i8 %a, i8 %b) {
911; CHECK-LABEL: @sext_cond_extra_uses(
912; CHECK-NEXT:    [[NEG:%.*]] = xor i1 [[CMP:%.*]], true
913; CHECK-NEXT:    [[SEXT1:%.*]] = sext i1 [[CMP]] to i8
914; CHECK-NEXT:    call void @use(i8 [[SEXT1]])
915; CHECK-NEXT:    [[SEXT2:%.*]] = sext i1 [[NEG]] to i8
916; CHECK-NEXT:    call void @use(i8 [[SEXT2]])
917; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP]], i8 [[A:%.*]], i8 [[B:%.*]]
918; CHECK-NEXT:    ret i8 [[OR]]
919;
920  %neg = xor i1 %cmp, -1
921  %sext1 = sext i1 %cmp to i8
922  call void @use(i8 %sext1)
923  %sext2 = sext i1 %neg to i8
924  call void @use(i8 %sext2)
925  %and1 = and i8 %sext1, %a
926  %and2 = and i8 %sext2, %b
927  %or = or i8 %and1, %and2
928  ret i8 %or
929}
930
931define i1 @xor_commute0(i1 %x, i1 %y) {
932; CHECK-LABEL: @xor_commute0(
933; CHECK-NEXT:    [[AND2:%.*]] = xor i1 [[X:%.*]], [[Y:%.*]]
934; CHECK-NEXT:    ret i1 [[AND2]]
935;
936  %and = select i1 %x, i1 %y, i1 false
937  %or = select i1 %x, i1 true, i1 %y
938  %nand = xor i1 %and, true
939  %and2 = select i1 %nand, i1 %or, i1 false
940  ret i1 %and2
941}
942
943define i1 @xor_commute1(i1 %x, i1 %y) {
944; CHECK-LABEL: @xor_commute1(
945; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false
946; CHECK-NEXT:    [[NAND:%.*]] = xor i1 [[AND]], true
947; CHECK-NEXT:    call void @use1(i1 [[NAND]])
948; CHECK-NEXT:    [[AND2:%.*]] = xor i1 [[X]], [[Y]]
949; CHECK-NEXT:    ret i1 [[AND2]]
950;
951  %and = select i1 %x, i1 %y, i1 false
952  %or = select i1 %y, i1 true, i1 %x
953  %nand = xor i1 %and, true
954  call void @use1(i1 %nand)
955  %and2 = select i1 %nand, i1 %or, i1 false
956  ret i1 %and2
957}
958
959define i1 @xor_commute2(i1 %x, i1 %y) {
960; CHECK-LABEL: @xor_commute2(
961; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false
962; CHECK-NEXT:    call void @use1(i1 [[AND]])
963; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
964; CHECK-NEXT:    call void @use1(i1 [[OR]])
965; CHECK-NEXT:    [[NAND:%.*]] = xor i1 [[AND]], true
966; CHECK-NEXT:    call void @use1(i1 [[NAND]])
967; CHECK-NEXT:    [[AND2:%.*]] = xor i1 [[X]], [[Y]]
968; CHECK-NEXT:    ret i1 [[AND2]]
969;
970  %and = select i1 %x, i1 %y, i1 false
971  call void @use1(i1 %and)
972  %or = select i1 %x, i1 true, i1 %y
973  call void @use1(i1 %or)
974  %nand = xor i1 %and, true
975  call void @use1(i1 %nand)
976  %and2 = select i1 %or, i1 %nand, i1 false
977  ret i1 %and2
978}
979
980define <2 x i1> @xor_commute3(<2 x i1> %x, <2 x i1> %y) {
981; CHECK-LABEL: @xor_commute3(
982; CHECK-NEXT:    [[AND2:%.*]] = xor <2 x i1> [[X:%.*]], [[Y:%.*]]
983; CHECK-NEXT:    ret <2 x i1> [[AND2]]
984;
985  %and = select <2 x i1> %x, <2 x i1> %y, <2 x i1> <i1 false, i1 false>
986  %or = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x
987  %nand = xor <2 x i1> %and, <i1 true, i1 true>
988  %and2 = select <2 x i1> %or, <2 x i1> %nand, <2 x i1> <i1 false, i1 false>
989  ret <2 x i1> %and2
990}
991
992define i1 @not_d_bools_commute00(i1 %c, i1 %x, i1 %y) {
993; CHECK-LABEL: @not_d_bools_commute00(
994; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[Y:%.*]], true
995; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 [[TMP1]]
996; CHECK-NEXT:    ret i1 [[R]]
997;
998  %y_c = or i1 %c, %y
999  %and2 = xor i1 %y_c, true
1000  %and1 = and i1 %c, %x
1001  %r = or i1 %and1, %and2
1002  ret i1 %r
1003}
1004
1005define i1 @not_d_bools_commute01(i1 %c, i1 %x, i1 %y) {
1006; CHECK-LABEL: @not_d_bools_commute01(
1007; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[Y:%.*]], true
1008; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 [[TMP1]]
1009; CHECK-NEXT:    ret i1 [[R]]
1010;
1011  %y_c = or i1 %y, %c
1012  %and2 = xor i1 %y_c, true
1013  %and1 = and i1 %c, %x
1014  %r = or i1 %and1, %and2
1015  ret i1 %r
1016}
1017
1018define i1 @not_d_bools_commute10(i1 %c, i1 %x, i1 %y) {
1019; CHECK-LABEL: @not_d_bools_commute10(
1020; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[Y:%.*]], true
1021; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 [[TMP1]]
1022; CHECK-NEXT:    ret i1 [[R]]
1023;
1024  %y_c = or i1 %c, %y
1025  %and2 = xor i1 %y_c, true
1026  %and1 = and i1 %x, %c
1027  %r = or i1 %and1, %and2
1028  ret i1 %r
1029}
1030
1031define i1 @not_d_bools_commute11(i1 %c, i1 %x, i1 %y) {
1032; CHECK-LABEL: @not_d_bools_commute11(
1033; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[Y:%.*]], true
1034; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 [[TMP1]]
1035; CHECK-NEXT:    ret i1 [[R]]
1036;
1037  %y_c = or i1 %y, %c
1038  %and2 = xor i1 %y_c, true
1039  %and1 = and i1 %x, %c
1040  %r = or i1 %and1, %and2
1041  ret i1 %r
1042}
1043
1044define <2 x i1> @not_d_bools_vector(<2 x i1> %c, <2 x i1> %x, <2 x i1> %y) {
1045; CHECK-LABEL: @not_d_bools_vector(
1046; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i1> [[Y:%.*]], splat (i1 true)
1047; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]], <2 x i1> [[TMP1]]
1048; CHECK-NEXT:    ret <2 x i1> [[R]]
1049;
1050  %y_c = or <2 x i1> %y, %c
1051  %and2 = xor <2 x i1> %y_c, <i1 true, i1 true>
1052  %and1 = and <2 x i1> %x, %c
1053  %r = or <2 x i1> %and1, %and2
1054  ret <2 x i1> %r
1055}
1056
1057define <2 x i1> @not_d_bools_vector_poison(<2 x i1> %c, <2 x i1> %x, <2 x i1> %y) {
1058; CHECK-LABEL: @not_d_bools_vector_poison(
1059; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i1> [[Y:%.*]], splat (i1 true)
1060; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]], <2 x i1> [[TMP1]]
1061; CHECK-NEXT:    ret <2 x i1> [[R]]
1062;
1063  %y_c = or <2 x i1> %y, %c
1064  %and2 = xor <2 x i1> %y_c, <i1 poison, i1 true>
1065  %and1 = and <2 x i1> %x, %c
1066  %r = or <2 x i1> %and1, %and2
1067  ret <2 x i1> %r
1068}
1069
1070define i32 @not_d_allSignBits(i32 %cond, i32 %tval, i32 %fval) {
1071; CHECK-LABEL: @not_d_allSignBits(
1072; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[FVAL:%.*]], -1
1073; CHECK-NEXT:    [[DOTNOT2:%.*]] = icmp slt i32 [[COND:%.*]], 0
1074; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[DOTNOT2]], i32 [[TVAL:%.*]], i32 [[TMP1]]
1075; CHECK-NEXT:    ret i32 [[SEL]]
1076;
1077  %bitmask = ashr i32 %cond, 31
1078  %a1 = and i32 %tval, %bitmask
1079  %or = or i32 %bitmask, %fval
1080  %a2 = xor i32 %or, -1
1081  %sel = or i32 %a1, %a2
1082  ret i32 %sel
1083}
1084
1085define i1 @not_d_bools_use2(i1 %c, i1 %x, i1 %y) {
1086; CHECK-LABEL: @not_d_bools_use2(
1087; CHECK-NEXT:    [[Y_C:%.*]] = or i1 [[C:%.*]], [[Y:%.*]]
1088; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[C]], [[X:%.*]]
1089; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[Y]], true
1090; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i1 [[X]], i1 [[TMP1]]
1091; CHECK-NEXT:    call void @use1(i1 [[AND1]])
1092; CHECK-NEXT:    call void @use1(i1 [[Y_C]])
1093; CHECK-NEXT:    ret i1 [[R]]
1094;
1095  %y_c = or i1 %c, %y
1096  %and2 = xor i1 %y_c, true
1097  %and1 = and i1 %c, %x
1098  %r = or i1 %and1, %and2
1099  call void @use1(i1 %and1)
1100  call void @use1(i1 %y_c)
1101  ret i1 %r
1102}
1103
1104; negative test: both op is not one-use
1105
1106define i1 @not_d_bools_negative_use2(i1 %c, i1 %x, i1 %y) {
1107; CHECK-LABEL: @not_d_bools_negative_use2(
1108; CHECK-NEXT:    [[Y_C:%.*]] = or i1 [[C:%.*]], [[Y:%.*]]
1109; CHECK-NEXT:    [[AND2:%.*]] = xor i1 [[Y_C]], true
1110; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[C]], [[X:%.*]]
1111; CHECK-NEXT:    [[R:%.*]] = or i1 [[AND1]], [[AND2]]
1112; CHECK-NEXT:    call void @use1(i1 [[AND2]])
1113; CHECK-NEXT:    call void @use1(i1 [[AND1]])
1114; CHECK-NEXT:    ret i1 [[R]]
1115;
1116  %y_c = or i1 %c, %y
1117  %and2 = xor i1 %y_c, true
1118  %and1 = and i1 %c, %x
1119  %r = or i1 %and1, %and2
1120  call void @use1(i1 %and2)
1121  call void @use1(i1 %and1)
1122  ret i1 %r
1123}
1124
1125; A & (~C | B)
1126define i1 @logical_and_or_with_not_op(i1 %a, i1 %b, i1 %c) {
1127; CHECK-LABEL: @logical_and_or_with_not_op(
1128; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true
1129; CHECK-NEXT:    [[OR:%.*]] = or i1 [[B:%.*]], [[NOT]]
1130; CHECK-NEXT:    [[AND:%.*]] = select i1 [[A:%.*]], i1 [[OR]], i1 false
1131; CHECK-NEXT:    ret i1 [[AND]]
1132;
1133  %not = xor i1 %c, true
1134  %or = or i1 %not, %b
1135  %and = select i1 %a, i1 %or, i1 zeroinitializer
1136  ret i1 %and
1137}
1138
1139; As logical_and_or_with_not_op but with C=A
1140; A & (~A | B) --> A & B
1141define i1 @logical_and_or_with_common_not_op_variant1(i1 %a, i1 %b) {
1142; CHECK-LABEL: @logical_and_or_with_common_not_op_variant1(
1143; CHECK-NEXT:    [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
1144; CHECK-NEXT:    ret i1 [[AND]]
1145;
1146  %not = xor i1 %a, true
1147  %or = or i1 %not, %b
1148  %and = select i1 %a, i1 %or, i1 zeroinitializer
1149  ret i1 %and
1150}
1151
1152; As logical_and_or_with_common_not_op_variant1 but operating on vectors
1153; A & (~A | B) --> A & B
1154define <2 x i1> @logical_and_or_with_common_not_op_variant2(<2 x i1> %a, <2 x i1> %b) {
1155; CHECK-LABEL: @logical_and_or_with_common_not_op_variant2(
1156; CHECK-NEXT:    [[AND:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
1157; CHECK-NEXT:    ret <2 x i1> [[AND]]
1158;
1159  %not = xor <2 x i1> %a, <i1 true, i1 true>
1160  %or = or <2 x i1> %not, %b
1161  %and = select <2 x i1> %a, <2 x i1> %or, <2 x i1> zeroinitializer
1162  ret <2 x i1> %and
1163}
1164
1165; As logical_and_or_with_common_not_op_variant1 but with "or" implemented as
1166; "select X, true, Y"
1167; A & (~A | B) --> A & B
1168define i1 @logical_and_or_with_common_not_op_variant3(i1 %a, i1 %b) {
1169; CHECK-LABEL: @logical_and_or_with_common_not_op_variant3(
1170; CHECK-NEXT:    [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
1171; CHECK-NEXT:    ret i1 [[AND]]
1172;
1173  %not = xor i1 %a, true
1174  %or = select i1 %not, i1 true, i1 %b
1175  %and = select i1 %a, i1 %or, i1 zeroinitializer
1176  ret i1 %and
1177}
1178
1179; As logical_and_or_with_common_not_op_variant3 but operating on vectors where
1180; each operand has other uses
1181; A & (~A | B) --> A & B
1182define <2 x i1> @logical_and_or_with_common_not_op_variant4(<2 x i1> %a, <2 x i1> %b) {
1183; CHECK-LABEL: @logical_and_or_with_common_not_op_variant4(
1184; CHECK-NEXT:    [[NOT:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true)
1185; CHECK-NEXT:    [[OR:%.*]] = select <2 x i1> [[NOT]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]]
1186; CHECK-NEXT:    [[AND:%.*]] = select <2 x i1> [[A]], <2 x i1> [[B]], <2 x i1> zeroinitializer
1187; CHECK-NEXT:    call void @use2(<2 x i1> [[A]])
1188; CHECK-NEXT:    call void @use2(<2 x i1> [[B]])
1189; CHECK-NEXT:    call void @use2(<2 x i1> [[OR]])
1190; CHECK-NEXT:    ret <2 x i1> [[AND]]
1191;
1192  %not = xor <2 x i1> %a, <i1 true, i1 true>
1193  %or = select <2 x i1> %not, <2 x i1> <i1 true, i1 true>, <2 x i1> %b
1194  %and = select <2 x i1> %a, <2 x i1> %or, <2 x i1> zeroinitializer
1195  call void @use2(<2 x i1> %a)
1196  call void @use2(<2 x i1> %b)
1197  call void @use2(<2 x i1> %or)
1198  ret <2 x i1> %and
1199}
1200
1201; As logical_and_or_with_common_not_op_variant1 but with |'s operands swapped
1202; A & (B | ~A) --> A & B
1203define i1 @logical_and_or_with_common_not_op_variant5(i1 %a) {
1204; CHECK-LABEL: @logical_and_or_with_common_not_op_variant5(
1205; CHECK-NEXT:    [[B:%.*]] = call i1 @gen()
1206; CHECK-NEXT:    [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B]], i1 false
1207; CHECK-NEXT:    ret i1 [[AND]]
1208;
1209  %b = call i1 @gen()
1210  %not = xor i1 %a, true
1211  %or = or i1 %b, %not
1212  %and = select i1 %a, i1 %or, i1 zeroinitializer
1213  ret i1 %and
1214}
1215
1216; A | (~C & B)
1217define i1 @logical_or_and_with_not_op(i1 %a, i1 %b, i1 %c) {
1218; CHECK-LABEL: @logical_or_and_with_not_op(
1219; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true
1220; CHECK-NEXT:    [[AND:%.*]] = and i1 [[B:%.*]], [[NOT]]
1221; CHECK-NEXT:    [[OR:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[AND]]
1222; CHECK-NEXT:    ret i1 [[OR]]
1223;
1224  %not = xor i1 %c, true
1225  %and = and i1 %not, %b
1226  %or = select i1 %a, i1 true, i1 %and
1227  ret i1 %or
1228}
1229
1230; As logical_or_and_with_not_op but with C=A
1231; A | (~A & B) --> A | B
1232define i1 @logical_or_and_with_common_not_op_variant1(i1 %a, i1 %b) {
1233; CHECK-LABEL: @logical_or_and_with_common_not_op_variant1(
1234; CHECK-NEXT:    [[OR:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
1235; CHECK-NEXT:    ret i1 [[OR]]
1236;
1237  %not = xor i1 %a, true
1238  %and = and i1 %not, %b
1239  %or = select i1 %a, i1 true, i1 %and
1240  ret i1 %or
1241}
1242
1243; As logical_or_and_with_common_not_op_variant1 but operating on vectors
1244; A | (~A & B) --> A | B
1245define <2 x i1> @logical_or_and_with_common_not_op_variant2(<2 x i1> %a, <2 x i1> %b) {
1246; CHECK-LABEL: @logical_or_and_with_common_not_op_variant2(
1247; CHECK-NEXT:    [[OR:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]]
1248; CHECK-NEXT:    ret <2 x i1> [[OR]]
1249;
1250  %not = xor <2 x i1> %a, <i1 true, i1 true>
1251  %and = and <2 x i1> %not, %b
1252  %or = select <2 x i1> %a, <2 x i1> <i1 true, i1 true>, <2 x i1> %and
1253  ret <2 x i1> %or
1254}
1255
1256; As logical_or_and_with_common_not_op_variant1 but with "and" implemented as
1257; "select X, Y, false"
1258; A | (~A & B) --> A | B
1259define i1 @logical_or_and_with_common_not_op_variant3(i1 %a, i1 %b) {
1260; CHECK-LABEL: @logical_or_and_with_common_not_op_variant3(
1261; CHECK-NEXT:    [[OR:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
1262; CHECK-NEXT:    ret i1 [[OR]]
1263;
1264  %not = xor i1 %a, true
1265  %and = select i1 %not, i1 %b, i1 false
1266  %or = select i1 %a, i1 true, i1 %and
1267  ret i1 %or
1268}
1269
1270; As logical_or_and_with_common_not_op_variant3 but operating on vectors where
1271; each operand has other uses
1272; A | (~A & B) --> A | B
1273define <2 x i1> @logical_or_and_with_common_not_op_variant4(<2 x i1> %a, <2 x i1> %b) {
1274; CHECK-LABEL: @logical_or_and_with_common_not_op_variant4(
1275; CHECK-NEXT:    [[NOT:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true)
1276; CHECK-NEXT:    [[AND:%.*]] = select <2 x i1> [[NOT]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
1277; CHECK-NEXT:    [[OR:%.*]] = select <2 x i1> [[A]], <2 x i1> splat (i1 true), <2 x i1> [[B]]
1278; CHECK-NEXT:    call void @use2(<2 x i1> [[A]])
1279; CHECK-NEXT:    call void @use2(<2 x i1> [[B]])
1280; CHECK-NEXT:    call void @use2(<2 x i1> [[AND]])
1281; CHECK-NEXT:    ret <2 x i1> [[OR]]
1282;
1283  %not = xor <2 x i1> %a, <i1 true, i1 true>
1284  %and = select <2 x i1> %not, <2 x i1> %b, <2 x i1> zeroinitializer
1285  %or = select <2 x i1> %a, <2 x i1> <i1 true, i1 true>, <2 x i1> %and
1286  call void @use2(<2 x i1> %a)
1287  call void @use2(<2 x i1> %b)
1288  call void @use2(<2 x i1> %and)
1289  ret <2 x i1> %or
1290}
1291
1292; As logical_or_and_with_common_not_op_variant1 but with &'s operands swapped
1293; A | (B & ~A) --> A | B
1294define i1 @logical_or_and_with_common_not_op_variant5(i1 %a) {
1295; CHECK-LABEL: @logical_or_and_with_common_not_op_variant5(
1296; CHECK-NEXT:    [[B:%.*]] = call i1 @gen()
1297; CHECK-NEXT:    [[OR:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B]]
1298; CHECK-NEXT:    ret i1 [[OR]]
1299;
1300  %b = call i1 @gen()
1301  %not = xor i1 %a, true
1302  %and = and i1 %b, %not
1303  %or = select i1 %a, i1 true, i1 %and
1304  ret i1 %or
1305}
1306
1307define i1 @reduce_logical_and1(i1 %a, i32 %b, i32 %c) {
1308; CHECK-LABEL: @reduce_logical_and1(
1309; CHECK-NEXT:  bb:
1310; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1311; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]]
1312; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[CMP1]], [[CMP]]
1313; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[A:%.*]], i1 [[TMP0]], i1 false
1314; CHECK-NEXT:    ret i1 [[AND2]]
1315;
1316bb:
1317  %cmp = icmp slt i32 %b, 6
1318  %cmp1 = icmp sgt i32 %c, %b
1319  %and1 = select i1 %a, i1 %cmp1, i1 false
1320  %and2 = select i1 %and1, i1 %cmp, i1 false
1321  ret i1 %and2
1322}
1323
1324define i1 @reduce_logical_and2(i1 %a, i1 %b, i1 %c) {
1325; CHECK-LABEL: @reduce_logical_and2(
1326; CHECK-NEXT:  bb:
1327; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[C:%.*]], true
1328; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[B:%.*]], [[TMP0]]
1329; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false
1330; CHECK-NEXT:    ret i1 [[AND2]]
1331;
1332bb:
1333  %or = xor i1 %c, %b
1334  %and1 = select i1 %a, i1 %or, i1 false
1335  %and2 = select i1 %and1, i1 %b, i1 false
1336  ret i1 %and2
1337}
1338
1339define i1 @reduce_logical_and3(i1 %a, i32 %b, i32 noundef %c) {
1340; CHECK-LABEL: @reduce_logical_and3(
1341; CHECK-NEXT:  bb:
1342; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1343; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]]
1344; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[CMP]], [[CMP1]]
1345; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[A:%.*]], i1 [[TMP0]], i1 false
1346; CHECK-NEXT:    ret i1 [[AND2]]
1347;
1348bb:
1349  %cmp = icmp slt i32 %b, 6
1350  %cmp1 = icmp sgt i32 %c, %b
1351  %and1 = select i1 %a, i1 %cmp, i1 false
1352  %and2 = select i1 %and1, i1 %cmp1, i1 false
1353  ret i1 %and2
1354}
1355
1356define i1 @reduce_logical_or1(i1 %a, i32 %b, i32 %c) {
1357; CHECK-LABEL: @reduce_logical_or1(
1358; CHECK-NEXT:  bb:
1359; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1360; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]]
1361; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[CMP1]], [[CMP]]
1362; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP0]]
1363; CHECK-NEXT:    ret i1 [[AND2]]
1364;
1365bb:
1366  %cmp = icmp slt i32 %b, 6
1367  %cmp1 = icmp sgt i32 %c, %b
1368  %and1 = select i1 %a, i1 true, i1 %cmp1
1369  %and2 = select i1 %and1, i1 true, i1 %cmp
1370  ret i1 %and2
1371}
1372
1373define i1 @reduce_logical_or2(i1 %a, i1 %b, i1 %c) {
1374; CHECK-LABEL: @reduce_logical_or2(
1375; CHECK-NEXT:  bb:
1376; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[C:%.*]], [[B:%.*]]
1377; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP0]]
1378; CHECK-NEXT:    ret i1 [[AND2]]
1379;
1380bb:
1381  %or = xor i1 %c, %b
1382  %and1 = select i1 %a, i1 true, i1 %or
1383  %and2 = select i1 %and1, i1 true, i1 %b
1384  ret i1 %and2
1385}
1386
1387define i1 @reduce_logical_or3(i1 %a, i32 %b, i32 noundef %c) {
1388; CHECK-LABEL: @reduce_logical_or3(
1389; CHECK-NEXT:  bb:
1390; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1391; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]]
1392; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[CMP]], [[CMP1]]
1393; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP0]]
1394; CHECK-NEXT:    ret i1 [[AND2]]
1395;
1396bb:
1397  %cmp = icmp slt i32 %b, 6
1398  %cmp1 = icmp sgt i32 %c, %b
1399  %and1 = select i1 %a, i1 true, i1 %cmp
1400  %and2 = select i1 %and1, i1 true, i1 %cmp1
1401  ret i1 %and2
1402}
1403
1404define i1 @reduce_logical_and_fail1(i1 %a, i32 %b, i32 %c) {
1405; CHECK-LABEL: @reduce_logical_and_fail1(
1406; CHECK-NEXT:  bb:
1407; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1408; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]]
1409; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[CMP]], i1 false
1410; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[AND1]], i1 [[CMP1]], i1 false
1411; CHECK-NEXT:    ret i1 [[AND2]]
1412;
1413bb:
1414  %cmp = icmp slt i32 %b, 6
1415  %cmp1 = icmp sgt i32 %c, %b
1416  %and1 = select i1 %a, i1 %cmp, i1 false
1417  %and2 = select i1 %and1, i1 %cmp1, i1 false
1418  ret i1 %and2
1419}
1420
1421define i1 @reduce_logical_and_fail2(i1 %a, i32 %b, i32 %c) {
1422; CHECK-LABEL: @reduce_logical_and_fail2(
1423; CHECK-NEXT:  bb:
1424; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1425; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], 7
1426; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[CMP]], i1 false
1427; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[AND1]], i1 [[CMP1]], i1 false
1428; CHECK-NEXT:    ret i1 [[AND2]]
1429;
1430bb:
1431  %cmp = icmp slt i32 %b, 6
1432  %cmp1 = icmp sgt i32 %c, 7
1433  %and1 = select i1 %a, i1 %cmp, i1 false
1434  %and2 = select i1 %and1, i1 %cmp1, i1 false
1435  ret i1 %and2
1436}
1437
1438define i1 @reduce_logical_or_fail1(i1 %a, i32 %b, i32 %c) {
1439; CHECK-LABEL: @reduce_logical_or_fail1(
1440; CHECK-NEXT:  bb:
1441; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1442; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]]
1443; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[CMP]]
1444; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 [[CMP1]]
1445; CHECK-NEXT:    ret i1 [[AND2]]
1446;
1447bb:
1448  %cmp = icmp slt i32 %b, 6
1449  %cmp1 = icmp sgt i32 %c, %b
1450  %and1 = select i1 %a, i1 true, i1 %cmp
1451  %and2 = select i1 %and1, i1 true, i1 %cmp1
1452  ret i1 %and2
1453}
1454
1455define i1 @reduce_logical_or_fail2(i1 %a, i32 %b, i32 %c) {
1456; CHECK-LABEL: @reduce_logical_or_fail2(
1457; CHECK-NEXT:  bb:
1458; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1459; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], 7
1460; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[CMP]]
1461; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 [[CMP1]]
1462; CHECK-NEXT:    ret i1 [[AND2]]
1463;
1464bb:
1465  %cmp = icmp slt i32 %b, 6
1466  %cmp1 = icmp sgt i32 %c, 7
1467  %and1 = select i1 %a, i1 true, i1 %cmp
1468  %and2 = select i1 %and1, i1 true, i1 %cmp1
1469  ret i1 %and2
1470}
1471
1472define i1 @reduce_logical_and_multiuse(i1 %a, i32 %b, i32 %c) {
1473; CHECK-LABEL: @reduce_logical_and_multiuse(
1474; CHECK-NEXT:  bb:
1475; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1476; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]]
1477; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[CMP1]], i1 false
1478; CHECK-NEXT:    call void @use1(i1 [[AND1]])
1479; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[AND1]], i1 [[CMP]], i1 false
1480; CHECK-NEXT:    ret i1 [[AND2]]
1481;
1482bb:
1483  %cmp = icmp slt i32 %b, 6
1484  %cmp1 = icmp sgt i32 %c, %b
1485  %and1 = select i1 %a, i1 %cmp1, i1 false
1486  call void @use1(i1 %and1)
1487  %and2 = select i1 %and1, i1 %cmp, i1 false
1488  ret i1 %and2
1489}
1490
1491define i1 @reduce_bitwise_and1(i1 %a, i32 %b, i32 %c) {
1492; CHECK-LABEL: @reduce_bitwise_and1(
1493; CHECK-NEXT:  bb:
1494; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1495; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]]
1496; CHECK-NEXT:    [[AND1:%.*]] = or i1 [[A:%.*]], [[CMP1]]
1497; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[AND1]], [[CMP]]
1498; CHECK-NEXT:    ret i1 [[AND2]]
1499;
1500bb:
1501  %cmp = icmp slt i32 %b, 6
1502  %cmp1 = icmp sgt i32 %c, %b
1503  %and1 = or i1 %a, %cmp1
1504  %and2 = select i1 %and1, i1 %cmp, i1 false
1505  ret i1 %and2
1506}
1507
1508define i1 @reduce_bitwise_and2(i1 %a, i32 %b, i32 %c) {
1509; CHECK-LABEL: @reduce_bitwise_and2(
1510; CHECK-NEXT:  bb:
1511; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6
1512; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]]
1513; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[CMP1]], i1 false
1514; CHECK-NEXT:    [[AND2:%.*]] = or i1 [[AND1]], [[CMP]]
1515; CHECK-NEXT:    ret i1 [[AND2]]
1516;
1517bb:
1518  %cmp = icmp slt i32 %b, 6
1519  %cmp1 = icmp sgt i32 %c, %b
1520  %and1 = select i1 %a, i1 %cmp1, i1 false
1521  %and2 = or i1 %and1, %cmp
1522  ret i1 %and2
1523}
1524
1525define i1 @test_logical_and_icmp_samesign(i8 %x) {
1526; CHECK-LABEL: @test_logical_and_icmp_samesign(
1527; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[X:%.*]], 9
1528; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult i8 [[X]], 11
1529; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1530; CHECK-NEXT:    ret i1 [[AND]]
1531;
1532  %cmp1 = icmp ne i8 %x, 9
1533  %cmp2 = icmp samesign ult i8 %x, 11
1534  %and = select i1 %cmp1, i1 %cmp2, i1 false
1535  ret i1 %and
1536}
1537
1538define i1 @test_logical_or_icmp_samesign(i8 %x) {
1539; CHECK-LABEL: @test_logical_or_icmp_samesign(
1540; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X:%.*]], -9
1541; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult i8 [[X]], -11
1542; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
1543; CHECK-NEXT:    ret i1 [[OR]]
1544;
1545  %cmp1 = icmp eq i8 %x, -9
1546  %cmp2 = icmp samesign ult i8 %x, -11
1547  %or = select i1 %cmp1, i1 true, i1 %cmp2
1548  ret i1 %or
1549}
1550
1551define i1 @test_double_logical_and_icmp_samesign1(i1 %cond, i32 %y) {
1552; CHECK-LABEL: @test_double_logical_and_icmp_samesign1(
1553; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult i32 [[Y:%.*]], 4
1554; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[SEL1:%.*]], i1 [[CMP2]], i1 false
1555; CHECK-NEXT:    ret i1 [[SEL2]]
1556;
1557  %cmp1 = icmp ne i32 %y, 5
1558  %sel1 = select i1 %cond, i1 %cmp1, i1 false
1559  %cmp2 = icmp samesign ult i32 %y, 4
1560  %sel2 = select i1 %sel1, i1 %cmp2, i1 false
1561  ret i1 %sel2
1562}
1563
1564define i1 @test_double_logical_and_icmp_samesign2(i1 %cond, i32 %y) {
1565; CHECK-LABEL: @test_double_logical_and_icmp_samesign2(
1566; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[Y:%.*]], -65536
1567; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[TMP1]], 1048576
1568; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[SEL1:%.*]], i1 [[CMP2]], i1 false
1569; CHECK-NEXT:    ret i1 [[SEL2]]
1570;
1571  %cmp1 = icmp samesign ugt i32 %y, 65535
1572  %sel1 = select i1 %cond, i1 %cmp1, i1 false
1573  %cmp2 = icmp samesign ult i32 %y, 1114112
1574  %sel2 = select i1 %sel1, i1 %cmp2, i1 false
1575  ret i1 %sel2
1576}
1577
1578define <2 x i1> @test_logical_and_icmp_samesign_vec(<2 x i8> %x) {
1579; CHECK-LABEL: @test_logical_and_icmp_samesign_vec(
1580; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], splat (i8 9)
1581; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult <2 x i8> [[X]], splat (i8 11)
1582; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[CMP1]], [[CMP2]]
1583; CHECK-NEXT:    ret <2 x i1> [[AND]]
1584;
1585  %cmp1 = icmp ne <2 x i8> %x, splat(i8 9)
1586  %cmp2 = icmp samesign ult <2 x i8> %x, splat(i8 11)
1587  %and = select <2 x i1> %cmp1, <2 x i1> %cmp2, <2 x i1> zeroinitializer
1588  ret <2 x i1> %and
1589}
1590
1591define <2 x i1> @test_logical_and_icmp_samesign_vec_with_poison_cond(<2 x i8> %x) {
1592; CHECK-LABEL: @test_logical_and_icmp_samesign_vec_with_poison_cond(
1593; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 9, i8 poison>
1594; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult <2 x i8> [[X]], splat (i8 11)
1595; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[CMP1]], [[CMP2]]
1596; CHECK-NEXT:    ret <2 x i1> [[AND]]
1597;
1598  %cmp1 = icmp ne <2 x i8> %x, <i8 9, i8 poison>
1599  %cmp2 = icmp samesign ult <2 x i8> %x, splat(i8 11)
1600  %and = select <2 x i1> %cmp1, <2 x i1> %cmp2, <2 x i1> zeroinitializer
1601  ret <2 x i1> %and
1602}
1603
1604define i1 @test_logical_and_icmp_samesign_do_not_imply(i8 %x) {
1605; CHECK-LABEL: @test_logical_and_icmp_samesign_do_not_imply(
1606; CHECK-NEXT:    [[AND:%.*]] = icmp ult i8 [[X:%.*]], 11
1607; CHECK-NEXT:    ret i1 [[AND]]
1608;
1609  %cmp1 = icmp ne i8 %x, -9
1610  %cmp2 = icmp samesign ult i8 %x, 11
1611  %and = select i1 %cmp1, i1 %cmp2, i1 false
1612  ret i1 %and
1613}
1614
1615define i1 @test_logical_and_icmp_no_samesign(i8 %x) {
1616; CHECK-LABEL: @test_logical_and_icmp_no_samesign(
1617; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[X:%.*]], 9
1618; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i8 [[X]], 11
1619; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1620; CHECK-NEXT:    ret i1 [[AND]]
1621;
1622  %cmp1 = icmp ne i8 %x, 9
1623  %cmp2 = icmp ult i8 %x, 11
1624  %and = select i1 %cmp1, i1 %cmp2, i1 false
1625  ret i1 %and
1626}
1627
1628; Negative tests
1629
1630define <2 x i1> @test_logical_and_icmp_samesign_vec_with_poison_tv(<2 x i8> %x) {
1631; CHECK-LABEL: @test_logical_and_icmp_samesign_vec_with_poison_tv(
1632; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], splat (i8 9)
1633; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult <2 x i8> [[X]], <i8 11, i8 poison>
1634; CHECK-NEXT:    [[AND:%.*]] = select <2 x i1> [[CMP1]], <2 x i1> [[CMP2]], <2 x i1> zeroinitializer
1635; CHECK-NEXT:    ret <2 x i1> [[AND]]
1636;
1637  %cmp1 = icmp ne <2 x i8> %x, splat(i8 9)
1638  %cmp2 = icmp samesign ult <2 x i8> %x, <i8 11, i8 poison>
1639  %and = select <2 x i1> %cmp1, <2 x i1> %cmp2, <2 x i1> zeroinitializer
1640  ret <2 x i1> %and
1641}
1642