Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / unfold-masked-merge-scalar-variablemask.ll
blob22c0b798e1468c868093a4ee5e3964b44958b143
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
11 ; TODO: Should we convert these to X ^ ((X ^ Y) & M) form when Zbb isn't
12 ; present?
14 define 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
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
36 define 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
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
58 define 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
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
80 define 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
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
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
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
124 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
125 ; These tests should produce the same output as the corresponding out* test
126 ; when the Zbb extension is enabled.
127 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
129 define 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
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
149 define 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
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
169 define 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
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
189 define 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
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
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:    or a0, a0, a2
212 ; RV32ZBB-NEXT:    andn a2, a3, a5
213 ; RV32ZBB-NEXT:    and a1, a1, a5
214 ; RV32ZBB-NEXT:    or a1, a1, a2
215 ; RV32ZBB-NEXT:    ret
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
229 ; ============================================================================ ;
230 ; Commutativity tests.
231 ; ============================================================================ ;
233 define 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
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
253 define 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
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
273 define 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
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
293 define 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
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
313 define 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
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
333 define 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
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
353 define 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
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
373 ; ============================================================================ ;
374 ; Y is an 'and' too.
375 ; ============================================================================ ;
377 define 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
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
400 define 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
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
423 ; ============================================================================ ;
424 ; M is an 'xor' too.
425 ; ============================================================================ ;
427 define 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
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
450 define 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
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
473 ; ============================================================================ ;
474 ; Both Y and M are complex.
475 ; ============================================================================ ;
477 define 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
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
503 define 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
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
529 define 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
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
555 define 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
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
581 ; ============================================================================ ;
582 ; Various cases with %x and/or %y being a constant
583 ; ============================================================================ ;
585 define 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
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
605 define 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
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
624 ; This is not a canonical form. Testing for completeness only.
625 define 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
637 ; This is not a canonical form. Testing for completeness only.
638 define 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
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
660 define 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
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
683 define 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
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
703 ; This is not a canonical form. Testing for completeness only.
704 define 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
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
726 ; This is not a canonical form. Testing for completeness only.
727 define 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
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
749 define 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
761 define 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
772 ; This is not a canonical form. Testing for completeness only.
773 define 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
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
793 ; This is not a canonical form. Testing for completeness only.
794 define 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
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
812 define 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
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
834 define 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
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
854 ; This is not a canonical form. Testing for completeness only.
855 define 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
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
878 ; This is not a canonical form. Testing for completeness only.
879 define 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
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
901 ; ============================================================================ ;
902 ; Negative tests. Should not be folded.
903 ; ============================================================================ ;
905 ; Multi-use tests.
906 declare void @use32(i32) nounwind
907 define 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
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
950 define 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
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
991 ; Various bad variants
992 define 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
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
1014 define 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
1029 define 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