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
9 define i8 @out8_constmask(i8 %x, i8 %y) {
10 ; CHECK-LABEL: out8_constmask:
12 ; CHECK-NEXT: bfxil w1, w0, #0, #4
13 ; CHECK-NEXT: mov w0, w1
21 define i16 @out16_constmask(i16 %x, i16 %y) {
22 ; CHECK-LABEL: out16_constmask:
24 ; CHECK-NEXT: bfxil w1, w0, #0, #8
25 ; CHECK-NEXT: mov w0, w1
28 %my = and i16 %y, -256
33 define i32 @out32_constmask(i32 %x, i32 %y) {
34 ; CHECK-LABEL: out32_constmask:
36 ; CHECK-NEXT: bfxil w1, w0, #0, #16
37 ; CHECK-NEXT: mov w0, w1
39 %mx = and i32 %x, 65535
40 %my = and i32 %y, -65536
45 define i64 @out64_constmask(i64 %x, i64 %y) {
46 ; CHECK-LABEL: out64_constmask:
48 ; CHECK-NEXT: bfxil x1, x0, #0, #32
49 ; CHECK-NEXT: mov x0, x1
51 %mx = and i64 %x, 4294967295
52 %my = and i64 %y, -4294967296
57 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
58 ; Should be the same as the previous one.
59 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
61 define i8 @in8_constmask(i8 %x, i8 %y) {
62 ; CHECK-LABEL: in8_constmask:
64 ; CHECK-NEXT: eor w8, w0, w1
65 ; CHECK-NEXT: and w8, w8, #0xf
66 ; CHECK-NEXT: eor w0, w8, w1
74 define i16 @in16_constmask(i16 %x, i16 %y) {
75 ; CHECK-LABEL: in16_constmask:
77 ; CHECK-NEXT: eor w8, w0, w1
78 ; CHECK-NEXT: and w8, w8, #0xff
79 ; CHECK-NEXT: eor w0, w8, w1
82 %n1 = and i16 %n0, 255
87 define i32 @in32_constmask(i32 %x, i32 %y) {
88 ; CHECK-LABEL: in32_constmask:
90 ; CHECK-NEXT: eor w8, w0, w1
91 ; CHECK-NEXT: and w8, w8, #0xffff
92 ; CHECK-NEXT: eor w0, w8, w1
95 %n1 = and i32 %n0, 65535
100 define i64 @in64_constmask(i64 %x, i64 %y) {
101 ; CHECK-LABEL: in64_constmask:
103 ; CHECK-NEXT: eor w8, w0, w1
104 ; CHECK-NEXT: eor x0, x8, x1
107 %n1 = and i64 %n0, 4294967295
112 ; ============================================================================ ;
113 ; Constant Commutativity tests.
114 ; ============================================================================ ;
116 define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {
117 ; CHECK-LABEL: in_constmask_commutativity_0_1:
119 ; CHECK-NEXT: eor w8, w0, w1
120 ; CHECK-NEXT: and w8, w8, #0xffff
121 ; CHECK-NEXT: eor w0, w1, w8
124 %n1 = and i32 %n0, 65535
125 %r = xor i32 %y, %n1 ; swapped
129 define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {
130 ; CHECK-LABEL: in_constmask_commutativity_1_0:
132 ; CHECK-NEXT: eor w8, w0, w1
133 ; CHECK-NEXT: and w8, w8, #0xffff
134 ; CHECK-NEXT: eor w0, w8, w0
137 %n1 = and i32 %n0, 65535
138 %r = xor i32 %n1, %x ; %x instead of %y
142 define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {
143 ; CHECK-LABEL: in_constmask_commutativity_1_1:
145 ; CHECK-NEXT: eor w8, w0, w1
146 ; CHECK-NEXT: and w8, w8, #0xffff
147 ; CHECK-NEXT: eor w0, w0, w8
150 %n1 = and i32 %n0, 65535
151 %r = xor i32 %x, %n1 ; swapped, %x instead of %y
155 ; ============================================================================ ;
157 ; ============================================================================ ;
159 define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
160 ; CHECK-LABEL: in_complex_y0_constmask:
162 ; CHECK-NEXT: and w8, w1, w2
163 ; CHECK-NEXT: eor w9, w0, w8
164 ; CHECK-NEXT: and w9, w9, #0xffff
165 ; CHECK-NEXT: eor w0, w9, w8
167 %y = and i32 %y_hi, %y_low
169 %n1 = and i32 %n0, 65535
174 define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
175 ; CHECK-LABEL: in_complex_y1_constmask:
177 ; CHECK-NEXT: and w8, w1, w2
178 ; CHECK-NEXT: eor w9, w0, w8
179 ; CHECK-NEXT: and w9, w9, #0xffff
180 ; CHECK-NEXT: eor w0, w8, w9
182 %y = and i32 %y_hi, %y_low
184 %n1 = and i32 %n0, 65535
189 ; ============================================================================ ;
190 ; Negative tests. Should not be folded.
191 ; ============================================================================ ;
195 declare void @use32(i32) nounwind
197 define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
198 ; CHECK-LABEL: in_multiuse_A_constmask:
200 ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
201 ; CHECK-NEXT: eor w8, w0, w1
202 ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
203 ; CHECK-NEXT: and w20, w8, #0xffff
204 ; CHECK-NEXT: mov w0, w20
205 ; CHECK-NEXT: mov w19, w1
206 ; CHECK-NEXT: bl use32
207 ; CHECK-NEXT: eor w0, w20, w19
208 ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
209 ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
212 %n1 = and i32 %n0, 65535
213 call void @use32(i32 %n1)
218 define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
219 ; CHECK-LABEL: in_multiuse_B_constmask:
221 ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
222 ; CHECK-NEXT: eor w0, w0, w1
223 ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
224 ; CHECK-NEXT: mov w19, w1
225 ; CHECK-NEXT: and w20, w0, #0xffff
226 ; CHECK-NEXT: bl use32
227 ; CHECK-NEXT: eor w0, w20, w19
228 ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
229 ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
232 %n1 = and i32 %n0, 65535
233 call void @use32(i32 %n0)
238 ; Various bad variants
240 define i32 @n0_badconstmask(i32 %x, i32 %y) {
241 ; CHECK-LABEL: n0_badconstmask:
243 ; CHECK-NEXT: and w8, w0, #0xffff
244 ; CHECK-NEXT: and w9, w1, #0xffff0001
245 ; CHECK-NEXT: orr w0, w8, w9
247 %mx = and i32 %x, 65535
248 %my = and i32 %y, -65535 ; instead of -65536
253 define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {
254 ; CHECK-LABEL: n1_thirdvar_constmask:
256 ; CHECK-NEXT: eor w8, w0, w1
257 ; CHECK-NEXT: and w8, w8, #0xffff
258 ; CHECK-NEXT: eor w0, w8, w2
261 %n1 = and i32 %n0, 65535
262 %r = xor i32 %n1, %z ; instead of %y