Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / logical-select.ll
blob6e2ed6bf796d08f2d86702687b0d570aef28bfa1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare i1 @gen()
6 declare void @use(i8)
7 declare void @use1(i1)
8 declare void @use2(<2 x i1>)
10 define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) {
11 ; CHECK-LABEL: @foo(
12 ; CHECK-NEXT:    [[E:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
13 ; CHECK-NEXT:    [[J:%.*]] = select i1 [[E]], i32 [[C:%.*]], i32 [[D:%.*]]
14 ; CHECK-NEXT:    ret i32 [[J]]
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
25 define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) {
26 ; CHECK-LABEL: @bar(
27 ; CHECK-NEXT:    [[E:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
28 ; CHECK-NEXT:    [[J:%.*]] = select i1 [[E]], i32 [[C:%.*]], i32 [[D:%.*]]
29 ; CHECK-NEXT:    ret i32 [[J]]
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
40 define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) {
41 ; CHECK-LABEL: @goo(
42 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
43 ; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0]], i32 [[C:%.*]], i32 [[D:%.*]]
44 ; CHECK-NEXT:    ret i32 [[T3]]
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
55 define 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]]
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
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.
73 define 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]]
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
90 ; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this.
92 define 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]]
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
109 ; TODO: Should fcmp have the same sort of predicate canonicalization as icmp?
111 define 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]]
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
128 ; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this.
130 define <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]]
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
147 define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) {
148 ; CHECK-LABEL: @par(
149 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
150 ; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0]], i32 [[C:%.*]], i32 [[D:%.*]]
151 ; CHECK-NEXT:    ret i32 [[T3]]
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
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.
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.
171 define <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]]
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
193 define <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]]
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
215 define <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]]
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
237 define <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]]
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
259 define <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]]
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
281 define <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]]
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
303 define <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]]
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
325 define <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]]
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
347 define <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> [[BC1]], [[A:%.*]]
352 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64>
353 ; CHECK-NEXT:    [[BC2:%.*]] = xor <2 x i64> [[TMP1]], <i64 -1, i64 -1>
354 ; CHECK-NEXT:    [[AND2:%.*]] = and <2 x i64> [[BC2]], [[B:%.*]]
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]]
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
372 define 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]]
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
384 define 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]]
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
396 ; Form a select if we know we can replace 2 simple logic ops.
398 define 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 [[NOT]], [[A:%.*]]
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]]
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
414 define 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]]
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
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.
433 define 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]]
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
447 define 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]]
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
466 define <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]]
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
478 define <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]]
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
490 define 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]]
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
507 define <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]]
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
526 ; Inverted 'and' constants mean this is a select which is canonicalized to a shuffle.
528 define <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]]
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
539 define <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]]
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
550 ; The mask elements must be inverted for this to be a select.
552 define <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]]
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
565 define <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]]
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
578 ; The inverted constants may be operands of xor instructions.
580 define <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]]
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
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.
598 define <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]]
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
617 ; The 'ashr' guarantees that we have a bitmask, so this is select with truncated condition.
619 define 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]]
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
636 define <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]]
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
653 ; Negative test - make sure that bitcasts from FP do not cause a crash.
655 define <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]]
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
676 define <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]]
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
708 define <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]]
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
724 ; Bitcast of condition from narrow source element type can be converted to select.
726 define <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]]
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
743 define <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]]
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
760 ; Negative test - bitcast of condition from wide source element type cannot be converted to select.
762 define <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]], <i3 -1, i3 -1, i3 -1, i3 -1, i3 -1, i3 -1, i3 -1, i3 -1>
768 ; CHECK-NEXT:    [[T11:%.*]] = and <8 x i3> [[C]], [[NOTT9]]
769 ; CHECK-NEXT:    [[T12:%.*]] = and <8 x i3> [[T9]], [[D:%.*]]
770 ; CHECK-NEXT:    [[R:%.*]] = or disjoint <8 x i3> [[T11]], [[T12]]
771 ; CHECK-NEXT:    ret <8 x i3> [[R]]
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
783 define <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]]
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
804 ; Condition doesn't have to be a bool vec - just all signbits.
806 define <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]]
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
828 ; Don't crash on invalid type for compute signbits.
830 define <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]], <i64 -1, i64 -1>
834 ; CHECK-NEXT:    [[T11:%.*]] = and <2 x i64> [[NOTT9]], [[C:%.*]]
835 ; CHECK-NEXT:    [[T12:%.*]] = and <2 x i64> [[T9]], [[D:%.*]]
836 ; CHECK-NEXT:    [[R:%.*]] = or disjoint <2 x i64> [[T11]], [[T12]]
837 ; CHECK-NEXT:    ret <2 x i64> [[R]]
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
847 ; Wider source type would be ok except poison could leak across elements.
849 define <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]], <i64 -1, i64 -1>
854 ; CHECK-NEXT:    [[T11:%.*]] = and <2 x i64> [[NOTT9]], [[C:%.*]]
855 ; CHECK-NEXT:    [[T12:%.*]] = and <2 x i64> [[T9]], [[D:%.*]]
856 ; CHECK-NEXT:    [[R:%.*]] = or disjoint <2 x i64> [[T11]], [[T12]]
857 ; CHECK-NEXT:    ret <2 x i64> [[R]]
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
868 ; Converting integer logic ops to vector select is allowed.
870 define 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]]
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
887 ; Peek through bitcasts and sexts to find negated bool condition.
889 define <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]]
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
908 ; Extra uses may prevent other transforms from creating the canonical patterns.
910 define 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]]
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
931 define 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]]
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
943 define 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]]
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
959 define 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]]
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
980 define <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]]
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
992 define 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]]
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
1005 define 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]]
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
1018 define 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]]
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
1031 define 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]]
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
1044 define <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:%.*]], <i1 true, 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]]
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
1057 define <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:%.*]], <i1 true, 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]]
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
1070 define 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]]
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
1085 define 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]]
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
1104 ; negative test: both op is not one-use
1106 define 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]]
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
1125 ; A & (~C | B)
1126 define 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 [[NOT]], [[B:%.*]]
1130 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[A:%.*]], i1 [[OR]], i1 false
1131 ; CHECK-NEXT:    ret i1 [[AND]]
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
1139 ; As logical_and_or_with_not_op but with C=A
1140 ; A & (~A | B) --> A & B
1141 define 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]]
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
1152 ; As logical_and_or_with_common_not_op_variant1 but operating on vectors
1153 ; A & (~A | B) --> A & B
1154 define <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]]
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
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
1168 define 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]]
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
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
1182 define <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:%.*]], <i1 true, i1 true>
1185 ; CHECK-NEXT:    [[OR:%.*]] = select <2 x i1> [[NOT]], <2 x i1> <i1 true, 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]]
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
1201 ; As logical_and_or_with_common_not_op_variant1 but with |'s operands swapped
1202 ; A & (B | ~A) --> A & B
1203 define 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]]
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
1216 ; A | (~C & B)
1217 define 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 [[NOT]], [[B:%.*]]
1221 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[AND]]
1222 ; CHECK-NEXT:    ret i1 [[OR]]
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
1230 ; As logical_or_and_with_not_op but with C=A
1231 ; A | (~A & B) --> A | B
1232 define 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]]
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
1243 ; As logical_or_and_with_common_not_op_variant1 but operating on vectors
1244 ; A | (~A & B) --> A | B
1245 define <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> <i1 true, i1 true>, <2 x i1> [[B:%.*]]
1248 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
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
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
1259 define 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]]
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
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
1273 define <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:%.*]], <i1 true, 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> <i1 true, 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]]
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
1292 ; As logical_or_and_with_common_not_op_variant1 but with &'s operands swapped
1293 ; A | (B & ~A) --> A | B
1294 define 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]]
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
1307 define 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]]
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
1324 define 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:    [[B:%.*]] = and i1 [[TMP0]], [[B1:%.*]]
1329 ; CHECK-NEXT:    [[AND3:%.*]] = select i1 [[AND2:%.*]], i1 [[B]], i1 false
1330 ; CHECK-NEXT:    ret i1 [[AND3]]
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
1339 define 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]]
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
1356 define 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]]
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
1373 define i1 @reduce_logical_or2(i1 %a, i1 %b, i1 %c) {
1374 ; CHECK-LABEL: @reduce_logical_or2(
1375 ; CHECK-NEXT:  bb:
1376 ; CHECK-NEXT:    [[B:%.*]] = or i1 [[C:%.*]], [[B1:%.*]]
1377 ; CHECK-NEXT:    [[AND3:%.*]] = select i1 [[AND2:%.*]], i1 true, i1 [[B]]
1378 ; CHECK-NEXT:    ret i1 [[AND3]]
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
1387 define 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]]
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
1404 define 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]]
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
1421 define 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]]
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
1438 define 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]]
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
1455 define 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]]
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
1472 define 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]]
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
1491 define 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 [[CMP1]], [[A:%.*]]
1497 ; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[AND1]], [[CMP]]
1498 ; CHECK-NEXT:    ret i1 [[AND2]]
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
1508 define 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]]
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