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