[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / AArch64 / unfold-masked-merge-scalar-constmask-interleavedbits.ll
blob2eeffe08199e85194201a19f85ac8b7504d82163
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
4 ; https://bugs.llvm.org/show_bug.cgi?id=37104
6 ; X:       [bit2]      [bit0]
7 ; Y: [bit3]      [bit1]
9 define i8 @out8_constmask(i8 %x, i8 %y) {
10 ; CHECK-LABEL: out8_constmask:
11 ; CHECK:       // %bb.0:
12 ; CHECK-NEXT:    mov w8, #85
13 ; CHECK-NEXT:    mov w9, #-86
14 ; CHECK-NEXT:    and w8, w0, w8
15 ; CHECK-NEXT:    and w9, w1, w9
16 ; CHECK-NEXT:    orr w0, w8, w9
17 ; CHECK-NEXT:    ret
18   %mx = and i8 %x, 85
19   %my = and i8 %y, -86
20   %r = or i8 %mx, %my
21   ret i8 %r
24 define i16 @out16_constmask(i16 %x, i16 %y) {
25 ; CHECK-LABEL: out16_constmask:
26 ; CHECK:       // %bb.0:
27 ; CHECK-NEXT:    mov w8, #21845
28 ; CHECK-NEXT:    mov w9, #-21846
29 ; CHECK-NEXT:    and w8, w0, w8
30 ; CHECK-NEXT:    and w9, w1, w9
31 ; CHECK-NEXT:    orr w0, w8, w9
32 ; CHECK-NEXT:    ret
33   %mx = and i16 %x, 21845
34   %my = and i16 %y, -21846
35   %r = or i16 %mx, %my
36   ret i16 %r
39 define i32 @out32_constmask(i32 %x, i32 %y) {
40 ; CHECK-LABEL: out32_constmask:
41 ; CHECK:       // %bb.0:
42 ; CHECK-NEXT:    and w8, w0, #0x55555555
43 ; CHECK-NEXT:    and w9, w1, #0xaaaaaaaa
44 ; CHECK-NEXT:    orr w0, w8, w9
45 ; CHECK-NEXT:    ret
46   %mx = and i32 %x, 1431655765
47   %my = and i32 %y, -1431655766
48   %r = or i32 %mx, %my
49   ret i32 %r
52 define i64 @out64_constmask(i64 %x, i64 %y) {
53 ; CHECK-LABEL: out64_constmask:
54 ; CHECK:       // %bb.0:
55 ; CHECK-NEXT:    and x8, x0, #0x5555555555555555
56 ; CHECK-NEXT:    and x9, x1, #0xaaaaaaaaaaaaaaaa
57 ; CHECK-NEXT:    orr x0, x8, x9
58 ; CHECK-NEXT:    ret
59   %mx = and i64 %x, 6148914691236517205
60   %my = and i64 %y, -6148914691236517206
61   %r = or i64 %mx, %my
62   ret i64 %r
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66 ; Should be the same as the previous one.
67 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
69 define i8 @in8_constmask(i8 %x, i8 %y) {
70 ; CHECK-LABEL: in8_constmask:
71 ; CHECK:       // %bb.0:
72 ; CHECK-NEXT:    eor w8, w0, w1
73 ; CHECK-NEXT:    mov w9, #85
74 ; CHECK-NEXT:    and w8, w8, w9
75 ; CHECK-NEXT:    eor w0, w8, w1
76 ; CHECK-NEXT:    ret
77   %n0 = xor i8 %x, %y
78   %n1 = and i8 %n0, 85
79   %r = xor i8 %n1, %y
80   ret i8 %r
83 define i16 @in16_constmask(i16 %x, i16 %y) {
84 ; CHECK-LABEL: in16_constmask:
85 ; CHECK:       // %bb.0:
86 ; CHECK-NEXT:    eor w8, w0, w1
87 ; CHECK-NEXT:    mov w9, #21845
88 ; CHECK-NEXT:    and w8, w8, w9
89 ; CHECK-NEXT:    eor w0, w8, w1
90 ; CHECK-NEXT:    ret
91   %n0 = xor i16 %x, %y
92   %n1 = and i16 %n0, 21845
93   %r = xor i16 %n1, %y
94   ret i16 %r
97 define i32 @in32_constmask(i32 %x, i32 %y) {
98 ; CHECK-LABEL: in32_constmask:
99 ; CHECK:       // %bb.0:
100 ; CHECK-NEXT:    eor w8, w0, w1
101 ; CHECK-NEXT:    and w8, w8, #0x55555555
102 ; CHECK-NEXT:    eor w0, w8, w1
103 ; CHECK-NEXT:    ret
104   %n0 = xor i32 %x, %y
105   %n1 = and i32 %n0, 1431655765
106   %r = xor i32 %n1, %y
107   ret i32 %r
110 define i64 @in64_constmask(i64 %x, i64 %y) {
111 ; CHECK-LABEL: in64_constmask:
112 ; CHECK:       // %bb.0:
113 ; CHECK-NEXT:    eor x8, x0, x1
114 ; CHECK-NEXT:    and x8, x8, #0x5555555555555555
115 ; CHECK-NEXT:    eor x0, x8, x1
116 ; CHECK-NEXT:    ret
117   %n0 = xor i64 %x, %y
118   %n1 = and i64 %n0, 6148914691236517205
119   %r = xor i64 %n1, %y
120   ret i64 %r
123 ; ============================================================================ ;
124 ; Constant Commutativity tests.
125 ; ============================================================================ ;
127 define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {
128 ; CHECK-LABEL: in_constmask_commutativity_0_1:
129 ; CHECK:       // %bb.0:
130 ; CHECK-NEXT:    eor w8, w0, w1
131 ; CHECK-NEXT:    and w8, w8, #0x55555555
132 ; CHECK-NEXT:    eor w0, w1, w8
133 ; CHECK-NEXT:    ret
134   %n0 = xor i32 %x, %y
135   %n1 = and i32 %n0, 1431655765
136   %r = xor i32 %y, %n1 ; swapped
137   ret i32 %r
140 define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {
141 ; CHECK-LABEL: in_constmask_commutativity_1_0:
142 ; CHECK:       // %bb.0:
143 ; CHECK-NEXT:    eor w8, w0, w1
144 ; CHECK-NEXT:    and w8, w8, #0x55555555
145 ; CHECK-NEXT:    eor w0, w8, w0
146 ; CHECK-NEXT:    ret
147   %n0 = xor i32 %x, %y
148   %n1 = and i32 %n0, 1431655765
149   %r = xor i32 %n1, %x ; %x instead of %y
150   ret i32 %r
153 define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {
154 ; CHECK-LABEL: in_constmask_commutativity_1_1:
155 ; CHECK:       // %bb.0:
156 ; CHECK-NEXT:    eor w8, w0, w1
157 ; CHECK-NEXT:    and w8, w8, #0x55555555
158 ; CHECK-NEXT:    eor w0, w0, w8
159 ; CHECK-NEXT:    ret
160   %n0 = xor i32 %x, %y
161   %n1 = and i32 %n0, 1431655765
162   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
163   ret i32 %r
166 ; ============================================================================ ;
167 ; Y is an 'and' too.
168 ; ============================================================================ ;
170 define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
171 ; CHECK-LABEL: in_complex_y0_constmask:
172 ; CHECK:       // %bb.0:
173 ; CHECK-NEXT:    and w8, w1, w2
174 ; CHECK-NEXT:    eor w9, w0, w8
175 ; CHECK-NEXT:    and w9, w9, #0x55555555
176 ; CHECK-NEXT:    eor w0, w9, w8
177 ; CHECK-NEXT:    ret
178   %y = and i32 %y_hi, %y_low
179   %n0 = xor i32 %x, %y
180   %n1 = and i32 %n0, 1431655765
181   %r = xor i32 %n1, %y
182   ret i32 %r
185 define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
186 ; CHECK-LABEL: in_complex_y1_constmask:
187 ; CHECK:       // %bb.0:
188 ; CHECK-NEXT:    and w8, w1, w2
189 ; CHECK-NEXT:    eor w9, w0, w8
190 ; CHECK-NEXT:    and w9, w9, #0x55555555
191 ; CHECK-NEXT:    eor w0, w8, w9
192 ; CHECK-NEXT:    ret
193   %y = and i32 %y_hi, %y_low
194   %n0 = xor i32 %x, %y
195   %n1 = and i32 %n0, 1431655765
196   %r = xor i32 %y, %n1
197   ret i32 %r
200 ; ============================================================================ ;
201 ; Negative tests. Should not be folded.
202 ; ============================================================================ ;
204 ; Multi-use tests.
206 declare void @use32(i32) nounwind
208 define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
209 ; CHECK-LABEL: in_multiuse_A_constmask:
210 ; CHECK:       // %bb.0:
211 ; CHECK-NEXT:    str x20, [sp, #-32]! // 8-byte Folded Spill
212 ; CHECK-NEXT:    eor w8, w0, w1
213 ; CHECK-NEXT:    and w20, w8, #0x55555555
214 ; CHECK-NEXT:    mov w0, w20
215 ; CHECK-NEXT:    stp x19, x30, [sp, #16] // 16-byte Folded Spill
216 ; CHECK-NEXT:    mov w19, w1
217 ; CHECK-NEXT:    bl use32
218 ; CHECK-NEXT:    eor w0, w20, w19
219 ; CHECK-NEXT:    ldp x19, x30, [sp, #16] // 16-byte Folded Reload
220 ; CHECK-NEXT:    ldr x20, [sp], #32 // 8-byte Folded Reload
221 ; CHECK-NEXT:    ret
222   %n0 = xor i32 %x, %y
223   %n1 = and i32 %n0, 1431655765
224   call void @use32(i32 %n1)
225   %r = xor i32 %n1, %y
226   ret i32 %r
229 define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
230 ; CHECK-LABEL: in_multiuse_B_constmask:
231 ; CHECK:       // %bb.0:
232 ; CHECK-NEXT:    str x20, [sp, #-32]! // 8-byte Folded Spill
233 ; CHECK-NEXT:    eor w0, w0, w1
234 ; CHECK-NEXT:    stp x19, x30, [sp, #16] // 16-byte Folded Spill
235 ; CHECK-NEXT:    mov w19, w1
236 ; CHECK-NEXT:    and w20, w0, #0x55555555
237 ; CHECK-NEXT:    bl use32
238 ; CHECK-NEXT:    eor w0, w20, w19
239 ; CHECK-NEXT:    ldp x19, x30, [sp, #16] // 16-byte Folded Reload
240 ; CHECK-NEXT:    ldr x20, [sp], #32 // 8-byte Folded Reload
241 ; CHECK-NEXT:    ret
242   %n0 = xor i32 %x, %y
243   %n1 = and i32 %n0, 1431655765
244   call void @use32(i32 %n0)
245   %r = xor i32 %n1, %y
246   ret i32 %r
249 ; Various bad variants
251 define i32 @n0_badconstmask(i32 %x, i32 %y) {
252 ; CHECK-LABEL: n0_badconstmask:
253 ; CHECK:       // %bb.0:
254 ; CHECK-NEXT:    mov w9, #43691
255 ; CHECK-NEXT:    movk w9, #43690, lsl #16
256 ; CHECK-NEXT:    and w8, w0, #0x55555555
257 ; CHECK-NEXT:    and w9, w1, w9
258 ; CHECK-NEXT:    orr w0, w8, w9
259 ; CHECK-NEXT:    ret
260   %mx = and i32 %x, 1431655765
261   %my = and i32 %y, -1431655765 ; instead of -1431655766
262   %r = or i32 %mx, %my
263   ret i32 %r
266 define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {
267 ; CHECK-LABEL: n1_thirdvar_constmask:
268 ; CHECK:       // %bb.0:
269 ; CHECK-NEXT:    eor w8, w0, w1
270 ; CHECK-NEXT:    and w8, w8, #0x55555555
271 ; CHECK-NEXT:    eor w0, w8, w2
272 ; CHECK-NEXT:    ret
273   %n0 = xor i32 %x, %y
274   %n1 = and i32 %n0, 1431655765
275   %r = xor i32 %n1, %z ; instead of %y
276   ret i32 %r