[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / unfold-masked-merge-scalar-constmask-lowhigh.ll
blob67b90c5f02aaeb97a0651abe7ca18378f2367ad0
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:               [byte1][byte0]
7 ; Y: [byte3][byte2]
9 define i8 @out8_constmask(i8 %x, i8 %y) {
10 ; CHECK-LABEL: out8_constmask:
11 ; CHECK:       // %bb.0:
12 ; CHECK-NEXT:    bfxil w1, w0, #0, #4
13 ; CHECK-NEXT:    mov w0, w1
14 ; CHECK-NEXT:    ret
15   %mx = and i8 %x, 15
16   %my = and i8 %y, -16
17   %r = or i8 %mx, %my
18   ret i8 %r
21 define i16 @out16_constmask(i16 %x, i16 %y) {
22 ; CHECK-LABEL: out16_constmask:
23 ; CHECK:       // %bb.0:
24 ; CHECK-NEXT:    bfxil w1, w0, #0, #8
25 ; CHECK-NEXT:    mov w0, w1
26 ; CHECK-NEXT:    ret
27   %mx = and i16 %x, 255
28   %my = and i16 %y, -256
29   %r = or i16 %mx, %my
30   ret i16 %r
33 define i32 @out32_constmask(i32 %x, i32 %y) {
34 ; CHECK-LABEL: out32_constmask:
35 ; CHECK:       // %bb.0:
36 ; CHECK-NEXT:    bfxil w1, w0, #0, #16
37 ; CHECK-NEXT:    mov w0, w1
38 ; CHECK-NEXT:    ret
39   %mx = and i32 %x, 65535
40   %my = and i32 %y, -65536
41   %r = or i32 %mx, %my
42   ret i32 %r
45 define i64 @out64_constmask(i64 %x, i64 %y) {
46 ; CHECK-LABEL: out64_constmask:
47 ; CHECK:       // %bb.0:
48 ; CHECK-NEXT:    bfxil x1, x0, #0, #32
49 ; CHECK-NEXT:    mov x0, x1
50 ; CHECK-NEXT:    ret
51   %mx = and i64 %x, 4294967295
52   %my = and i64 %y, -4294967296
53   %r = or i64 %mx, %my
54   ret i64 %r
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:
63 ; CHECK:       // %bb.0:
64 ; CHECK-NEXT:    eor w8, w0, w1
65 ; CHECK-NEXT:    and w8, w8, #0xf
66 ; CHECK-NEXT:    eor w0, w8, w1
67 ; CHECK-NEXT:    ret
68   %n0 = xor i8 %x, %y
69   %n1 = and i8 %n0, 15
70   %r = xor i8 %n1, %y
71   ret i8 %r
74 define i16 @in16_constmask(i16 %x, i16 %y) {
75 ; CHECK-LABEL: in16_constmask:
76 ; CHECK:       // %bb.0:
77 ; CHECK-NEXT:    eor w8, w0, w1
78 ; CHECK-NEXT:    and w8, w8, #0xff
79 ; CHECK-NEXT:    eor w0, w8, w1
80 ; CHECK-NEXT:    ret
81   %n0 = xor i16 %x, %y
82   %n1 = and i16 %n0, 255
83   %r = xor i16 %n1, %y
84   ret i16 %r
87 define i32 @in32_constmask(i32 %x, i32 %y) {
88 ; CHECK-LABEL: in32_constmask:
89 ; CHECK:       // %bb.0:
90 ; CHECK-NEXT:    eor w8, w0, w1
91 ; CHECK-NEXT:    and w8, w8, #0xffff
92 ; CHECK-NEXT:    eor w0, w8, w1
93 ; CHECK-NEXT:    ret
94   %n0 = xor i32 %x, %y
95   %n1 = and i32 %n0, 65535
96   %r = xor i32 %n1, %y
97   ret i32 %r
100 define i64 @in64_constmask(i64 %x, i64 %y) {
101 ; CHECK-LABEL: in64_constmask:
102 ; CHECK:       // %bb.0:
103 ; CHECK-NEXT:    eor w8, w0, w1
104 ; CHECK-NEXT:    eor x0, x8, x1
105 ; CHECK-NEXT:    ret
106   %n0 = xor i64 %x, %y
107   %n1 = and i64 %n0, 4294967295
108   %r = xor i64 %n1, %y
109   ret i64 %r
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:
118 ; CHECK:       // %bb.0:
119 ; CHECK-NEXT:    eor w8, w0, w1
120 ; CHECK-NEXT:    and w8, w8, #0xffff
121 ; CHECK-NEXT:    eor w0, w1, w8
122 ; CHECK-NEXT:    ret
123   %n0 = xor i32 %x, %y
124   %n1 = and i32 %n0, 65535
125   %r = xor i32 %y, %n1 ; swapped
126   ret i32 %r
129 define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {
130 ; CHECK-LABEL: in_constmask_commutativity_1_0:
131 ; CHECK:       // %bb.0:
132 ; CHECK-NEXT:    eor w8, w0, w1
133 ; CHECK-NEXT:    and w8, w8, #0xffff
134 ; CHECK-NEXT:    eor w0, w8, w0
135 ; CHECK-NEXT:    ret
136   %n0 = xor i32 %x, %y
137   %n1 = and i32 %n0, 65535
138   %r = xor i32 %n1, %x ; %x instead of %y
139   ret i32 %r
142 define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {
143 ; CHECK-LABEL: in_constmask_commutativity_1_1:
144 ; CHECK:       // %bb.0:
145 ; CHECK-NEXT:    eor w8, w0, w1
146 ; CHECK-NEXT:    and w8, w8, #0xffff
147 ; CHECK-NEXT:    eor w0, w0, w8
148 ; CHECK-NEXT:    ret
149   %n0 = xor i32 %x, %y
150   %n1 = and i32 %n0, 65535
151   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
152   ret i32 %r
155 ; ============================================================================ ;
156 ; Y is an 'and' too.
157 ; ============================================================================ ;
159 define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
160 ; CHECK-LABEL: in_complex_y0_constmask:
161 ; CHECK:       // %bb.0:
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
166 ; CHECK-NEXT:    ret
167   %y = and i32 %y_hi, %y_low
168   %n0 = xor i32 %x, %y
169   %n1 = and i32 %n0, 65535
170   %r = xor i32 %n1, %y
171   ret i32 %r
174 define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
175 ; CHECK-LABEL: in_complex_y1_constmask:
176 ; CHECK:       // %bb.0:
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
181 ; CHECK-NEXT:    ret
182   %y = and i32 %y_hi, %y_low
183   %n0 = xor i32 %x, %y
184   %n1 = and i32 %n0, 65535
185   %r = xor i32 %y, %n1
186   ret i32 %r
189 ; ============================================================================ ;
190 ; Negative tests. Should not be folded.
191 ; ============================================================================ ;
193 ; Multi-use tests.
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:
199 ; CHECK:       // %bb.0:
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:    mov w19, w1
204 ; CHECK-NEXT:    and w20, w8, #0xffff
205 ; CHECK-NEXT:    mov w0, w20
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
210 ; CHECK-NEXT:    ret
211   %n0 = xor i32 %x, %y
212   %n1 = and i32 %n0, 65535
213   call void @use32(i32 %n1)
214   %r = xor i32 %n1, %y
215   ret i32 %r
218 define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
219 ; CHECK-LABEL: in_multiuse_B_constmask:
220 ; CHECK:       // %bb.0:
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
230 ; CHECK-NEXT:    ret
231   %n0 = xor i32 %x, %y
232   %n1 = and i32 %n0, 65535
233   call void @use32(i32 %n0)
234   %r = xor i32 %n1, %y
235   ret i32 %r
238 ; Various bad variants
240 define i32 @n0_badconstmask(i32 %x, i32 %y) {
241 ; CHECK-LABEL: n0_badconstmask:
242 ; CHECK:       // %bb.0:
243 ; CHECK-NEXT:    and w8, w0, #0xffff
244 ; CHECK-NEXT:    and w9, w1, #0xffff0001
245 ; CHECK-NEXT:    orr w0, w8, w9
246 ; CHECK-NEXT:    ret
247   %mx = and i32 %x, 65535
248   %my = and i32 %y, -65535 ; instead of -65536
249   %r = or i32 %mx, %my
250   ret i32 %r
253 define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {
254 ; CHECK-LABEL: n1_thirdvar_constmask:
255 ; CHECK:       // %bb.0:
256 ; CHECK-NEXT:    eor w8, w0, w1
257 ; CHECK-NEXT:    and w8, w8, #0xffff
258 ; CHECK-NEXT:    eor w0, w8, w2
259 ; CHECK-NEXT:    ret
260   %n0 = xor i32 %x, %y
261   %n1 = and i32 %n0, 65535
262   %r = xor i32 %n1, %z ; instead of %y
263   ret i32 %r