xref: /llvm-project/llvm/test/CodeGen/AArch64/combine-andintoload.ll (revision db158c7c830807caeeb0691739c41f1d522029e9)
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
4
5define 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
12;
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
24}
25
26define 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
33;
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
45}
46
47define 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
54;
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
66}
67
68define 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
75;
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
87}
88
89define 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
96;
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
108}
109
110define 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
117;
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
129}
130
131define 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
137;
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
149}
150
151define 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
157;
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
168}
169
170define 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
177;
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
189}
190
191define 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
198;
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
210}
211
212define 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
218;
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
229}
230
231define 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
238;
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
251}
252
253define 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
260;
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
273}
274
275define 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
282;
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
294}
295
296define 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
303;
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
316}
317
318define 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
326;
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
341}
342
343define 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
351;
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
366}
367
368define 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
375;
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
388}
389
390define 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
397;
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
410}
411
412define 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
426;
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
440entry:
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
456}
457