1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
3
4; ============================================================================ ;
5; Various cases with %x and/or %y being a constant
6; ============================================================================ ;
7
8define <4 x i32> @out_constant_varx_mone(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
9; CHECK-LABEL: out_constant_varx_mone:
10; CHECK:       // %bb.0:
11; CHECK-NEXT:    and v0.16b, v2.16b, v0.16b
12; CHECK-NEXT:    orn v0.16b, v0.16b, v2.16b
13; CHECK-NEXT:    ret
14  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
15  %mx = and <4 x i32> %mask, %x
16  %my = and <4 x i32> %notmask, <i32 -1, i32 -1, i32 -1, i32 -1>
17  %r = or <4 x i32> %mx, %my
18  ret <4 x i32> %r
19}
20
21define <4 x i32> @in_constant_varx_mone(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
22; CHECK-LABEL: in_constant_varx_mone:
23; CHECK:       // %bb.0:
24; CHECK-NEXT:    bic v0.16b, v2.16b, v0.16b
25; CHECK-NEXT:    mvn v0.16b, v0.16b
26; CHECK-NEXT:    ret
27  %n0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> ; %x
28  %n1 = and <4 x i32> %n0, %mask
29  %r = xor <4 x i32> %n1, <i32 -1, i32 -1, i32 -1, i32 -1>
30  ret <4 x i32> %r
31}
32
33; This is not a canonical form. Testing for completeness only.
34define <4 x i32> @out_constant_varx_mone_invmask(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
35; CHECK-LABEL: out_constant_varx_mone_invmask:
36; CHECK:       // %bb.0:
37; CHECK-NEXT:    bic v0.16b, v0.16b, v2.16b
38; CHECK-NEXT:    orr v0.16b, v0.16b, v2.16b
39; CHECK-NEXT:    ret
40  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
41  %mx = and <4 x i32> %notmask, %x
42  %my = and <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
43  %r = or <4 x i32> %mx, %my
44  ret <4 x i32> %r
45}
46
47; This is not a canonical form. Testing for completeness only.
48define <4 x i32> @in_constant_varx_mone_invmask(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
49; CHECK-LABEL: in_constant_varx_mone_invmask:
50; CHECK:       // %bb.0:
51; CHECK-NEXT:    mvn v0.16b, v0.16b
52; CHECK-NEXT:    bic v0.16b, v0.16b, v2.16b
53; CHECK-NEXT:    mvn v0.16b, v0.16b
54; CHECK-NEXT:    ret
55  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
56  %n0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> ; %x
57  %n1 = and <4 x i32> %n0, %notmask
58  %r = xor <4 x i32> %n1, <i32 -1, i32 -1, i32 -1, i32 -1>
59  ret <4 x i32> %r
60}
61
62define <4 x i32> @out_constant_varx_42(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
63; CHECK-LABEL: out_constant_varx_42:
64; CHECK:       // %bb.0:
65; CHECK-NEXT:    movi v1.4s, #42
66; CHECK-NEXT:    bsl v2.16b, v0.16b, v1.16b
67; CHECK-NEXT:    mov v0.16b, v2.16b
68; CHECK-NEXT:    ret
69  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
70  %mx = and <4 x i32> %mask, %x
71  %my = and <4 x i32> %notmask, <i32 42, i32 42, i32 42, i32 42>
72  %r = or <4 x i32> %mx, %my
73  ret <4 x i32> %r
74}
75
76define <4 x i32> @in_constant_varx_42(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
77; CHECK-LABEL: in_constant_varx_42:
78; CHECK:       // %bb.0:
79; CHECK-NEXT:    movi v1.4s, #42
80; CHECK-NEXT:    bsl v2.16b, v0.16b, v1.16b
81; CHECK-NEXT:    mov v0.16b, v2.16b
82; CHECK-NEXT:    ret
83  %n0 = xor <4 x i32> %x, <i32 42, i32 42, i32 42, i32 42> ; %x
84  %n1 = and <4 x i32> %n0, %mask
85  %r = xor <4 x i32> %n1, <i32 42, i32 42, i32 42, i32 42>
86  ret <4 x i32> %r
87}
88
89; This is not a canonical form. Testing for completeness only.
90define <4 x i32> @out_constant_varx_42_invmask(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
91; CHECK-LABEL: out_constant_varx_42_invmask:
92; CHECK:       // %bb.0:
93; CHECK-NEXT:    movi v1.4s, #42
94; CHECK-NEXT:    bsl v2.16b, v1.16b, v0.16b
95; CHECK-NEXT:    mov v0.16b, v2.16b
96; CHECK-NEXT:    ret
97  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
98  %mx = and <4 x i32> %notmask, %x
99  %my = and <4 x i32> %mask, <i32 42, i32 42, i32 42, i32 42>
100  %r = or <4 x i32> %mx, %my
101  ret <4 x i32> %r
102}
103
104; This is not a canonical form. Testing for completeness only.
105define <4 x i32> @in_constant_varx_42_invmask(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
106; CHECK-LABEL: in_constant_varx_42_invmask:
107; CHECK:       // %bb.0:
108; CHECK-NEXT:    movi v1.4s, #42
109; CHECK-NEXT:    bsl v2.16b, v1.16b, v0.16b
110; CHECK-NEXT:    mov v0.16b, v2.16b
111; CHECK-NEXT:    ret
112  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
113  %n0 = xor <4 x i32> %x, <i32 42, i32 42, i32 42, i32 42> ; %x
114  %n1 = and <4 x i32> %n0, %notmask
115  %r = xor <4 x i32> %n1, <i32 42, i32 42, i32 42, i32 42>
116  ret <4 x i32> %r
117}
118
119define <4 x i32> @out_constant_mone_vary(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
120; CHECK-LABEL: out_constant_mone_vary:
121; CHECK:       // %bb.0:
122; CHECK-NEXT:    bic v0.16b, v1.16b, v2.16b
123; CHECK-NEXT:    orr v0.16b, v2.16b, v0.16b
124; CHECK-NEXT:    ret
125  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
126  %mx = and <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
127  %my = and <4 x i32> %notmask, %y
128  %r = or <4 x i32> %mx, %my
129  ret <4 x i32> %r
130}
131
132define <4 x i32> @in_constant_mone_vary(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
133; CHECK-LABEL: in_constant_mone_vary:
134; CHECK:       // %bb.0:
135; CHECK-NEXT:    bic v0.16b, v1.16b, v2.16b
136; CHECK-NEXT:    orr v0.16b, v2.16b, v0.16b
137; CHECK-NEXT:    ret
138  %n0 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %y ; %x
139  %n1 = and <4 x i32> %n0, %mask
140  %r = xor <4 x i32> %n1, %y
141  ret <4 x i32> %r
142}
143
144; This is not a canonical form. Testing for completeness only.
145define <4 x i32> @out_constant_mone_vary_invmask(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
146; CHECK-LABEL: out_constant_mone_vary_invmask:
147; CHECK:       // %bb.0:
148; CHECK-NEXT:    and v0.16b, v2.16b, v1.16b
149; CHECK-NEXT:    orn v0.16b, v0.16b, v2.16b
150; CHECK-NEXT:    ret
151  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
152  %mx = and <4 x i32> %notmask, <i32 -1, i32 -1, i32 -1, i32 -1>
153  %my = and <4 x i32> %mask, %y
154  %r = or <4 x i32> %mx, %my
155  ret <4 x i32> %r
156}
157
158; This is not a canonical form. Testing for completeness only.
159define <4 x i32> @in_constant_mone_vary_invmask(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
160; CHECK-LABEL: in_constant_mone_vary_invmask:
161; CHECK:       // %bb.0:
162; CHECK-NEXT:    and v0.16b, v1.16b, v2.16b
163; CHECK-NEXT:    orn v0.16b, v0.16b, v2.16b
164; CHECK-NEXT:    ret
165  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
166  %n0 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %y ; %x
167  %n1 = and <4 x i32> %n0, %notmask
168  %r = xor <4 x i32> %n1, %y
169  ret <4 x i32> %r
170}
171
172define <4 x i32> @out_constant_42_vary(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
173; CHECK-LABEL: out_constant_42_vary:
174; CHECK:       // %bb.0:
175; CHECK-NEXT:    mov v0.16b, v2.16b
176; CHECK-NEXT:    movi v2.4s, #42
177; CHECK-NEXT:    bsl v0.16b, v2.16b, v1.16b
178; CHECK-NEXT:    ret
179  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
180  %mx = and <4 x i32> %mask, <i32 42, i32 42, i32 42, i32 42>
181  %my = and <4 x i32> %notmask, %y
182  %r = or <4 x i32> %mx, %my
183  ret <4 x i32> %r
184}
185
186define <4 x i32> @in_constant_42_vary(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
187; CHECK-LABEL: in_constant_42_vary:
188; CHECK:       // %bb.0:
189; CHECK-NEXT:    mov v0.16b, v2.16b
190; CHECK-NEXT:    movi v2.4s, #42
191; CHECK-NEXT:    bsl v0.16b, v2.16b, v1.16b
192; CHECK-NEXT:    ret
193  %n0 = xor <4 x i32> <i32 42, i32 42, i32 42, i32 42>, %y ; %x
194  %n1 = and <4 x i32> %n0, %mask
195  %r = xor <4 x i32> %n1, %y
196  ret <4 x i32> %r
197}
198
199; This is not a canonical form. Testing for completeness only.
200define <4 x i32> @out_constant_42_vary_invmask(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
201; CHECK-LABEL: out_constant_42_vary_invmask:
202; CHECK:       // %bb.0:
203; CHECK-NEXT:    mov v0.16b, v2.16b
204; CHECK-NEXT:    movi v2.4s, #42
205; CHECK-NEXT:    bsl v0.16b, v1.16b, v2.16b
206; CHECK-NEXT:    ret
207  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
208  %mx = and <4 x i32> %notmask, <i32 42, i32 42, i32 42, i32 42>
209  %my = and <4 x i32> %mask, %y
210  %r = or <4 x i32> %mx, %my
211  ret <4 x i32> %r
212}
213
214; This is not a canonical form. Testing for completeness only.
215define <4 x i32> @in_constant_42_vary_invmask(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
216; CHECK-LABEL: in_constant_42_vary_invmask:
217; CHECK:       // %bb.0:
218; CHECK-NEXT:    mov v0.16b, v2.16b
219; CHECK-NEXT:    movi v2.4s, #42
220; CHECK-NEXT:    bsl v0.16b, v1.16b, v2.16b
221; CHECK-NEXT:    ret
222  %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
223  %n0 = xor <4 x i32> <i32 42, i32 42, i32 42, i32 42>, %y ; %x
224  %n1 = and <4 x i32> %n0, %notmask
225  %r = xor <4 x i32> %n1, %y
226  ret <4 x i32> %r
227}
228