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: lsr w8, w0, #2
13 ; CHECK-NEXT: bfi w1, w8, #2, #4
14 ; CHECK-NEXT: mov w0, w1
22 define i16 @out16_constmask(i16 %x, i16 %y) {
23 ; CHECK-LABEL: out16_constmask:
25 ; CHECK-NEXT: lsr w8, w0, #4
26 ; CHECK-NEXT: bfi w1, w8, #4, #8
27 ; CHECK-NEXT: mov w0, w1
29 %mx = and i16 %x, 4080
30 %my = and i16 %y, -4081
35 define i32 @out32_constmask(i32 %x, i32 %y) {
36 ; CHECK-LABEL: out32_constmask:
38 ; CHECK-NEXT: lsr w8, w0, #8
39 ; CHECK-NEXT: bfi w1, w8, #8, #16
40 ; CHECK-NEXT: mov w0, w1
42 %mx = and i32 %x, 16776960
43 %my = and i32 %y, -16776961
48 define i64 @out64_constmask(i64 %x, i64 %y) {
49 ; CHECK-LABEL: out64_constmask:
51 ; CHECK-NEXT: lsr x8, x0, #16
52 ; CHECK-NEXT: bfi x1, x8, #16, #32
53 ; CHECK-NEXT: mov x0, x1
55 %mx = and i64 %x, 281474976645120
56 %my = and i64 %y, -281474976645121
61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62 ; Should be the same as the previous one.
63 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65 define i8 @in8_constmask(i8 %x, i8 %y) {
66 ; CHECK-LABEL: in8_constmask:
68 ; CHECK-NEXT: eor w8, w0, w1
69 ; CHECK-NEXT: and w8, w8, #0x3c
70 ; CHECK-NEXT: eor w0, w8, w1
78 define i16 @in16_constmask(i16 %x, i16 %y) {
79 ; CHECK-LABEL: in16_constmask:
81 ; CHECK-NEXT: eor w8, w0, w1
82 ; CHECK-NEXT: and w8, w8, #0xff0
83 ; CHECK-NEXT: eor w0, w8, w1
86 %n1 = and i16 %n0, 4080
91 define i32 @in32_constmask(i32 %x, i32 %y) {
92 ; CHECK-LABEL: in32_constmask:
94 ; CHECK-NEXT: eor w8, w0, w1
95 ; CHECK-NEXT: and w8, w8, #0xffff00
96 ; CHECK-NEXT: eor w0, w8, w1
99 %n1 = and i32 %n0, 16776960
104 define i64 @in64_constmask(i64 %x, i64 %y) {
105 ; CHECK-LABEL: in64_constmask:
107 ; CHECK-NEXT: eor x8, x0, x1
108 ; CHECK-NEXT: and x8, x8, #0xffffffff0000
109 ; CHECK-NEXT: eor x0, x8, x1
112 %n1 = and i64 %n0, 281474976645120
117 ; ============================================================================ ;
118 ; Constant Commutativity tests.
119 ; ============================================================================ ;
121 define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {
122 ; CHECK-LABEL: in_constmask_commutativity_0_1:
124 ; CHECK-NEXT: eor w8, w0, w1
125 ; CHECK-NEXT: and w8, w8, #0xffff00
126 ; CHECK-NEXT: eor w0, w1, w8
129 %n1 = and i32 %n0, 16776960
130 %r = xor i32 %y, %n1 ; swapped
134 define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {
135 ; CHECK-LABEL: in_constmask_commutativity_1_0:
137 ; CHECK-NEXT: eor w8, w0, w1
138 ; CHECK-NEXT: and w8, w8, #0xffff00
139 ; CHECK-NEXT: eor w0, w8, w0
142 %n1 = and i32 %n0, 16776960
143 %r = xor i32 %n1, %x ; %x instead of %y
147 define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {
148 ; CHECK-LABEL: in_constmask_commutativity_1_1:
150 ; CHECK-NEXT: eor w8, w0, w1
151 ; CHECK-NEXT: and w8, w8, #0xffff00
152 ; CHECK-NEXT: eor w0, w0, w8
155 %n1 = and i32 %n0, 16776960
156 %r = xor i32 %x, %n1 ; swapped, %x instead of %y
160 ; ============================================================================ ;
162 ; ============================================================================ ;
164 define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
165 ; CHECK-LABEL: in_complex_y0_constmask:
167 ; CHECK-NEXT: and w8, w1, w2
168 ; CHECK-NEXT: eor w9, w0, w8
169 ; CHECK-NEXT: and w9, w9, #0xffff00
170 ; CHECK-NEXT: eor w0, w9, w8
172 %y = and i32 %y_hi, %y_low
174 %n1 = and i32 %n0, 16776960
179 define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
180 ; CHECK-LABEL: in_complex_y1_constmask:
182 ; CHECK-NEXT: and w8, w1, w2
183 ; CHECK-NEXT: eor w9, w0, w8
184 ; CHECK-NEXT: and w9, w9, #0xffff00
185 ; CHECK-NEXT: eor w0, w8, w9
187 %y = and i32 %y_hi, %y_low
189 %n1 = and i32 %n0, 16776960
194 ; ============================================================================ ;
195 ; Negative tests. Should not be folded.
196 ; ============================================================================ ;
200 declare void @use32(i32) nounwind
202 define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
203 ; CHECK-LABEL: in_multiuse_A_constmask:
205 ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
206 ; CHECK-NEXT: eor w8, w0, w1
207 ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
208 ; CHECK-NEXT: and w20, w8, #0xffff00
209 ; CHECK-NEXT: mov w0, w20
210 ; CHECK-NEXT: mov w19, w1
211 ; CHECK-NEXT: bl use32
212 ; CHECK-NEXT: eor w0, w20, w19
213 ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
214 ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
217 %n1 = and i32 %n0, 16776960
218 call void @use32(i32 %n1)
223 define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
224 ; CHECK-LABEL: in_multiuse_B_constmask:
226 ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
227 ; CHECK-NEXT: eor w0, w0, w1
228 ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
229 ; CHECK-NEXT: mov w19, w1
230 ; CHECK-NEXT: and w20, w0, #0xffff00
231 ; CHECK-NEXT: bl use32
232 ; CHECK-NEXT: eor w0, w20, w19
233 ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
234 ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
237 %n1 = and i32 %n0, 16776960
238 call void @use32(i32 %n0)
243 ; Various bad variants
245 define i32 @n0_badconstmask(i32 %x, i32 %y) {
246 ; CHECK-LABEL: n0_badconstmask:
248 ; CHECK-NEXT: mov w9, #256
249 ; CHECK-NEXT: movk w9, #65280, lsl #16
250 ; CHECK-NEXT: and w8, w0, #0xffff00
251 ; CHECK-NEXT: and w9, w1, w9
252 ; CHECK-NEXT: orr w0, w8, w9
254 %mx = and i32 %x, 16776960
255 %my = and i32 %y, -16776960 ; instead of -16776961
260 define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {
261 ; CHECK-LABEL: n1_thirdvar_constmask:
263 ; CHECK-NEXT: eor w8, w0, w1
264 ; CHECK-NEXT: and w8, w8, #0xffff00
265 ; CHECK-NEXT: eor w0, w8, w2
268 %n1 = and i32 %n0, 16776960
269 %r = xor i32 %n1, %z ; instead of %y