Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / AArch64 / combine-andintoload.ll
blobf0b8fef848998fb496d470887228d7d187cd1c44
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64 -o - | FileCheck %s
3 ; RUN: llc < %s -mtriple=aarch64_be -o - | FileCheck %s --check-prefix=CHECKBE
5 define i64 @load32_and16_and(ptr %p, i64 %y) {
6 ; CHECK-LABEL: load32_and16_and:
7 ; CHECK:       // %bb.0:
8 ; CHECK-NEXT:    ldr w8, [x0]
9 ; CHECK-NEXT:    and w8, w1, w8
10 ; CHECK-NEXT:    and x0, x8, #0xffff
11 ; CHECK-NEXT:    ret
13 ; CHECKBE-LABEL: load32_and16_and:
14 ; CHECKBE:       // %bb.0:
15 ; CHECKBE-NEXT:    ldr w8, [x0]
16 ; CHECKBE-NEXT:    and w8, w1, w8
17 ; CHECKBE-NEXT:    and x0, x8, #0xffff
18 ; CHECKBE-NEXT:    ret
19   %x = load i32, ptr %p, align 4
20   %xz = zext i32 %x to i64
21   %ym = and i64 %y, 65535
22   %r = and i64 %ym, %xz
23   ret i64 %r
26 define i64 @load32_and16_andr(ptr %p, i64 %y) {
27 ; CHECK-LABEL: load32_and16_andr:
28 ; CHECK:       // %bb.0:
29 ; CHECK-NEXT:    ldr w8, [x0]
30 ; CHECK-NEXT:    and w8, w1, w8
31 ; CHECK-NEXT:    and x0, x8, #0xffff
32 ; CHECK-NEXT:    ret
34 ; CHECKBE-LABEL: load32_and16_andr:
35 ; CHECKBE:       // %bb.0:
36 ; CHECKBE-NEXT:    ldr w8, [x0]
37 ; CHECKBE-NEXT:    and w8, w1, w8
38 ; CHECKBE-NEXT:    and x0, x8, #0xffff
39 ; CHECKBE-NEXT:    ret
40   %x = load i32, ptr %p, align 4
41   %xz = zext i32 %x to i64
42   %a = and i64 %y, %xz
43   %r = and i64 %a, 65535
44   ret i64 %r
47 define i64 @load32_and16_and_sext(ptr %p, i64 %y) {
48 ; CHECK-LABEL: load32_and16_and_sext:
49 ; CHECK:       // %bb.0:
50 ; CHECK-NEXT:    ldr w8, [x0]
51 ; CHECK-NEXT:    and w8, w1, w8
52 ; CHECK-NEXT:    and x0, x8, #0xffff
53 ; CHECK-NEXT:    ret
55 ; CHECKBE-LABEL: load32_and16_and_sext:
56 ; CHECKBE:       // %bb.0:
57 ; CHECKBE-NEXT:    ldr w8, [x0]
58 ; CHECKBE-NEXT:    and w8, w1, w8
59 ; CHECKBE-NEXT:    and x0, x8, #0xffff
60 ; CHECKBE-NEXT:    ret
61   %x = load i32, ptr %p, align 4
62   %xz = sext i32 %x to i64
63   %a = and i64 %y, %xz
64   %r = and i64 %a, 65535
65   ret i64 %r
68 define i64 @load32_and16_or(ptr %p, i64 %y) {
69 ; CHECK-LABEL: load32_and16_or:
70 ; CHECK:       // %bb.0:
71 ; CHECK-NEXT:    ldr w8, [x0]
72 ; CHECK-NEXT:    orr w8, w1, w8
73 ; CHECK-NEXT:    and x0, x8, #0xffff
74 ; CHECK-NEXT:    ret
76 ; CHECKBE-LABEL: load32_and16_or:
77 ; CHECKBE:       // %bb.0:
78 ; CHECKBE-NEXT:    ldr w8, [x0]
79 ; CHECKBE-NEXT:    orr w8, w1, w8
80 ; CHECKBE-NEXT:    and x0, x8, #0xffff
81 ; CHECKBE-NEXT:    ret
82   %x = load i32, ptr %p, align 4
83   %xz = zext i32 %x to i64
84   %a = or i64 %y, %xz
85   %r = and i64 %a, 65535
86   ret i64 %r
89 define i64 @load32_and16_orr(ptr %p, i64 %y) {
90 ; CHECK-LABEL: load32_and16_orr:
91 ; CHECK:       // %bb.0:
92 ; CHECK-NEXT:    ldr w8, [x0]
93 ; CHECK-NEXT:    and x9, x1, #0xffff
94 ; CHECK-NEXT:    orr x0, x9, x8
95 ; CHECK-NEXT:    ret
97 ; CHECKBE-LABEL: load32_and16_orr:
98 ; CHECKBE:       // %bb.0:
99 ; CHECKBE-NEXT:    ldr w8, [x0]
100 ; CHECKBE-NEXT:    and x9, x1, #0xffff
101 ; CHECKBE-NEXT:    orr x0, x9, x8
102 ; CHECKBE-NEXT:    ret
103   %x = load i32, ptr %p, align 4
104   %xz = zext i32 %x to i64
105   %ym = and i64 %y, 65535
106   %r = or i64 %ym, %xz
107   ret i64 %r
110 define i64 @load32_and16_xorm1(ptr %p) {
111 ; CHECK-LABEL: load32_and16_xorm1:
112 ; CHECK:       // %bb.0:
113 ; CHECK-NEXT:    ldr w8, [x0]
114 ; CHECK-NEXT:    mvn w8, w8
115 ; CHECK-NEXT:    and x0, x8, #0xffff
116 ; CHECK-NEXT:    ret
118 ; CHECKBE-LABEL: load32_and16_xorm1:
119 ; CHECKBE:       // %bb.0:
120 ; CHECKBE-NEXT:    ldr w8, [x0]
121 ; CHECKBE-NEXT:    mvn w8, w8
122 ; CHECKBE-NEXT:    and x0, x8, #0xffff
123 ; CHECKBE-NEXT:    ret
124   %x = load i32, ptr %p, align 4
125   %xz = zext i32 %x to i64
126   %a = xor i64 %xz, -1
127   %r = and i64 %a, 65535
128   ret i64 %r
131 define i64 @load64_and16(ptr %p, i128 %y) {
132 ; CHECK-LABEL: load64_and16:
133 ; CHECK:       // %bb.0:
134 ; CHECK-NEXT:    ldrh w8, [x0]
135 ; CHECK-NEXT:    and x0, x2, x8
136 ; CHECK-NEXT:    ret
138 ; CHECKBE-LABEL: load64_and16:
139 ; CHECKBE:       // %bb.0:
140 ; CHECKBE-NEXT:    ldrh w8, [x0, #6]
141 ; CHECKBE-NEXT:    and x0, x3, x8
142 ; CHECKBE-NEXT:    ret
143   %x = load i64, ptr %p, align 4
144   %xz = zext i64 %x to i128
145   %a = and i128 %y, %xz
146   %t = trunc i128 %a to i64
147   %r = and i64 %t, 65535
148   ret i64 %r
151 define i64 @load16_and16(ptr %p, i64 %y) {
152 ; CHECK-LABEL: load16_and16:
153 ; CHECK:       // %bb.0:
154 ; CHECK-NEXT:    ldrh w8, [x0]
155 ; CHECK-NEXT:    and x0, x1, x8
156 ; CHECK-NEXT:    ret
158 ; CHECKBE-LABEL: load16_and16:
159 ; CHECKBE:       // %bb.0:
160 ; CHECKBE-NEXT:    ldrh w8, [x0]
161 ; CHECKBE-NEXT:    and x0, x1, x8
162 ; CHECKBE-NEXT:    ret
163   %x = load i16, ptr %p, align 4
164   %xz = zext i16 %x to i64
165   %a = and i64 %y, %xz
166   %r = and i64 %a, 65535
167   ret i64 %r
170 define i64 @load16_and8(ptr %p, i64 %y) {
171 ; CHECK-LABEL: load16_and8:
172 ; CHECK:       // %bb.0:
173 ; CHECK-NEXT:    ldrh w8, [x0]
174 ; CHECK-NEXT:    and w8, w1, w8
175 ; CHECK-NEXT:    and x0, x8, #0xff
176 ; CHECK-NEXT:    ret
178 ; CHECKBE-LABEL: load16_and8:
179 ; CHECKBE:       // %bb.0:
180 ; CHECKBE-NEXT:    ldrh w8, [x0]
181 ; CHECKBE-NEXT:    and w8, w1, w8
182 ; CHECKBE-NEXT:    and x0, x8, #0xff
183 ; CHECKBE-NEXT:    ret
184   %x = load i16, ptr %p, align 4
185   %xz = zext i16 %x to i64
186   %a = and i64 %y, %xz
187   %r = and i64 %a, 255
188   ret i64 %r
191 define i64 @load16_and7(ptr %p, i64 %y) {
192 ; CHECK-LABEL: load16_and7:
193 ; CHECK:       // %bb.0:
194 ; CHECK-NEXT:    ldrh w8, [x0]
195 ; CHECK-NEXT:    and w8, w1, w8
196 ; CHECK-NEXT:    and x0, x8, #0x7f
197 ; CHECK-NEXT:    ret
199 ; CHECKBE-LABEL: load16_and7:
200 ; CHECKBE:       // %bb.0:
201 ; CHECKBE-NEXT:    ldrh w8, [x0]
202 ; CHECKBE-NEXT:    and w8, w1, w8
203 ; CHECKBE-NEXT:    and x0, x8, #0x7f
204 ; CHECKBE-NEXT:    ret
205   %x = load i16, ptr %p, align 4
206   %xz = zext i16 %x to i64
207   %a = and i64 %y, %xz
208   %r = and i64 %a, 127
209   ret i64 %r
212 define i64 @load8_and16(ptr %p, i64 %y) {
213 ; CHECK-LABEL: load8_and16:
214 ; CHECK:       // %bb.0:
215 ; CHECK-NEXT:    ldrb w8, [x0]
216 ; CHECK-NEXT:    and x0, x1, x8
217 ; CHECK-NEXT:    ret
219 ; CHECKBE-LABEL: load8_and16:
220 ; CHECKBE:       // %bb.0:
221 ; CHECKBE-NEXT:    ldrb w8, [x0]
222 ; CHECKBE-NEXT:    and x0, x1, x8
223 ; CHECKBE-NEXT:    ret
224   %x = load i8, ptr %p, align 4
225   %xz = zext i8 %x to i64
226   %a = and i64 %y, %xz
227   %r = and i64 %a, 65535
228   ret i64 %r
231 define i64 @load8_and16_zext(ptr %p, i8 %y) {
232 ; CHECK-LABEL: load8_and16_zext:
233 ; CHECK:       // %bb.0:
234 ; CHECK-NEXT:    ldrb w8, [x0]
235 ; CHECK-NEXT:    and w8, w1, w8
236 ; CHECK-NEXT:    and x0, x8, #0xff
237 ; CHECK-NEXT:    ret
239 ; CHECKBE-LABEL: load8_and16_zext:
240 ; CHECKBE:       // %bb.0:
241 ; CHECKBE-NEXT:    ldrb w8, [x0]
242 ; CHECKBE-NEXT:    and w8, w1, w8
243 ; CHECKBE-NEXT:    and x0, x8, #0xff
244 ; CHECKBE-NEXT:    ret
245   %x = load i8, ptr %p, align 4
246   %xz = zext i8 %x to i64
247   %yz = zext i8 %y to i64
248   %a = and i64 %yz, %xz
249   %r = and i64 %a, 65535
250   ret i64 %r
253 define i64 @load8_and16_sext(ptr %p, i8 %y) {
254 ; CHECK-LABEL: load8_and16_sext:
255 ; CHECK:       // %bb.0:
256 ; CHECK-NEXT:    ldrb w8, [x0]
257 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
258 ; CHECK-NEXT:    and x0, x1, x8
259 ; CHECK-NEXT:    ret
261 ; CHECKBE-LABEL: load8_and16_sext:
262 ; CHECKBE:       // %bb.0:
263 ; CHECKBE-NEXT:    ldrb w8, [x0]
264 ; CHECKBE-NEXT:    // kill: def $w1 killed $w1 def $x1
265 ; CHECKBE-NEXT:    and x0, x1, x8
266 ; CHECKBE-NEXT:    ret
267   %x = load i8, ptr %p, align 4
268   %xz = zext i8 %x to i64
269   %yz = sext i8 %y to i64
270   %a = and i64 %yz, %xz
271   %r = and i64 %a, 65535
272   ret i64 %r
275 define i64 @load8_and16_or(ptr %p, i64 %y) {
276 ; CHECK-LABEL: load8_and16_or:
277 ; CHECK:       // %bb.0:
278 ; CHECK-NEXT:    ldrb w8, [x0]
279 ; CHECK-NEXT:    orr w8, w1, w8
280 ; CHECK-NEXT:    and x0, x8, #0xffff
281 ; CHECK-NEXT:    ret
283 ; CHECKBE-LABEL: load8_and16_or:
284 ; CHECKBE:       // %bb.0:
285 ; CHECKBE-NEXT:    ldrb w8, [x0]
286 ; CHECKBE-NEXT:    orr w8, w1, w8
287 ; CHECKBE-NEXT:    and x0, x8, #0xffff
288 ; CHECKBE-NEXT:    ret
289   %x = load i8, ptr %p, align 4
290   %xz = zext i8 %x to i64
291   %a = or i64 %y, %xz
292   %r = and i64 %a, 65535
293   ret i64 %r
296 define i64 @load16_and8_manyext(ptr %p, i32 %y) {
297 ; CHECK-LABEL: load16_and8_manyext:
298 ; CHECK:       // %bb.0:
299 ; CHECK-NEXT:    ldrh w8, [x0]
300 ; CHECK-NEXT:    and w8, w1, w8
301 ; CHECK-NEXT:    and x0, x8, #0xff
302 ; CHECK-NEXT:    ret
304 ; CHECKBE-LABEL: load16_and8_manyext:
305 ; CHECKBE:       // %bb.0:
306 ; CHECKBE-NEXT:    ldrh w8, [x0]
307 ; CHECKBE-NEXT:    and w8, w1, w8
308 ; CHECKBE-NEXT:    and x0, x8, #0xff
309 ; CHECKBE-NEXT:    ret
310   %x = load i16, ptr %p, align 4
311   %xz = zext i16 %x to i32
312   %a = and i32 %y, %xz
313   %az = zext i32 %a to i64
314   %r = and i64 %az, 255
315   ret i64 %r
318 define i64 @multiple_load(ptr %p, ptr %q) {
319 ; CHECK-LABEL: multiple_load:
320 ; CHECK:       // %bb.0:
321 ; CHECK-NEXT:    ldrh w8, [x0]
322 ; CHECK-NEXT:    ldr w9, [x1]
323 ; CHECK-NEXT:    and w8, w9, w8
324 ; CHECK-NEXT:    and x0, x8, #0xff
325 ; CHECK-NEXT:    ret
327 ; CHECKBE-LABEL: multiple_load:
328 ; CHECKBE:       // %bb.0:
329 ; CHECKBE-NEXT:    ldrh w8, [x0]
330 ; CHECKBE-NEXT:    ldr w9, [x1]
331 ; CHECKBE-NEXT:    and w8, w9, w8
332 ; CHECKBE-NEXT:    and x0, x8, #0xff
333 ; CHECKBE-NEXT:    ret
334   %x = load i16, ptr %p, align 4
335   %xz = zext i16 %x to i64
336   %y = load i32, ptr %q, align 4
337   %yz = zext i32 %y to i64
338   %a = and i64 %yz, %xz
339   %r = and i64 %a, 255
340   ret i64 %r
343 define i64 @multiple_load_or(ptr %p, ptr %q) {
344 ; CHECK-LABEL: multiple_load_or:
345 ; CHECK:       // %bb.0:
346 ; CHECK-NEXT:    ldrh w8, [x0]
347 ; CHECK-NEXT:    ldr w9, [x1]
348 ; CHECK-NEXT:    orr w8, w9, w8
349 ; CHECK-NEXT:    and x0, x8, #0xff
350 ; CHECK-NEXT:    ret
352 ; CHECKBE-LABEL: multiple_load_or:
353 ; CHECKBE:       // %bb.0:
354 ; CHECKBE-NEXT:    ldrh w8, [x0]
355 ; CHECKBE-NEXT:    ldr w9, [x1]
356 ; CHECKBE-NEXT:    orr w8, w9, w8
357 ; CHECKBE-NEXT:    and x0, x8, #0xff
358 ; CHECKBE-NEXT:    ret
359   %x = load i16, ptr %p, align 4
360   %xz = zext i16 %x to i64
361   %y = load i32, ptr %q, align 4
362   %yz = zext i32 %y to i64
363   %a = or i64 %yz, %xz
364   %r = and i64 %a, 255
365   ret i64 %r
368 define i64 @load32_and16_zexty(ptr %p, i32 %y) {
369 ; CHECK-LABEL: load32_and16_zexty:
370 ; CHECK:       // %bb.0:
371 ; CHECK-NEXT:    ldr w8, [x0]
372 ; CHECK-NEXT:    orr w8, w1, w8
373 ; CHECK-NEXT:    and x0, x8, #0xffff
374 ; CHECK-NEXT:    ret
376 ; CHECKBE-LABEL: load32_and16_zexty:
377 ; CHECKBE:       // %bb.0:
378 ; CHECKBE-NEXT:    ldr w8, [x0]
379 ; CHECKBE-NEXT:    orr w8, w1, w8
380 ; CHECKBE-NEXT:    and x0, x8, #0xffff
381 ; CHECKBE-NEXT:    ret
382   %x = load i32, ptr %p, align 4
383   %xz = zext i32 %x to i64
384   %yz = zext i32 %y to i64
385   %a = or i64 %yz, %xz
386   %r = and i64 %a, 65535
387   ret i64 %r
390 define i64 @load32_and16_sexty(ptr %p, i32 %y) {
391 ; CHECK-LABEL: load32_and16_sexty:
392 ; CHECK:       // %bb.0:
393 ; CHECK-NEXT:    ldr w8, [x0]
394 ; CHECK-NEXT:    orr w8, w1, w8
395 ; CHECK-NEXT:    and x0, x8, #0xffff
396 ; CHECK-NEXT:    ret
398 ; CHECKBE-LABEL: load32_and16_sexty:
399 ; CHECKBE:       // %bb.0:
400 ; CHECKBE-NEXT:    ldr w8, [x0]
401 ; CHECKBE-NEXT:    orr w8, w1, w8
402 ; CHECKBE-NEXT:    and x0, x8, #0xffff
403 ; CHECKBE-NEXT:    ret
404   %x = load i32, ptr %p, align 4
405   %xz = zext i32 %x to i64
406   %yz = sext i32 %y to i64
407   %a = or i64 %yz, %xz
408   %r = and i64 %a, 65535
409   ret i64 %r
412 define zeroext i1 @bigger(ptr nocapture readonly %c, ptr nocapture readonly %e, i64 %d, i64 %p1) {
413 ; CHECK-LABEL: bigger:
414 ; CHECK:       // %bb.0: // %entry
415 ; CHECK-NEXT:    ldrb w8, [x1, x2]
416 ; CHECK-NEXT:    ldrb w9, [x0, x2]
417 ; CHECK-NEXT:    and w10, w3, #0x7
418 ; CHECK-NEXT:    mov w11, #8 // =0x8
419 ; CHECK-NEXT:    sub w10, w11, w10
420 ; CHECK-NEXT:    eor w8, w8, w9
421 ; CHECK-NEXT:    mov w9, #5 // =0x5
422 ; CHECK-NEXT:    lsr w8, w8, w10
423 ; CHECK-NEXT:    tst w8, w9
424 ; CHECK-NEXT:    cset w0, eq
425 ; CHECK-NEXT:    ret
427 ; CHECKBE-LABEL: bigger:
428 ; CHECKBE:       // %bb.0: // %entry
429 ; CHECKBE-NEXT:    ldrb w8, [x1, x2]
430 ; CHECKBE-NEXT:    ldrb w9, [x0, x2]
431 ; CHECKBE-NEXT:    and w10, w3, #0x7
432 ; CHECKBE-NEXT:    mov w11, #8 // =0x8
433 ; CHECKBE-NEXT:    sub w10, w11, w10
434 ; CHECKBE-NEXT:    eor w8, w8, w9
435 ; CHECKBE-NEXT:    mov w9, #5 // =0x5
436 ; CHECKBE-NEXT:    lsr w8, w8, w10
437 ; CHECKBE-NEXT:    tst w8, w9
438 ; CHECKBE-NEXT:    cset w0, eq
439 ; CHECKBE-NEXT:    ret
440 entry:
441   %0 = trunc i64 %p1 to i16
442   %1 = and i16 %0, 7
443   %sh_prom = sub nuw nsw i16 8, %1
444   %shl = shl nuw nsw i16 5, %sh_prom
445   %arrayidx = getelementptr inbounds i8, ptr %c, i64 %d
446   %2 = load i8, ptr %arrayidx, align 1
447   %3 = and i16 %shl, 255
448   %conv2 = zext i16 %3 to i32
449   %arrayidx3 = getelementptr inbounds i8, ptr %e, i64 %d
450   %4 = load i8, ptr %arrayidx3, align 1
451   %5 = xor i8 %4, %2
452   %6 = zext i8 %5 to i32
453   %7 = and i32 %6, %conv2
454   %cmp.not = icmp eq i32 %7, 0
455   ret i1 %cmp.not