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