[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstCombine / masked-merge-and-of-ors.ll
blob48346ad6505b1b6482e410888e3cfffa2ad53363
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; https://bugs.llvm.org/show_bug.cgi?id=6773
6 ; Pattern:
7 ;   (x | ~m) & (y & m)
8 ; Should be transformed into:
9 ;   (x & m) | (y & ~m)
10 ; And then into:
11 ;   ((x ^ y) & m) ^ y
13 ; ============================================================================ ;
14 ; Most basic positive tests
15 ; ============================================================================ ;
17 define i32 @p(i32 %x, i32 %y, i32 %m) {
18 ; CHECK-LABEL: @p(
19 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
20 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
21 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
22 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
23 ; CHECK-NEXT:    ret i32 [[RET]]
25   %neg = xor i32 %m, -1
26   %or = or i32 %neg, %x
27   %or1 = or i32 %y, %m
28   %ret = and i32 %or, %or1
29   ret i32 %ret
32 define <2 x i32> @p_splatvec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %m) {
33 ; CHECK-LABEL: @p_splatvec(
34 ; CHECK-NEXT:    [[NEG:%.*]] = xor <2 x i32> [[M:%.*]], <i32 -1, i32 -1>
35 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[NEG]], [[X:%.*]]
36 ; CHECK-NEXT:    [[OR1:%.*]] = or <2 x i32> [[Y:%.*]], [[M]]
37 ; CHECK-NEXT:    [[RET:%.*]] = and <2 x i32> [[OR]], [[OR1]]
38 ; CHECK-NEXT:    ret <2 x i32> [[RET]]
40   %neg = xor <2 x i32> %m, <i32 -1, i32 -1>
41   %or = or <2 x i32> %neg, %x
42   %or1 = or <2 x i32> %y, %m
43   %ret = and <2 x i32> %or, %or1
44   ret <2 x i32> %ret
47 define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> %m) {
48 ; CHECK-LABEL: @p_vec_undef(
49 ; CHECK-NEXT:    [[NEG:%.*]] = xor <3 x i32> [[M:%.*]], <i32 -1, i32 undef, i32 -1>
50 ; CHECK-NEXT:    [[OR:%.*]] = or <3 x i32> [[NEG]], [[X:%.*]]
51 ; CHECK-NEXT:    [[OR1:%.*]] = or <3 x i32> [[Y:%.*]], [[M]]
52 ; CHECK-NEXT:    [[RET:%.*]] = and <3 x i32> [[OR]], [[OR1]]
53 ; CHECK-NEXT:    ret <3 x i32> [[RET]]
55   %neg = xor <3 x i32> %m, <i32 -1, i32 undef, i32 -1>
56   %or = or <3 x i32> %neg, %x
57   %or1 = or <3 x i32> %y, %m
58   %ret = and <3 x i32> %or, %or1
59   ret <3 x i32> %ret
62 ; ============================================================================ ;
63 ; Constant mask.
64 ; ============================================================================ ;
66 define i32 @p_constmask(i32 %x, i32 %y) {
67 ; CHECK-LABEL: @p_constmask(
68 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -65281
69 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], 65280
70 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
71 ; CHECK-NEXT:    ret i32 [[RET]]
73   %or = or i32 %x, -65281
74   %or1 = or i32 %y, 65280
75   %ret = and i32 %or, %or1
76   ret i32 %ret
79 define <2 x i32> @p_constmask_splatvec(<2 x i32> %x, <2 x i32> %y) {
80 ; CHECK-LABEL: @p_constmask_splatvec(
81 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[X:%.*]], <i32 -65281, i32 -65281>
82 ; CHECK-NEXT:    [[OR1:%.*]] = or <2 x i32> [[Y:%.*]], <i32 65280, i32 65280>
83 ; CHECK-NEXT:    [[RET:%.*]] = and <2 x i32> [[OR]], [[OR1]]
84 ; CHECK-NEXT:    ret <2 x i32> [[RET]]
86   %or = or <2 x i32> %x, <i32 -65281, i32 -65281>
87   %or1 = or <2 x i32> %y, <i32 65280, i32 65280>
88   %ret = and <2 x i32> %or, %or1
89   ret <2 x i32> %ret
92 define <2 x i32> @p_constmask_vec(<2 x i32> %x, <2 x i32> %y) {
93 ; CHECK-LABEL: @p_constmask_vec(
94 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[X:%.*]], <i32 -65281, i32 -16776961>
95 ; CHECK-NEXT:    [[OR1:%.*]] = or <2 x i32> [[Y:%.*]], <i32 65280, i32 16776960>
96 ; CHECK-NEXT:    [[RET:%.*]] = and <2 x i32> [[OR]], [[OR1]]
97 ; CHECK-NEXT:    ret <2 x i32> [[RET]]
99   %or = or <2 x i32> %x, <i32 -65281, i32 -16776961>
100   %or1 = or <2 x i32> %y, <i32 65280, i32 16776960>
101   %ret = and <2 x i32> %or, %or1
102   ret <2 x i32> %ret
105 define <3 x i32> @p_constmask_vec_undef(<3 x i32> %x, <3 x i32> %y) {
106 ; CHECK-LABEL: @p_constmask_vec_undef(
107 ; CHECK-NEXT:    [[OR:%.*]] = or <3 x i32> [[X:%.*]], <i32 -65281, i32 undef, i32 -65281>
108 ; CHECK-NEXT:    [[OR1:%.*]] = or <3 x i32> [[Y:%.*]], <i32 65280, i32 undef, i32 65280>
109 ; CHECK-NEXT:    [[RET:%.*]] = and <3 x i32> [[OR]], [[OR1]]
110 ; CHECK-NEXT:    ret <3 x i32> [[RET]]
112   %or = or <3 x i32> %x, <i32 -65281, i32 undef, i32 -65281>
113   %or1 = or <3 x i32> %y, <i32 65280, i32 undef, i32 65280>
114   %ret = and <3 x i32> %or, %or1
115   ret <3 x i32> %ret
118 ; ============================================================================ ;
119 ; Commutativity.
120 ; ============================================================================ ;
122 ; Used to make sure that the IR complexity sorting does not interfere.
123 declare i32 @gen32()
125 define i32 @p_commutative0(i32 %x, i32 %y, i32 %m) {
126 ; CHECK-LABEL: @p_commutative0(
127 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
128 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
129 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
130 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
131 ; CHECK-NEXT:    ret i32 [[RET]]
133   %neg = xor i32 %m, -1
134   %or = or i32 %x, %neg ; swapped order
135   %or1 = or i32 %y, %m
136   %ret = and i32 %or, %or1
137   ret i32 %ret
140 define i32 @p_commutative1(i32 %x, i32 %m) {
141 ; CHECK-LABEL: @p_commutative1(
142 ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
143 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
144 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
145 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[M]]
146 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
147 ; CHECK-NEXT:    ret i32 [[RET]]
149   %y = call i32 @gen32()
150   %neg = xor i32 %m, -1
151   %or = or i32 %neg, %x
152   %or1 = or i32 %m, %y; swapped order
153   %ret = and i32 %or, %or1
154   ret i32 %ret
157 define i32 @p_commutative2(i32 %x, i32 %y, i32 %m) {
158 ; CHECK-LABEL: @p_commutative2(
159 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
160 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
161 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
162 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR1]], [[OR]]
163 ; CHECK-NEXT:    ret i32 [[RET]]
165   %neg = xor i32 %m, -1
166   %or = or i32 %neg, %x
167   %or1 = or i32 %y, %m
168   %ret = and i32 %or1, %or ; swapped order
169   ret i32 %ret
172 define i32 @p_commutative3(i32 %x, i32 %m) {
173 ; CHECK-LABEL: @p_commutative3(
174 ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
175 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
176 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
177 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[M]]
178 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
179 ; CHECK-NEXT:    ret i32 [[RET]]
181   %y = call i32 @gen32()
182   %neg = xor i32 %m, -1
183   %or = or i32 %x, %neg ; swapped order
184   %or1 = or i32 %m, %y; swapped order
185   %ret = and i32 %or, %or1
186   ret i32 %ret
189 define i32 @p_commutative4(i32 %x, i32 %y, i32 %m) {
190 ; CHECK-LABEL: @p_commutative4(
191 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
192 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
193 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
194 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR1]], [[OR]]
195 ; CHECK-NEXT:    ret i32 [[RET]]
197   %neg = xor i32 %m, -1
198   %or = or i32 %x, %neg ; swapped order
199   %or1 = or i32 %y, %m
200   %ret = and i32 %or1, %or ; swapped order
201   ret i32 %ret
204 define i32 @p_commutative5(i32 %x, i32 %m) {
205 ; CHECK-LABEL: @p_commutative5(
206 ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
207 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
208 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
209 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[M]]
210 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR1]], [[OR]]
211 ; CHECK-NEXT:    ret i32 [[RET]]
213   %y = call i32 @gen32()
214   %neg = xor i32 %m, -1
215   %or = or i32 %neg, %x
216   %or1 = or i32 %m, %y; swapped order
217   %ret = and i32 %or1, %or ; swapped order
218   ret i32 %ret
221 define i32 @p_commutative6(i32 %x, i32 %m) {
222 ; CHECK-LABEL: @p_commutative6(
223 ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
224 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
225 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
226 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[M]]
227 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR1]], [[OR]]
228 ; CHECK-NEXT:    ret i32 [[RET]]
230   %y = call i32 @gen32()
231   %neg = xor i32 %m, -1
232   %or = or i32 %x, %neg ; swapped order
233   %or1 = or i32 %m, %y; swapped order
234   %ret = and i32 %or1, %or ; swapped order
235   ret i32 %ret
238 define i32 @p_constmask_commutative(i32 %x, i32 %y) {
239 ; CHECK-LABEL: @p_constmask_commutative(
240 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -65281
241 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], 65280
242 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR1]], [[OR]]
243 ; CHECK-NEXT:    ret i32 [[RET]]
245   %or = or i32 %x, -65281
246   %or1 = or i32 %y, 65280
247   %ret = and i32 %or1, %or ; swapped order
248   ret i32 %ret
251 ; ============================================================================ ;
252 ; Negative tests. Should not be folded.
253 ; ============================================================================ ;
255 ; One use only.
257 declare void @use32(i32)
259 define i32 @n0_oneuse_of_neg_is_ok_0(i32 %x, i32 %y, i32 %m) {
260 ; CHECK-LABEL: @n0_oneuse_of_neg_is_ok_0(
261 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
262 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
263 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
264 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
265 ; CHECK-NEXT:    call void @use32(i32 [[NEG]])
266 ; CHECK-NEXT:    ret i32 [[RET]]
268   %neg = xor i32 %m, -1
269   %or = or i32 %neg, %x
270   %or1 = or i32 %y, %m
271   %ret = and i32 %or, %or1
272   call void @use32(i32 %neg)
273   ret i32 %ret
276 define i32 @n0_oneuse_1(i32 %x, i32 %y, i32 %m) {
277 ; CHECK-LABEL: @n0_oneuse_1(
278 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
279 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
280 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
281 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
282 ; CHECK-NEXT:    call void @use32(i32 [[OR]])
283 ; CHECK-NEXT:    ret i32 [[RET]]
285   %neg = xor i32 %m, -1
286   %or = or i32 %neg, %x
287   %or1 = or i32 %y, %m
288   %ret = and i32 %or, %or1
289   call void @use32(i32 %or)
290   ret i32 %ret
293 define i32 @n0_oneuse_2(i32 %x, i32 %y, i32 %m) {
294 ; CHECK-LABEL: @n0_oneuse_2(
295 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
296 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
297 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
298 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
299 ; CHECK-NEXT:    call void @use32(i32 [[OR1]])
300 ; CHECK-NEXT:    ret i32 [[RET]]
302   %neg = xor i32 %m, -1
303   %or = or i32 %neg, %x
304   %or1 = or i32 %y, %m
305   %ret = and i32 %or, %or1
306   call void @use32(i32 %or1)
307   ret i32 %ret
310 define i32 @n0_oneuse_3(i32 %x, i32 %y, i32 %m) {
311 ; CHECK-LABEL: @n0_oneuse_3(
312 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
313 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
314 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
315 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
316 ; CHECK-NEXT:    call void @use32(i32 [[NEG]])
317 ; CHECK-NEXT:    call void @use32(i32 [[OR]])
318 ; CHECK-NEXT:    ret i32 [[RET]]
320   %neg = xor i32 %m, -1
321   %or = or i32 %neg, %x
322   %or1 = or i32 %y, %m
323   %ret = and i32 %or, %or1
324   call void @use32(i32 %neg)
325   call void @use32(i32 %or)
326   ret i32 %ret
329 define i32 @n0_oneuse_4(i32 %x, i32 %y, i32 %m) {
330 ; CHECK-LABEL: @n0_oneuse_4(
331 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
332 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
333 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
334 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
335 ; CHECK-NEXT:    call void @use32(i32 [[NEG]])
336 ; CHECK-NEXT:    call void @use32(i32 [[OR1]])
337 ; CHECK-NEXT:    ret i32 [[RET]]
339   %neg = xor i32 %m, -1
340   %or = or i32 %neg, %x
341   %or1 = or i32 %y, %m
342   %ret = and i32 %or, %or1
343   call void @use32(i32 %neg)
344   call void @use32(i32 %or1)
345   ret i32 %ret
348 define i32 @n0_oneuse_5(i32 %x, i32 %y, i32 %m) {
349 ; CHECK-LABEL: @n0_oneuse_5(
350 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
351 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
352 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
353 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
354 ; CHECK-NEXT:    call void @use32(i32 [[NEG]])
355 ; CHECK-NEXT:    call void @use32(i32 [[OR]])
356 ; CHECK-NEXT:    call void @use32(i32 [[OR1]])
357 ; CHECK-NEXT:    ret i32 [[RET]]
359   %neg = xor i32 %m, -1
360   %or = or i32 %neg, %x
361   %or1 = or i32 %y, %m
362   %ret = and i32 %or, %or1
363   call void @use32(i32 %neg)
364   call void @use32(i32 %or)
365   call void @use32(i32 %or1)
366   ret i32 %ret
369 define i32 @n0_oneuse_6(i32 %x, i32 %y, i32 %m) {
370 ; CHECK-LABEL: @n0_oneuse_6(
371 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], -1
372 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
373 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
374 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
375 ; CHECK-NEXT:    call void @use32(i32 [[OR]])
376 ; CHECK-NEXT:    call void @use32(i32 [[OR1]])
377 ; CHECK-NEXT:    ret i32 [[RET]]
379   %neg = xor i32 %m, -1
380   %or = or i32 %neg, %x
381   %or1 = or i32 %y, %m
382   %ret = and i32 %or, %or1
383   call void @use32(i32 %or)
384   call void @use32(i32 %or1)
385   ret i32 %ret
388 ; One-use with constant mask
390 define i32 @n0_constmask_oneuse_0(i32 %x, i32 %y) {
391 ; CHECK-LABEL: @n0_constmask_oneuse_0(
392 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -65281
393 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], 65280
394 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
395 ; CHECK-NEXT:    call void @use32(i32 [[OR]])
396 ; CHECK-NEXT:    ret i32 [[RET]]
398   %or = or i32 %x, -65281
399   %or1 = or i32 %y, 65280
400   %ret = and i32 %or, %or1
401   call void @use32(i32 %or)
402   ret i32 %ret
405 define i32 @n0_constmask_oneuse_1(i32 %x, i32 %y) {
406 ; CHECK-LABEL: @n0_constmask_oneuse_1(
407 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -65281
408 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], 65280
409 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
410 ; CHECK-NEXT:    call void @use32(i32 [[OR1]])
411 ; CHECK-NEXT:    ret i32 [[RET]]
413   %or = or i32 %x, -65281
414   %or1 = or i32 %y, 65280
415   %ret = and i32 %or, %or1
416   call void @use32(i32 %or1)
417   ret i32 %ret
420 define i32 @n0_constmask_oneuse_2(i32 %x, i32 %y) {
421 ; CHECK-LABEL: @n0_constmask_oneuse_2(
422 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -65281
423 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], 65280
424 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
425 ; CHECK-NEXT:    call void @use32(i32 [[OR]])
426 ; CHECK-NEXT:    call void @use32(i32 [[OR1]])
427 ; CHECK-NEXT:    ret i32 [[RET]]
429   %or = or i32 %x, -65281
430   %or1 = or i32 %y, 65280
431   %ret = and i32 %or, %or1
432   call void @use32(i32 %or)
433   call void @use32(i32 %or1)
434   ret i32 %ret
437 ; Bad xor constant
439 define i32 @n1_badxor(i32 %x, i32 %y, i32 %m) {
440 ; CHECK-LABEL: @n1_badxor(
441 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M:%.*]], 1
442 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
443 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[M]]
444 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
445 ; CHECK-NEXT:    ret i32 [[RET]]
447   %neg = xor i32 %m, 1 ; not -1
448   %or = or i32 %neg, %x
449   %or1 = or i32 %y, %m
450   %ret = and i32 %or, %or1
451   ret i32 %ret
454 ; Different mask is used
456 define i32 @n2_badmask(i32 %x, i32 %y, i32 %m1, i32 %m2) {
457 ; CHECK-LABEL: @n2_badmask(
458 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M2:%.*]], -1
459 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[NEG]], [[X:%.*]]
460 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[M1:%.*]], [[Y:%.*]]
461 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
462 ; CHECK-NEXT:    ret i32 [[RET]]
464   %neg = xor i32 %m2, -1 ; different mask, not %m1
465   %or = or i32 %neg, %x
466   %or1 = or i32 %m1, %y
467   %ret = and i32 %or, %or1
468   ret i32 %ret
471 ; Different const mask is used
473 define i32 @n3_constmask_badmask_set(i32 %x, i32 %y) {
474 ; CHECK-LABEL: @n3_constmask_badmask_set(
475 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -65281
476 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], 65281
477 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
478 ; CHECK-NEXT:    ret i32 [[RET]]
480   %or = or i32 %x, -65281
481   %or1 = or i32 %y, 65281 ; not 65280, so they have one common bit
482   %ret = and i32 %or, %or1
483   ret i32 %ret
486 define i32 @n3_constmask_badmask_unset(i32 %x, i32 %y) {
487 ; CHECK-LABEL: @n3_constmask_badmask_unset(
488 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -65281
489 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], 65024
490 ; CHECK-NEXT:    [[RET:%.*]] = and i32 [[OR]], [[OR1]]
491 ; CHECK-NEXT:    ret i32 [[RET]]
493   %or = or i32 %x, -65281
494   %or1 = or i32 %y, 65024 ; not 65280, so they have one common unset bit
495   %ret = and i32 %or, %or1
496   ret i32 %ret
499 define i32 @n3_constmask_samemask(i32 %x, i32 %y) {
500 ; CHECK-LABEL: @n3_constmask_samemask(
501 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
502 ; CHECK-NEXT:    [[RET:%.*]] = or i32 [[OR2]], -65281
503 ; CHECK-NEXT:    ret i32 [[RET]]
505   %or = or i32 %x, -65281
506   %or1 = or i32 %y, -65281 ; both masks are the same
507   %ret = and i32 %or, %or1
508   ret i32 %ret