1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
8 declare void @use2(<2 x i1>)
10 define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) {
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
25 define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) {
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
40 define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) {
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
55 define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) {
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
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
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
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
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
147 define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) {
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
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
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
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
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
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
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
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
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
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
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
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]]
378 %and1 = and i1 %not, %a
379 %and2 = and i1 %c, %b
380 %or = or i1 %and1, %and2
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]]
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
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]]
407 %and1 = and i1 %not, %a
408 %and2 = and i1 %c, %b
409 %or = or i1 %and1, %and2
410 %xor = xor i1 %or, %and1
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]]
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
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]]
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
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]]
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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>
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]]
999 %and2 = xor i1 %y_c, true
1000 %and1 = and i1 %c, %x
1001 %r = or i1 %and1, %and2
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]]
1012 %and2 = xor i1 %y_c, true
1013 %and1 = and i1 %c, %x
1014 %r = or i1 %and1, %and2
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]]
1025 %and2 = xor i1 %y_c, true
1026 %and1 = and i1 %x, %c
1027 %r = or i1 %and1, %and2
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]]
1038 %and2 = xor i1 %y_c, true
1039 %and1 = and i1 %x, %c
1040 %r = or i1 %and1, %and2
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
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
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
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]]
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)
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]]
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)
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
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
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
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
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)
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]]
1210 %not = xor i1 %a, true
1211 %or = or i1 %b, %not
1212 %and = select i1 %a, i1 %or, i1 zeroinitializer
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
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
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
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
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)
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]]
1301 %not = xor i1 %a, true
1302 %and = and i1 %b, %not
1303 %or = select i1 %a, i1 true, i1 %and
1307 define i1 @reduce_logical_and1(i1 %a, i32 %b, i32 %c) {
1308 ; CHECK-LABEL: @reduce_logical_and1(
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
1324 define i1 @reduce_logical_and2(i1 %a, i1 %b, i1 %c) {
1325 ; CHECK-LABEL: @reduce_logical_and2(
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]]
1334 %and1 = select i1 %a, i1 %or, i1 false
1335 %and2 = select i1 %and1, i1 %b, i1 false
1339 define i1 @reduce_logical_and3(i1 %a, i32 %b, i32 noundef %c) {
1340 ; CHECK-LABEL: @reduce_logical_and3(
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
1356 define i1 @reduce_logical_or1(i1 %a, i32 %b, i32 %c) {
1357 ; CHECK-LABEL: @reduce_logical_or1(
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
1373 define i1 @reduce_logical_or2(i1 %a, i1 %b, i1 %c) {
1374 ; CHECK-LABEL: @reduce_logical_or2(
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]]
1382 %and1 = select i1 %a, i1 true, i1 %or
1383 %and2 = select i1 %and1, i1 true, i1 %b
1387 define i1 @reduce_logical_or3(i1 %a, i32 %b, i32 noundef %c) {
1388 ; CHECK-LABEL: @reduce_logical_or3(
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
1404 define i1 @reduce_logical_and_fail1(i1 %a, i32 %b, i32 %c) {
1405 ; CHECK-LABEL: @reduce_logical_and_fail1(
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
1421 define i1 @reduce_logical_and_fail2(i1 %a, i32 %b, i32 %c) {
1422 ; CHECK-LABEL: @reduce_logical_and_fail2(
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
1438 define i1 @reduce_logical_or_fail1(i1 %a, i32 %b, i32 %c) {
1439 ; CHECK-LABEL: @reduce_logical_or_fail1(
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
1455 define i1 @reduce_logical_or_fail2(i1 %a, i32 %b, i32 %c) {
1456 ; CHECK-LABEL: @reduce_logical_or_fail2(
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
1472 define i1 @reduce_logical_and_multiuse(i1 %a, i32 %b, i32 %c) {
1473 ; CHECK-LABEL: @reduce_logical_and_multiuse(
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
1491 define i1 @reduce_bitwise_and1(i1 %a, i32 %b, i32 %c) {
1492 ; CHECK-LABEL: @reduce_bitwise_and1(
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
1508 define i1 @reduce_bitwise_and2(i1 %a, i32 %b, i32 %c) {
1509 ; CHECK-LABEL: @reduce_bitwise_and2(
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