1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi < %s | FileCheck %s --check-prefix=CHECK-NOBMI
3; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi < %s | FileCheck %s --check-prefix=CHECK-BMI
4; https://bugs.llvm.org/show_bug.cgi?id=37104
5
6define i8 @out8(i8 %x, i8 %y, i8 %mask) {
7; CHECK-NOBMI-LABEL: out8:
8; CHECK-NOBMI:       # %bb.0:
9; CHECK-NOBMI-NEXT:    movl %edx, %eax
10; CHECK-NOBMI-NEXT:    andl %edx, %edi
11; CHECK-NOBMI-NEXT:    notb %al
12; CHECK-NOBMI-NEXT:    andb %sil, %al
13; CHECK-NOBMI-NEXT:    orb %dil, %al
14; CHECK-NOBMI-NEXT:    # kill: def $al killed $al killed $eax
15; CHECK-NOBMI-NEXT:    retq
16;
17; CHECK-BMI-LABEL: out8:
18; CHECK-BMI:       # %bb.0:
19; CHECK-BMI-NEXT:    movl %edx, %eax
20; CHECK-BMI-NEXT:    andl %edx, %edi
21; CHECK-BMI-NEXT:    notb %al
22; CHECK-BMI-NEXT:    andb %sil, %al
23; CHECK-BMI-NEXT:    orb %dil, %al
24; CHECK-BMI-NEXT:    # kill: def $al killed $al killed $eax
25; CHECK-BMI-NEXT:    retq
26  %mx = and i8 %x, %mask
27  %notmask = xor i8 %mask, -1
28  %my = and i8 %y, %notmask
29  %r = or i8 %mx, %my
30  ret i8 %r
31}
32
33define i16 @out16(i16 %x, i16 %y, i16 %mask) {
34; CHECK-NOBMI-LABEL: out16:
35; CHECK-NOBMI:       # %bb.0:
36; CHECK-NOBMI-NEXT:    movl %edx, %eax
37; CHECK-NOBMI-NEXT:    andl %edx, %edi
38; CHECK-NOBMI-NEXT:    notl %eax
39; CHECK-NOBMI-NEXT:    andl %esi, %eax
40; CHECK-NOBMI-NEXT:    orl %edi, %eax
41; CHECK-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
42; CHECK-NOBMI-NEXT:    retq
43;
44; CHECK-BMI-LABEL: out16:
45; CHECK-BMI:       # %bb.0:
46; CHECK-BMI-NEXT:    andl %edx, %edi
47; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
48; CHECK-BMI-NEXT:    orl %edi, %eax
49; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
50; CHECK-BMI-NEXT:    retq
51  %mx = and i16 %x, %mask
52  %notmask = xor i16 %mask, -1
53  %my = and i16 %y, %notmask
54  %r = or i16 %mx, %my
55  ret i16 %r
56}
57
58define i32 @out32(i32 %x, i32 %y, i32 %mask) {
59; CHECK-NOBMI-LABEL: out32:
60; CHECK-NOBMI:       # %bb.0:
61; CHECK-NOBMI-NEXT:    movl %edx, %eax
62; CHECK-NOBMI-NEXT:    andl %edx, %edi
63; CHECK-NOBMI-NEXT:    notl %eax
64; CHECK-NOBMI-NEXT:    andl %esi, %eax
65; CHECK-NOBMI-NEXT:    orl %edi, %eax
66; CHECK-NOBMI-NEXT:    retq
67;
68; CHECK-BMI-LABEL: out32:
69; CHECK-BMI:       # %bb.0:
70; CHECK-BMI-NEXT:    andl %edx, %edi
71; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
72; CHECK-BMI-NEXT:    orl %edi, %eax
73; CHECK-BMI-NEXT:    retq
74  %mx = and i32 %x, %mask
75  %notmask = xor i32 %mask, -1
76  %my = and i32 %y, %notmask
77  %r = or i32 %mx, %my
78  ret i32 %r
79}
80
81define i64 @out64(i64 %x, i64 %y, i64 %mask) {
82; CHECK-NOBMI-LABEL: out64:
83; CHECK-NOBMI:       # %bb.0:
84; CHECK-NOBMI-NEXT:    movq %rdx, %rax
85; CHECK-NOBMI-NEXT:    andq %rdx, %rdi
86; CHECK-NOBMI-NEXT:    notq %rax
87; CHECK-NOBMI-NEXT:    andq %rsi, %rax
88; CHECK-NOBMI-NEXT:    orq %rdi, %rax
89; CHECK-NOBMI-NEXT:    retq
90;
91; CHECK-BMI-LABEL: out64:
92; CHECK-BMI:       # %bb.0:
93; CHECK-BMI-NEXT:    andq %rdx, %rdi
94; CHECK-BMI-NEXT:    andnq %rsi, %rdx, %rax
95; CHECK-BMI-NEXT:    orq %rdi, %rax
96; CHECK-BMI-NEXT:    retq
97  %mx = and i64 %x, %mask
98  %notmask = xor i64 %mask, -1
99  %my = and i64 %y, %notmask
100  %r = or i64 %mx, %my
101  ret i64 %r
102}
103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
104; Should be the same as the previous one.
105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
106
107define i8 @in8(i8 %x, i8 %y, i8 %mask) {
108; CHECK-NOBMI-LABEL: in8:
109; CHECK-NOBMI:       # %bb.0:
110; CHECK-NOBMI-NEXT:    movl %edi, %eax
111; CHECK-NOBMI-NEXT:    xorl %esi, %eax
112; CHECK-NOBMI-NEXT:    andl %edx, %eax
113; CHECK-NOBMI-NEXT:    xorl %esi, %eax
114; CHECK-NOBMI-NEXT:    # kill: def $al killed $al killed $eax
115; CHECK-NOBMI-NEXT:    retq
116;
117; CHECK-BMI-LABEL: in8:
118; CHECK-BMI:       # %bb.0:
119; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
120; CHECK-BMI-NEXT:    andl %edx, %edi
121; CHECK-BMI-NEXT:    orl %edi, %eax
122; CHECK-BMI-NEXT:    # kill: def $al killed $al killed $eax
123; CHECK-BMI-NEXT:    retq
124  %n0 = xor i8 %x, %y
125  %n1 = and i8 %n0, %mask
126  %r = xor i8 %n1, %y
127  ret i8 %r
128}
129
130define i16 @in16(i16 %x, i16 %y, i16 %mask) {
131; CHECK-NOBMI-LABEL: in16:
132; CHECK-NOBMI:       # %bb.0:
133; CHECK-NOBMI-NEXT:    movl %edi, %eax
134; CHECK-NOBMI-NEXT:    xorl %esi, %eax
135; CHECK-NOBMI-NEXT:    andl %edx, %eax
136; CHECK-NOBMI-NEXT:    xorl %esi, %eax
137; CHECK-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
138; CHECK-NOBMI-NEXT:    retq
139;
140; CHECK-BMI-LABEL: in16:
141; CHECK-BMI:       # %bb.0:
142; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
143; CHECK-BMI-NEXT:    andl %edx, %edi
144; CHECK-BMI-NEXT:    orl %edi, %eax
145; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
146; CHECK-BMI-NEXT:    retq
147  %n0 = xor i16 %x, %y
148  %n1 = and i16 %n0, %mask
149  %r = xor i16 %n1, %y
150  ret i16 %r
151}
152
153define i32 @in32(i32 %x, i32 %y, i32 %mask) {
154; CHECK-NOBMI-LABEL: in32:
155; CHECK-NOBMI:       # %bb.0:
156; CHECK-NOBMI-NEXT:    movl %edi, %eax
157; CHECK-NOBMI-NEXT:    xorl %esi, %eax
158; CHECK-NOBMI-NEXT:    andl %edx, %eax
159; CHECK-NOBMI-NEXT:    xorl %esi, %eax
160; CHECK-NOBMI-NEXT:    retq
161;
162; CHECK-BMI-LABEL: in32:
163; CHECK-BMI:       # %bb.0:
164; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
165; CHECK-BMI-NEXT:    andl %edx, %edi
166; CHECK-BMI-NEXT:    orl %edi, %eax
167; CHECK-BMI-NEXT:    retq
168  %n0 = xor i32 %x, %y
169  %n1 = and i32 %n0, %mask
170  %r = xor i32 %n1, %y
171  ret i32 %r
172}
173
174define i64 @in64(i64 %x, i64 %y, i64 %mask) {
175; CHECK-NOBMI-LABEL: in64:
176; CHECK-NOBMI:       # %bb.0:
177; CHECK-NOBMI-NEXT:    movq %rdi, %rax
178; CHECK-NOBMI-NEXT:    xorq %rsi, %rax
179; CHECK-NOBMI-NEXT:    andq %rdx, %rax
180; CHECK-NOBMI-NEXT:    xorq %rsi, %rax
181; CHECK-NOBMI-NEXT:    retq
182;
183; CHECK-BMI-LABEL: in64:
184; CHECK-BMI:       # %bb.0:
185; CHECK-BMI-NEXT:    andnq %rsi, %rdx, %rax
186; CHECK-BMI-NEXT:    andq %rdx, %rdi
187; CHECK-BMI-NEXT:    orq %rdi, %rax
188; CHECK-BMI-NEXT:    retq
189  %n0 = xor i64 %x, %y
190  %n1 = and i64 %n0, %mask
191  %r = xor i64 %n1, %y
192  ret i64 %r
193}
194; ============================================================================ ;
195; Commutativity tests.
196; ============================================================================ ;
197define i32 @in_commutativity_0_0_1(i32 %x, i32 %y, i32 %mask) {
198; CHECK-NOBMI-LABEL: in_commutativity_0_0_1:
199; CHECK-NOBMI:       # %bb.0:
200; CHECK-NOBMI-NEXT:    movl %edi, %eax
201; CHECK-NOBMI-NEXT:    xorl %esi, %eax
202; CHECK-NOBMI-NEXT:    andl %edx, %eax
203; CHECK-NOBMI-NEXT:    xorl %esi, %eax
204; CHECK-NOBMI-NEXT:    retq
205;
206; CHECK-BMI-LABEL: in_commutativity_0_0_1:
207; CHECK-BMI:       # %bb.0:
208; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
209; CHECK-BMI-NEXT:    andl %edx, %edi
210; CHECK-BMI-NEXT:    orl %edi, %eax
211; CHECK-BMI-NEXT:    retq
212  %n0 = xor i32 %x, %y
213  %n1 = and i32 %mask, %n0 ; swapped
214  %r = xor i32 %n1, %y
215  ret i32 %r
216}
217define i32 @in_commutativity_0_1_0(i32 %x, i32 %y, i32 %mask) {
218; CHECK-NOBMI-LABEL: in_commutativity_0_1_0:
219; CHECK-NOBMI:       # %bb.0:
220; CHECK-NOBMI-NEXT:    movl %edi, %eax
221; CHECK-NOBMI-NEXT:    xorl %esi, %eax
222; CHECK-NOBMI-NEXT:    andl %edx, %eax
223; CHECK-NOBMI-NEXT:    xorl %esi, %eax
224; CHECK-NOBMI-NEXT:    retq
225;
226; CHECK-BMI-LABEL: in_commutativity_0_1_0:
227; CHECK-BMI:       # %bb.0:
228; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
229; CHECK-BMI-NEXT:    andl %edx, %edi
230; CHECK-BMI-NEXT:    orl %edi, %eax
231; CHECK-BMI-NEXT:    retq
232  %n0 = xor i32 %x, %y
233  %n1 = and i32 %n0, %mask
234  %r = xor i32 %y, %n1 ; swapped
235  ret i32 %r
236}
237define i32 @in_commutativity_0_1_1(i32 %x, i32 %y, i32 %mask) {
238; CHECK-NOBMI-LABEL: in_commutativity_0_1_1:
239; CHECK-NOBMI:       # %bb.0:
240; CHECK-NOBMI-NEXT:    movl %edi, %eax
241; CHECK-NOBMI-NEXT:    xorl %esi, %eax
242; CHECK-NOBMI-NEXT:    andl %edx, %eax
243; CHECK-NOBMI-NEXT:    xorl %esi, %eax
244; CHECK-NOBMI-NEXT:    retq
245;
246; CHECK-BMI-LABEL: in_commutativity_0_1_1:
247; CHECK-BMI:       # %bb.0:
248; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
249; CHECK-BMI-NEXT:    andl %edx, %edi
250; CHECK-BMI-NEXT:    orl %edi, %eax
251; CHECK-BMI-NEXT:    retq
252  %n0 = xor i32 %x, %y
253  %n1 = and i32 %mask, %n0 ; swapped
254  %r = xor i32 %y, %n1 ; swapped
255  ret i32 %r
256}
257define i32 @in_commutativity_1_0_0(i32 %x, i32 %y, i32 %mask) {
258; CHECK-NOBMI-LABEL: in_commutativity_1_0_0:
259; CHECK-NOBMI:       # %bb.0:
260; CHECK-NOBMI-NEXT:    movl %esi, %eax
261; CHECK-NOBMI-NEXT:    xorl %edi, %eax
262; CHECK-NOBMI-NEXT:    andl %edx, %eax
263; CHECK-NOBMI-NEXT:    xorl %edi, %eax
264; CHECK-NOBMI-NEXT:    retq
265;
266; CHECK-BMI-LABEL: in_commutativity_1_0_0:
267; CHECK-BMI:       # %bb.0:
268; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
269; CHECK-BMI-NEXT:    andl %edx, %esi
270; CHECK-BMI-NEXT:    orl %esi, %eax
271; CHECK-BMI-NEXT:    retq
272  %n0 = xor i32 %x, %y
273  %n1 = and i32 %n0, %mask
274  %r = xor i32 %n1, %x ; %x instead of %y
275  ret i32 %r
276}
277define i32 @in_commutativity_1_0_1(i32 %x, i32 %y, i32 %mask) {
278; CHECK-NOBMI-LABEL: in_commutativity_1_0_1:
279; CHECK-NOBMI:       # %bb.0:
280; CHECK-NOBMI-NEXT:    movl %esi, %eax
281; CHECK-NOBMI-NEXT:    xorl %edi, %eax
282; CHECK-NOBMI-NEXT:    andl %edx, %eax
283; CHECK-NOBMI-NEXT:    xorl %edi, %eax
284; CHECK-NOBMI-NEXT:    retq
285;
286; CHECK-BMI-LABEL: in_commutativity_1_0_1:
287; CHECK-BMI:       # %bb.0:
288; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
289; CHECK-BMI-NEXT:    andl %edx, %esi
290; CHECK-BMI-NEXT:    orl %esi, %eax
291; CHECK-BMI-NEXT:    retq
292  %n0 = xor i32 %x, %y
293  %n1 = and i32 %mask, %n0 ; swapped
294  %r = xor i32 %n1, %x ; %x instead of %y
295  ret i32 %r
296}
297define i32 @in_commutativity_1_1_0(i32 %x, i32 %y, i32 %mask) {
298; CHECK-NOBMI-LABEL: in_commutativity_1_1_0:
299; CHECK-NOBMI:       # %bb.0:
300; CHECK-NOBMI-NEXT:    movl %esi, %eax
301; CHECK-NOBMI-NEXT:    xorl %edi, %eax
302; CHECK-NOBMI-NEXT:    andl %edx, %eax
303; CHECK-NOBMI-NEXT:    xorl %edi, %eax
304; CHECK-NOBMI-NEXT:    retq
305;
306; CHECK-BMI-LABEL: in_commutativity_1_1_0:
307; CHECK-BMI:       # %bb.0:
308; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
309; CHECK-BMI-NEXT:    andl %edx, %esi
310; CHECK-BMI-NEXT:    orl %esi, %eax
311; CHECK-BMI-NEXT:    retq
312  %n0 = xor i32 %x, %y
313  %n1 = and i32 %n0, %mask
314  %r = xor i32 %x, %n1 ; swapped, %x instead of %y
315  ret i32 %r
316}
317define i32 @in_commutativity_1_1_1(i32 %x, i32 %y, i32 %mask) {
318; CHECK-NOBMI-LABEL: in_commutativity_1_1_1:
319; CHECK-NOBMI:       # %bb.0:
320; CHECK-NOBMI-NEXT:    movl %esi, %eax
321; CHECK-NOBMI-NEXT:    xorl %edi, %eax
322; CHECK-NOBMI-NEXT:    andl %edx, %eax
323; CHECK-NOBMI-NEXT:    xorl %edi, %eax
324; CHECK-NOBMI-NEXT:    retq
325;
326; CHECK-BMI-LABEL: in_commutativity_1_1_1:
327; CHECK-BMI:       # %bb.0:
328; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
329; CHECK-BMI-NEXT:    andl %edx, %esi
330; CHECK-BMI-NEXT:    orl %esi, %eax
331; CHECK-BMI-NEXT:    retq
332  %n0 = xor i32 %x, %y
333  %n1 = and i32 %mask, %n0 ; swapped
334  %r = xor i32 %x, %n1 ; swapped, %x instead of %y
335  ret i32 %r
336}
337; ============================================================================ ;
338; Y is an 'and' too.
339; ============================================================================ ;
340define i32 @in_complex_y0(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {
341; CHECK-NOBMI-LABEL: in_complex_y0:
342; CHECK-NOBMI:       # %bb.0:
343; CHECK-NOBMI-NEXT:    movl %edi, %eax
344; CHECK-NOBMI-NEXT:    andl %edx, %esi
345; CHECK-NOBMI-NEXT:    xorl %esi, %eax
346; CHECK-NOBMI-NEXT:    andl %ecx, %eax
347; CHECK-NOBMI-NEXT:    xorl %esi, %eax
348; CHECK-NOBMI-NEXT:    retq
349;
350; CHECK-BMI-LABEL: in_complex_y0:
351; CHECK-BMI:       # %bb.0:
352; CHECK-BMI-NEXT:    andl %edx, %esi
353; CHECK-BMI-NEXT:    andl %ecx, %edi
354; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
355; CHECK-BMI-NEXT:    orl %edi, %eax
356; CHECK-BMI-NEXT:    retq
357  %y = and i32 %y_hi, %y_low
358  %n0 = xor i32 %x, %y
359  %n1 = and i32 %n0, %mask
360  %r = xor i32 %n1, %y
361  ret i32 %r
362}
363define i32 @in_complex_y1(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {
364; CHECK-NOBMI-LABEL: in_complex_y1:
365; CHECK-NOBMI:       # %bb.0:
366; CHECK-NOBMI-NEXT:    movl %edi, %eax
367; CHECK-NOBMI-NEXT:    andl %edx, %esi
368; CHECK-NOBMI-NEXT:    xorl %esi, %eax
369; CHECK-NOBMI-NEXT:    andl %ecx, %eax
370; CHECK-NOBMI-NEXT:    xorl %esi, %eax
371; CHECK-NOBMI-NEXT:    retq
372;
373; CHECK-BMI-LABEL: in_complex_y1:
374; CHECK-BMI:       # %bb.0:
375; CHECK-BMI-NEXT:    andl %edx, %esi
376; CHECK-BMI-NEXT:    andl %ecx, %edi
377; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
378; CHECK-BMI-NEXT:    orl %edi, %eax
379; CHECK-BMI-NEXT:    retq
380  %y = and i32 %y_hi, %y_low
381  %n0 = xor i32 %x, %y
382  %n1 = and i32 %n0, %mask
383  %r = xor i32 %y, %n1
384  ret i32 %r
385}
386; ============================================================================ ;
387; M is an 'xor' too.
388; ============================================================================ ;
389define i32 @in_complex_m0(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {
390; CHECK-NOBMI-LABEL: in_complex_m0:
391; CHECK-NOBMI:       # %bb.0:
392; CHECK-NOBMI-NEXT:    movl %edi, %eax
393; CHECK-NOBMI-NEXT:    xorl %ecx, %edx
394; CHECK-NOBMI-NEXT:    xorl %esi, %eax
395; CHECK-NOBMI-NEXT:    andl %edx, %eax
396; CHECK-NOBMI-NEXT:    xorl %esi, %eax
397; CHECK-NOBMI-NEXT:    retq
398;
399; CHECK-BMI-LABEL: in_complex_m0:
400; CHECK-BMI:       # %bb.0:
401; CHECK-BMI-NEXT:    xorl %ecx, %edx
402; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
403; CHECK-BMI-NEXT:    andl %edi, %edx
404; CHECK-BMI-NEXT:    orl %edx, %eax
405; CHECK-BMI-NEXT:    retq
406  %mask = xor i32 %m_a, %m_b
407  %n0 = xor i32 %x, %y
408  %n1 = and i32 %n0, %mask
409  %r = xor i32 %n1, %y
410  ret i32 %r
411}
412define i32 @in_complex_m1(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {
413; CHECK-NOBMI-LABEL: in_complex_m1:
414; CHECK-NOBMI:       # %bb.0:
415; CHECK-NOBMI-NEXT:    movl %edi, %eax
416; CHECK-NOBMI-NEXT:    xorl %ecx, %edx
417; CHECK-NOBMI-NEXT:    xorl %esi, %eax
418; CHECK-NOBMI-NEXT:    andl %edx, %eax
419; CHECK-NOBMI-NEXT:    xorl %esi, %eax
420; CHECK-NOBMI-NEXT:    retq
421;
422; CHECK-BMI-LABEL: in_complex_m1:
423; CHECK-BMI:       # %bb.0:
424; CHECK-BMI-NEXT:    xorl %ecx, %edx
425; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
426; CHECK-BMI-NEXT:    andl %edi, %edx
427; CHECK-BMI-NEXT:    orl %edx, %eax
428; CHECK-BMI-NEXT:    retq
429  %mask = xor i32 %m_a, %m_b
430  %n0 = xor i32 %x, %y
431  %n1 = and i32 %mask, %n0
432  %r = xor i32 %n1, %y
433  ret i32 %r
434}
435; ============================================================================ ;
436; Both Y and M are complex.
437; ============================================================================ ;
438define i32 @in_complex_y0_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
439; CHECK-NOBMI-LABEL: in_complex_y0_m0:
440; CHECK-NOBMI:       # %bb.0:
441; CHECK-NOBMI-NEXT:    movl %edi, %eax
442; CHECK-NOBMI-NEXT:    andl %edx, %esi
443; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
444; CHECK-NOBMI-NEXT:    xorl %esi, %eax
445; CHECK-NOBMI-NEXT:    andl %ecx, %eax
446; CHECK-NOBMI-NEXT:    xorl %esi, %eax
447; CHECK-NOBMI-NEXT:    retq
448;
449; CHECK-BMI-LABEL: in_complex_y0_m0:
450; CHECK-BMI:       # %bb.0:
451; CHECK-BMI-NEXT:    andl %edx, %esi
452; CHECK-BMI-NEXT:    xorl %r8d, %ecx
453; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
454; CHECK-BMI-NEXT:    andl %edi, %ecx
455; CHECK-BMI-NEXT:    orl %ecx, %eax
456; CHECK-BMI-NEXT:    retq
457  %y = and i32 %y_hi, %y_low
458  %mask = xor i32 %m_a, %m_b
459  %n0 = xor i32 %x, %y
460  %n1 = and i32 %n0, %mask
461  %r = xor i32 %n1, %y
462  ret i32 %r
463}
464define i32 @in_complex_y1_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
465; CHECK-NOBMI-LABEL: in_complex_y1_m0:
466; CHECK-NOBMI:       # %bb.0:
467; CHECK-NOBMI-NEXT:    movl %edi, %eax
468; CHECK-NOBMI-NEXT:    andl %edx, %esi
469; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
470; CHECK-NOBMI-NEXT:    xorl %esi, %eax
471; CHECK-NOBMI-NEXT:    andl %ecx, %eax
472; CHECK-NOBMI-NEXT:    xorl %esi, %eax
473; CHECK-NOBMI-NEXT:    retq
474;
475; CHECK-BMI-LABEL: in_complex_y1_m0:
476; CHECK-BMI:       # %bb.0:
477; CHECK-BMI-NEXT:    andl %edx, %esi
478; CHECK-BMI-NEXT:    xorl %r8d, %ecx
479; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
480; CHECK-BMI-NEXT:    andl %edi, %ecx
481; CHECK-BMI-NEXT:    orl %ecx, %eax
482; CHECK-BMI-NEXT:    retq
483  %y = and i32 %y_hi, %y_low
484  %mask = xor i32 %m_a, %m_b
485  %n0 = xor i32 %x, %y
486  %n1 = and i32 %n0, %mask
487  %r = xor i32 %y, %n1
488  ret i32 %r
489}
490define i32 @in_complex_y0_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
491; CHECK-NOBMI-LABEL: in_complex_y0_m1:
492; CHECK-NOBMI:       # %bb.0:
493; CHECK-NOBMI-NEXT:    movl %edi, %eax
494; CHECK-NOBMI-NEXT:    andl %edx, %esi
495; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
496; CHECK-NOBMI-NEXT:    xorl %esi, %eax
497; CHECK-NOBMI-NEXT:    andl %ecx, %eax
498; CHECK-NOBMI-NEXT:    xorl %esi, %eax
499; CHECK-NOBMI-NEXT:    retq
500;
501; CHECK-BMI-LABEL: in_complex_y0_m1:
502; CHECK-BMI:       # %bb.0:
503; CHECK-BMI-NEXT:    andl %edx, %esi
504; CHECK-BMI-NEXT:    xorl %r8d, %ecx
505; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
506; CHECK-BMI-NEXT:    andl %edi, %ecx
507; CHECK-BMI-NEXT:    orl %ecx, %eax
508; CHECK-BMI-NEXT:    retq
509  %y = and i32 %y_hi, %y_low
510  %mask = xor i32 %m_a, %m_b
511  %n0 = xor i32 %x, %y
512  %n1 = and i32 %mask, %n0
513  %r = xor i32 %n1, %y
514  ret i32 %r
515}
516define i32 @in_complex_y1_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
517; CHECK-NOBMI-LABEL: in_complex_y1_m1:
518; CHECK-NOBMI:       # %bb.0:
519; CHECK-NOBMI-NEXT:    movl %edi, %eax
520; CHECK-NOBMI-NEXT:    andl %edx, %esi
521; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
522; CHECK-NOBMI-NEXT:    xorl %esi, %eax
523; CHECK-NOBMI-NEXT:    andl %ecx, %eax
524; CHECK-NOBMI-NEXT:    xorl %esi, %eax
525; CHECK-NOBMI-NEXT:    retq
526;
527; CHECK-BMI-LABEL: in_complex_y1_m1:
528; CHECK-BMI:       # %bb.0:
529; CHECK-BMI-NEXT:    andl %edx, %esi
530; CHECK-BMI-NEXT:    xorl %r8d, %ecx
531; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
532; CHECK-BMI-NEXT:    andl %edi, %ecx
533; CHECK-BMI-NEXT:    orl %ecx, %eax
534; CHECK-BMI-NEXT:    retq
535  %y = and i32 %y_hi, %y_low
536  %mask = xor i32 %m_a, %m_b
537  %n0 = xor i32 %x, %y
538  %n1 = and i32 %mask, %n0
539  %r = xor i32 %y, %n1
540  ret i32 %r
541}
542; ============================================================================ ;
543; Various cases with %x and/or %y being a constant
544; ============================================================================ ;
545define i32 @out_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {
546; CHECK-NOBMI-LABEL: out_constant_varx_mone:
547; CHECK-NOBMI:       # %bb.0:
548; CHECK-NOBMI-NEXT:    movl %edi, %eax
549; CHECK-NOBMI-NEXT:    andl %edx, %eax
550; CHECK-NOBMI-NEXT:    notl %edx
551; CHECK-NOBMI-NEXT:    orl %edx, %eax
552; CHECK-NOBMI-NEXT:    retq
553;
554; CHECK-BMI-LABEL: out_constant_varx_mone:
555; CHECK-BMI:       # %bb.0:
556; CHECK-BMI-NEXT:    movl %edi, %eax
557; CHECK-BMI-NEXT:    andl %edx, %eax
558; CHECK-BMI-NEXT:    notl %edx
559; CHECK-BMI-NEXT:    orl %edx, %eax
560; CHECK-BMI-NEXT:    retq
561  %notmask = xor i32 %mask, -1
562  %mx = and i32 %mask, %x
563  %my = and i32 %notmask, -1
564  %r = or i32 %mx, %my
565  ret i32 %r
566}
567define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {
568; CHECK-NOBMI-LABEL: in_constant_varx_mone:
569; CHECK-NOBMI:       # %bb.0:
570; CHECK-NOBMI-NEXT:    movl %edi, %eax
571; CHECK-NOBMI-NEXT:    notl %eax
572; CHECK-NOBMI-NEXT:    andl %edx, %eax
573; CHECK-NOBMI-NEXT:    notl %eax
574; CHECK-NOBMI-NEXT:    retq
575;
576; CHECK-BMI-LABEL: in_constant_varx_mone:
577; CHECK-BMI:       # %bb.0:
578; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
579; CHECK-BMI-NEXT:    notl %eax
580; CHECK-BMI-NEXT:    retq
581  %n0 = xor i32 %x, -1 ; %x
582  %n1 = and i32 %n0, %mask
583  %r = xor i32 %n1, -1
584  ret i32 %r
585}
586; This is not a canonical form. Testing for completeness only.
587define i32 @out_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {
588; CHECK-NOBMI-LABEL: out_constant_varx_mone_invmask:
589; CHECK-NOBMI:       # %bb.0:
590; CHECK-NOBMI-NEXT:    movl %edi, %eax
591; CHECK-NOBMI-NEXT:    orl %edx, %eax
592; CHECK-NOBMI-NEXT:    retq
593;
594; CHECK-BMI-LABEL: out_constant_varx_mone_invmask:
595; CHECK-BMI:       # %bb.0:
596; CHECK-BMI-NEXT:    movl %edi, %eax
597; CHECK-BMI-NEXT:    orl %edx, %eax
598; CHECK-BMI-NEXT:    retq
599  %notmask = xor i32 %mask, -1
600  %mx = and i32 %notmask, %x
601  %my = and i32 %mask, -1
602  %r = or i32 %mx, %my
603  ret i32 %r
604}
605; This is not a canonical form. Testing for completeness only.
606define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {
607; CHECK-NOBMI-LABEL: in_constant_varx_mone_invmask:
608; CHECK-NOBMI:       # %bb.0:
609; CHECK-NOBMI-NEXT:    movl %edi, %eax
610; CHECK-NOBMI-NEXT:    notl %edx
611; CHECK-NOBMI-NEXT:    notl %eax
612; CHECK-NOBMI-NEXT:    andl %edx, %eax
613; CHECK-NOBMI-NEXT:    notl %eax
614; CHECK-NOBMI-NEXT:    retq
615;
616; CHECK-BMI-LABEL: in_constant_varx_mone_invmask:
617; CHECK-BMI:       # %bb.0:
618; CHECK-BMI-NEXT:    notl %edx
619; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
620; CHECK-BMI-NEXT:    notl %eax
621; CHECK-BMI-NEXT:    retq
622  %notmask = xor i32 %mask, -1
623  %n0 = xor i32 %x, -1 ; %x
624  %n1 = and i32 %n0, %notmask
625  %r = xor i32 %n1, -1
626  ret i32 %r
627}
628define i32 @out_constant_varx_42(i32 %x, i32 %y, i32 %mask) {
629; CHECK-NOBMI-LABEL: out_constant_varx_42:
630; CHECK-NOBMI:       # %bb.0:
631; CHECK-NOBMI-NEXT:    andl %edx, %edi
632; CHECK-NOBMI-NEXT:    movl %edx, %eax
633; CHECK-NOBMI-NEXT:    notl %eax
634; CHECK-NOBMI-NEXT:    andl $42, %eax
635; CHECK-NOBMI-NEXT:    orl %edi, %eax
636; CHECK-NOBMI-NEXT:    retq
637;
638; CHECK-BMI-LABEL: out_constant_varx_42:
639; CHECK-BMI:       # %bb.0:
640; CHECK-BMI-NEXT:    andl %edx, %edi
641; CHECK-BMI-NEXT:    movl %edx, %eax
642; CHECK-BMI-NEXT:    notl %eax
643; CHECK-BMI-NEXT:    andl $42, %eax
644; CHECK-BMI-NEXT:    orl %edi, %eax
645; CHECK-BMI-NEXT:    retq
646  %notmask = xor i32 %mask, -1
647  %mx = and i32 %mask, %x
648  %my = and i32 %notmask, 42
649  %r = or i32 %mx, %my
650  ret i32 %r
651}
652define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) {
653; CHECK-NOBMI-LABEL: in_constant_varx_42:
654; CHECK-NOBMI:       # %bb.0:
655; CHECK-NOBMI-NEXT:    movl %edi, %eax
656; CHECK-NOBMI-NEXT:    xorl $42, %eax
657; CHECK-NOBMI-NEXT:    andl %edx, %eax
658; CHECK-NOBMI-NEXT:    xorl $42, %eax
659; CHECK-NOBMI-NEXT:    retq
660;
661; CHECK-BMI-LABEL: in_constant_varx_42:
662; CHECK-BMI:       # %bb.0:
663; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
664; CHECK-BMI-NEXT:    orl $42, %edx
665; CHECK-BMI-NEXT:    andnl %edx, %eax, %eax
666; CHECK-BMI-NEXT:    retq
667  %n0 = xor i32 %x, 42 ; %x
668  %n1 = and i32 %n0, %mask
669  %r = xor i32 %n1, 42
670  ret i32 %r
671}
672; This is not a canonical form. Testing for completeness only.
673define i32 @out_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {
674; CHECK-NOBMI-LABEL: out_constant_varx_42_invmask:
675; CHECK-NOBMI:       # %bb.0:
676; CHECK-NOBMI-NEXT:    movl %edx, %eax
677; CHECK-NOBMI-NEXT:    movl %edx, %ecx
678; CHECK-NOBMI-NEXT:    notl %ecx
679; CHECK-NOBMI-NEXT:    andl %edi, %ecx
680; CHECK-NOBMI-NEXT:    andl $42, %eax
681; CHECK-NOBMI-NEXT:    orl %ecx, %eax
682; CHECK-NOBMI-NEXT:    retq
683;
684; CHECK-BMI-LABEL: out_constant_varx_42_invmask:
685; CHECK-BMI:       # %bb.0:
686; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
687; CHECK-BMI-NEXT:    andl $42, %edx
688; CHECK-BMI-NEXT:    orl %edx, %eax
689; CHECK-BMI-NEXT:    retq
690  %notmask = xor i32 %mask, -1
691  %mx = and i32 %notmask, %x
692  %my = and i32 %mask, 42
693  %r = or i32 %mx, %my
694  ret i32 %r
695}
696; This is not a canonical form. Testing for completeness only.
697define i32 @in_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {
698; CHECK-NOBMI-LABEL: in_constant_varx_42_invmask:
699; CHECK-NOBMI:       # %bb.0:
700; CHECK-NOBMI-NEXT:    movl %edi, %eax
701; CHECK-NOBMI-NEXT:    notl %edx
702; CHECK-NOBMI-NEXT:    xorl $42, %eax
703; CHECK-NOBMI-NEXT:    andl %edx, %eax
704; CHECK-NOBMI-NEXT:    xorl $42, %eax
705; CHECK-NOBMI-NEXT:    retq
706;
707; CHECK-BMI-LABEL: in_constant_varx_42_invmask:
708; CHECK-BMI:       # %bb.0:
709; CHECK-BMI-NEXT:    notl %edx
710; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
711; CHECK-BMI-NEXT:    orl $42, %edx
712; CHECK-BMI-NEXT:    andnl %edx, %eax, %eax
713; CHECK-BMI-NEXT:    retq
714  %notmask = xor i32 %mask, -1
715  %n0 = xor i32 %x, 42 ; %x
716  %n1 = and i32 %n0, %notmask
717  %r = xor i32 %n1, 42
718  ret i32 %r
719}
720define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
721; CHECK-NOBMI-LABEL: out_constant_mone_vary:
722; CHECK-NOBMI:       # %bb.0:
723; CHECK-NOBMI-NEXT:    movl %esi, %eax
724; CHECK-NOBMI-NEXT:    orl %edx, %eax
725; CHECK-NOBMI-NEXT:    retq
726;
727; CHECK-BMI-LABEL: out_constant_mone_vary:
728; CHECK-BMI:       # %bb.0:
729; CHECK-BMI-NEXT:    movl %esi, %eax
730; CHECK-BMI-NEXT:    orl %edx, %eax
731; CHECK-BMI-NEXT:    retq
732  %notmask = xor i32 %mask, -1
733  %mx = and i32 %mask, -1
734  %my = and i32 %notmask, %y
735  %r = or i32 %mx, %my
736  ret i32 %r
737}
738define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
739; CHECK-NOBMI-LABEL: in_constant_mone_vary:
740; CHECK-NOBMI:       # %bb.0:
741; CHECK-NOBMI-NEXT:    movl %esi, %eax
742; CHECK-NOBMI-NEXT:    notl %eax
743; CHECK-NOBMI-NEXT:    andl %edx, %eax
744; CHECK-NOBMI-NEXT:    xorl %esi, %eax
745; CHECK-NOBMI-NEXT:    retq
746;
747; CHECK-BMI-LABEL: in_constant_mone_vary:
748; CHECK-BMI:       # %bb.0:
749; CHECK-BMI-NEXT:    andnl %edx, %esi, %eax
750; CHECK-BMI-NEXT:    xorl %esi, %eax
751; CHECK-BMI-NEXT:    retq
752  %n0 = xor i32 -1, %y ; %x
753  %n1 = and i32 %n0, %mask
754  %r = xor i32 %n1, %y
755  ret i32 %r
756}
757; This is not a canonical form. Testing for completeness only.
758define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
759; CHECK-NOBMI-LABEL: out_constant_mone_vary_invmask:
760; CHECK-NOBMI:       # %bb.0:
761; CHECK-NOBMI-NEXT:    movl %esi, %eax
762; CHECK-NOBMI-NEXT:    andl %edx, %eax
763; CHECK-NOBMI-NEXT:    notl %edx
764; CHECK-NOBMI-NEXT:    orl %edx, %eax
765; CHECK-NOBMI-NEXT:    retq
766;
767; CHECK-BMI-LABEL: out_constant_mone_vary_invmask:
768; CHECK-BMI:       # %bb.0:
769; CHECK-BMI-NEXT:    movl %esi, %eax
770; CHECK-BMI-NEXT:    andl %edx, %eax
771; CHECK-BMI-NEXT:    notl %edx
772; CHECK-BMI-NEXT:    orl %edx, %eax
773; CHECK-BMI-NEXT:    retq
774  %notmask = xor i32 %mask, -1
775  %mx = and i32 %notmask, -1
776  %my = and i32 %mask, %y
777  %r = or i32 %mx, %my
778  ret i32 %r
779}
780; This is not a canonical form. Testing for completeness only.
781define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
782; CHECK-NOBMI-LABEL: in_constant_mone_vary_invmask:
783; CHECK-NOBMI:       # %bb.0:
784; CHECK-NOBMI-NEXT:    notl %edx
785; CHECK-NOBMI-NEXT:    movl %esi, %eax
786; CHECK-NOBMI-NEXT:    notl %eax
787; CHECK-NOBMI-NEXT:    andl %edx, %eax
788; CHECK-NOBMI-NEXT:    xorl %esi, %eax
789; CHECK-NOBMI-NEXT:    retq
790;
791; CHECK-BMI-LABEL: in_constant_mone_vary_invmask:
792; CHECK-BMI:       # %bb.0:
793; CHECK-BMI-NEXT:    notl %edx
794; CHECK-BMI-NEXT:    andnl %edx, %esi, %eax
795; CHECK-BMI-NEXT:    xorl %esi, %eax
796; CHECK-BMI-NEXT:    retq
797  %notmask = xor i32 %mask, -1
798  %n0 = xor i32 -1, %y ; %x
799  %n1 = and i32 %n0, %notmask
800  %r = xor i32 %n1, %y
801  ret i32 %r
802}
803define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) {
804; CHECK-NOBMI-LABEL: out_constant_42_vary:
805; CHECK-NOBMI:       # %bb.0:
806; CHECK-NOBMI-NEXT:    movl %edx, %eax
807; CHECK-NOBMI-NEXT:    notl %eax
808; CHECK-NOBMI-NEXT:    andl $42, %edx
809; CHECK-NOBMI-NEXT:    andl %esi, %eax
810; CHECK-NOBMI-NEXT:    orl %edx, %eax
811; CHECK-NOBMI-NEXT:    retq
812;
813; CHECK-BMI-LABEL: out_constant_42_vary:
814; CHECK-BMI:       # %bb.0:
815; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
816; CHECK-BMI-NEXT:    andl $42, %edx
817; CHECK-BMI-NEXT:    orl %edx, %eax
818; CHECK-BMI-NEXT:    retq
819  %notmask = xor i32 %mask, -1
820  %mx = and i32 %mask, 42
821  %my = and i32 %notmask, %y
822  %r = or i32 %mx, %my
823  ret i32 %r
824}
825define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) {
826; CHECK-NOBMI-LABEL: in_constant_42_vary:
827; CHECK-NOBMI:       # %bb.0:
828; CHECK-NOBMI-NEXT:    movl %esi, %eax
829; CHECK-NOBMI-NEXT:    xorl $42, %eax
830; CHECK-NOBMI-NEXT:    andl %edx, %eax
831; CHECK-NOBMI-NEXT:    xorl %esi, %eax
832; CHECK-NOBMI-NEXT:    retq
833;
834; CHECK-BMI-LABEL: in_constant_42_vary:
835; CHECK-BMI:       # %bb.0:
836; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
837; CHECK-BMI-NEXT:    andl $42, %edx
838; CHECK-BMI-NEXT:    orl %edx, %eax
839; CHECK-BMI-NEXT:    retq
840  %n0 = xor i32 42, %y ; %x
841  %n1 = and i32 %n0, %mask
842  %r = xor i32 %n1, %y
843  ret i32 %r
844}
845; This is not a canonical form. Testing for completeness only.
846define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {
847; CHECK-NOBMI-LABEL: out_constant_42_vary_invmask:
848; CHECK-NOBMI:       # %bb.0:
849; CHECK-NOBMI-NEXT:    movl %esi, %eax
850; CHECK-NOBMI-NEXT:    andl %edx, %eax
851; CHECK-NOBMI-NEXT:    notl %edx
852; CHECK-NOBMI-NEXT:    andl $42, %edx
853; CHECK-NOBMI-NEXT:    orl %edx, %eax
854; CHECK-NOBMI-NEXT:    retq
855;
856; CHECK-BMI-LABEL: out_constant_42_vary_invmask:
857; CHECK-BMI:       # %bb.0:
858; CHECK-BMI-NEXT:    movl %esi, %eax
859; CHECK-BMI-NEXT:    andl %edx, %eax
860; CHECK-BMI-NEXT:    notl %edx
861; CHECK-BMI-NEXT:    andl $42, %edx
862; CHECK-BMI-NEXT:    orl %edx, %eax
863; CHECK-BMI-NEXT:    retq
864  %notmask = xor i32 %mask, -1
865  %mx = and i32 %notmask, 42
866  %my = and i32 %mask, %y
867  %r = or i32 %mx, %my
868  ret i32 %r
869}
870; This is not a canonical form. Testing for completeness only.
871define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {
872; CHECK-NOBMI-LABEL: in_constant_42_vary_invmask:
873; CHECK-NOBMI:       # %bb.0:
874; CHECK-NOBMI-NEXT:    notl %edx
875; CHECK-NOBMI-NEXT:    movl %esi, %eax
876; CHECK-NOBMI-NEXT:    xorl $42, %eax
877; CHECK-NOBMI-NEXT:    andl %edx, %eax
878; CHECK-NOBMI-NEXT:    xorl %esi, %eax
879; CHECK-NOBMI-NEXT:    retq
880;
881; CHECK-BMI-LABEL: in_constant_42_vary_invmask:
882; CHECK-BMI:       # %bb.0:
883; CHECK-BMI-NEXT:    movl %edx, %eax
884; CHECK-BMI-NEXT:    andl %edx, %esi
885; CHECK-BMI-NEXT:    notl %eax
886; CHECK-BMI-NEXT:    andl $42, %eax
887; CHECK-BMI-NEXT:    orl %esi, %eax
888; CHECK-BMI-NEXT:    retq
889  %notmask = xor i32 %mask, -1
890  %n0 = xor i32 42, %y ; %x
891  %n1 = and i32 %n0, %notmask
892  %r = xor i32 %n1, %y
893  ret i32 %r
894}
895; ============================================================================ ;
896; Negative tests. Should not be folded.
897; ============================================================================ ;
898; Multi-use tests.
899declare void @use32(i32) nounwind
900define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
901; CHECK-NOBMI-LABEL: in_multiuse_A:
902; CHECK-NOBMI:       # %bb.0:
903; CHECK-NOBMI-NEXT:    pushq %rbp
904; CHECK-NOBMI-NEXT:    pushq %rbx
905; CHECK-NOBMI-NEXT:    pushq %rax
906; CHECK-NOBMI-NEXT:    movl %esi, %ebx
907; CHECK-NOBMI-NEXT:    movl %edi, %ebp
908; CHECK-NOBMI-NEXT:    xorl %esi, %ebp
909; CHECK-NOBMI-NEXT:    andl %ecx, %ebp
910; CHECK-NOBMI-NEXT:    movl %ebp, %edi
911; CHECK-NOBMI-NEXT:    callq use32
912; CHECK-NOBMI-NEXT:    xorl %ebx, %ebp
913; CHECK-NOBMI-NEXT:    movl %ebp, %eax
914; CHECK-NOBMI-NEXT:    addq $8, %rsp
915; CHECK-NOBMI-NEXT:    popq %rbx
916; CHECK-NOBMI-NEXT:    popq %rbp
917; CHECK-NOBMI-NEXT:    retq
918;
919; CHECK-BMI-LABEL: in_multiuse_A:
920; CHECK-BMI:       # %bb.0:
921; CHECK-BMI-NEXT:    pushq %rbp
922; CHECK-BMI-NEXT:    pushq %rbx
923; CHECK-BMI-NEXT:    pushq %rax
924; CHECK-BMI-NEXT:    movl %esi, %ebx
925; CHECK-BMI-NEXT:    movl %edi, %ebp
926; CHECK-BMI-NEXT:    xorl %esi, %ebp
927; CHECK-BMI-NEXT:    andl %ecx, %ebp
928; CHECK-BMI-NEXT:    movl %ebp, %edi
929; CHECK-BMI-NEXT:    callq use32
930; CHECK-BMI-NEXT:    xorl %ebx, %ebp
931; CHECK-BMI-NEXT:    movl %ebp, %eax
932; CHECK-BMI-NEXT:    addq $8, %rsp
933; CHECK-BMI-NEXT:    popq %rbx
934; CHECK-BMI-NEXT:    popq %rbp
935; CHECK-BMI-NEXT:    retq
936  %n0 = xor i32 %x, %y
937  %n1 = and i32 %n0, %mask
938  call void @use32(i32 %n1)
939  %r = xor i32 %n1, %y
940  ret i32 %r
941}
942define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
943; CHECK-NOBMI-LABEL: in_multiuse_B:
944; CHECK-NOBMI:       # %bb.0:
945; CHECK-NOBMI-NEXT:    pushq %rbp
946; CHECK-NOBMI-NEXT:    pushq %rbx
947; CHECK-NOBMI-NEXT:    pushq %rax
948; CHECK-NOBMI-NEXT:    movl %ecx, %ebx
949; CHECK-NOBMI-NEXT:    movl %esi, %ebp
950; CHECK-NOBMI-NEXT:    xorl %esi, %edi
951; CHECK-NOBMI-NEXT:    andl %edi, %ebx
952; CHECK-NOBMI-NEXT:    callq use32
953; CHECK-NOBMI-NEXT:    xorl %ebp, %ebx
954; CHECK-NOBMI-NEXT:    movl %ebx, %eax
955; CHECK-NOBMI-NEXT:    addq $8, %rsp
956; CHECK-NOBMI-NEXT:    popq %rbx
957; CHECK-NOBMI-NEXT:    popq %rbp
958; CHECK-NOBMI-NEXT:    retq
959;
960; CHECK-BMI-LABEL: in_multiuse_B:
961; CHECK-BMI:       # %bb.0:
962; CHECK-BMI-NEXT:    pushq %rbp
963; CHECK-BMI-NEXT:    pushq %rbx
964; CHECK-BMI-NEXT:    pushq %rax
965; CHECK-BMI-NEXT:    movl %ecx, %ebx
966; CHECK-BMI-NEXT:    movl %esi, %ebp
967; CHECK-BMI-NEXT:    xorl %esi, %edi
968; CHECK-BMI-NEXT:    andl %edi, %ebx
969; CHECK-BMI-NEXT:    callq use32
970; CHECK-BMI-NEXT:    xorl %ebp, %ebx
971; CHECK-BMI-NEXT:    movl %ebx, %eax
972; CHECK-BMI-NEXT:    addq $8, %rsp
973; CHECK-BMI-NEXT:    popq %rbx
974; CHECK-BMI-NEXT:    popq %rbp
975; CHECK-BMI-NEXT:    retq
976  %n0 = xor i32 %x, %y
977  %n1 = and i32 %n0, %mask
978  call void @use32(i32 %n0)
979  %r = xor i32 %n1, %y
980  ret i32 %r
981}
982; Various bad variants
983define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) {
984; CHECK-NOBMI-LABEL: n0_badmask:
985; CHECK-NOBMI:       # %bb.0:
986; CHECK-NOBMI-NEXT:    movl %ecx, %eax
987; CHECK-NOBMI-NEXT:    andl %edx, %edi
988; CHECK-NOBMI-NEXT:    notl %eax
989; CHECK-NOBMI-NEXT:    andl %esi, %eax
990; CHECK-NOBMI-NEXT:    orl %edi, %eax
991; CHECK-NOBMI-NEXT:    retq
992;
993; CHECK-BMI-LABEL: n0_badmask:
994; CHECK-BMI:       # %bb.0:
995; CHECK-BMI-NEXT:    andl %edx, %edi
996; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
997; CHECK-BMI-NEXT:    orl %edi, %eax
998; CHECK-BMI-NEXT:    retq
999  %mx = and i32 %x, %mask
1000  %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask
1001  %my = and i32 %y, %notmask
1002  %r = or i32 %mx, %my
1003  ret i32 %r
1004}
1005define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) {
1006; CHECK-NOBMI-LABEL: n0_badxor:
1007; CHECK-NOBMI:       # %bb.0:
1008; CHECK-NOBMI-NEXT:    movl %edx, %eax
1009; CHECK-NOBMI-NEXT:    andl %edx, %edi
1010; CHECK-NOBMI-NEXT:    xorl $1, %eax
1011; CHECK-NOBMI-NEXT:    andl %esi, %eax
1012; CHECK-NOBMI-NEXT:    orl %edi, %eax
1013; CHECK-NOBMI-NEXT:    retq
1014;
1015; CHECK-BMI-LABEL: n0_badxor:
1016; CHECK-BMI:       # %bb.0:
1017; CHECK-BMI-NEXT:    movl %edx, %eax
1018; CHECK-BMI-NEXT:    andl %edx, %edi
1019; CHECK-BMI-NEXT:    xorl $1, %eax
1020; CHECK-BMI-NEXT:    andl %esi, %eax
1021; CHECK-BMI-NEXT:    orl %edi, %eax
1022; CHECK-BMI-NEXT:    retq
1023  %mx = and i32 %x, %mask
1024  %notmask = xor i32 %mask, 1 ; instead of -1
1025  %my = and i32 %y, %notmask
1026  %r = or i32 %mx, %my
1027  ret i32 %r
1028}
1029define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) {
1030; CHECK-NOBMI-LABEL: n1_thirdvar:
1031; CHECK-NOBMI:       # %bb.0:
1032; CHECK-NOBMI-NEXT:    movl %edi, %eax
1033; CHECK-NOBMI-NEXT:    xorl %esi, %eax
1034; CHECK-NOBMI-NEXT:    andl %ecx, %eax
1035; CHECK-NOBMI-NEXT:    xorl %edx, %eax
1036; CHECK-NOBMI-NEXT:    retq
1037;
1038; CHECK-BMI-LABEL: n1_thirdvar:
1039; CHECK-BMI:       # %bb.0:
1040; CHECK-BMI-NEXT:    movl %edi, %eax
1041; CHECK-BMI-NEXT:    xorl %esi, %eax
1042; CHECK-BMI-NEXT:    andl %ecx, %eax
1043; CHECK-BMI-NEXT:    xorl %edx, %eax
1044; CHECK-BMI-NEXT:    retq
1045  %n0 = xor i32 %x, %y
1046  %n1 = and i32 %n0, %mask
1047  %r = xor i32 %n1, %z ; instead of %y
1048  ret i32 %r
1049}
1050