xref: /llvm-project/llvm/test/CodeGen/ARM/ldm-stm-base-materialization.ll (revision bed1c7f061aa12417aa081e334afdba45767b938)
1; RUN: llc -mtriple armv7a-none-eabi -mattr=-neon < %s -verify-machineinstrs -o - | FileCheck %s
2
3; Thumb1 (thumbv6m) is tested in tests/Thumb
4
5@a = external global ptr
6@b = external global ptr
7
8; Function Attrs: nounwind
9define void @foo24() #0 {
10entry:
11; CHECK-LABEL: foo24:
12; We use 'ptr' to allow 'r0'..'r12', 'lr'
13; CHECK: movt [[LB:[rl0-9]+]], :upper16:b
14; CHECK: movt [[SB:[rl0-9]+]], :upper16:a
15; CHECK: add [[NLB:[rl0-9]+]], [[LB]], #4
16; CHECK: add [[NSB:[rl0-9]+]], [[SB]], #4
17; CHECK-NEXT: ldm [[NLB]], {[[R1:[rl0-9]+]], [[R2:[rl0-9]+]], [[R3:[rl0-9]+]], [[R4:[rl0-9]+]], [[R5:[rl0-9]+]], [[R6:[rl0-9]+]]}
18; CHECK-NEXT: stm [[NSB]], {[[R1]], [[R2]], [[R3]], [[R4]], [[R5]], [[R6]]}
19  %0 = load ptr, ptr @a, align 4
20  %arrayidx = getelementptr inbounds i32, ptr %0, i32 1
21  %1 = load ptr, ptr @b, align 4
22  %arrayidx1 = getelementptr inbounds i32, ptr %1, i32 1
23  tail call void @llvm.memcpy.p0.p0.i32(ptr align 4 %arrayidx, ptr align 4 %arrayidx1, i32 24, i1 false)
24  ret void
25}
26
27define void @foo28() #0 {
28entry:
29; CHECK-LABEL: foo28:
30; CHECK: movt [[LB:[rl0-9]+]], :upper16:b
31; CHECK: movt [[SB:[rl0-9]+]], :upper16:a
32; CHECK: add [[NLB:[rl0-9]+]], [[LB]], #4
33; CHECK: add [[NSB:[rl0-9]+]], [[SB]], #4
34; CHECK-NEXT: ldm [[NLB]]!, {[[R1:[rl0-9]+]], [[R2:[rl0-9]+]], [[R3:[rl0-9]+]]}
35; CHECK-NEXT: stm [[NSB]]!, {[[R1]], [[R2]], [[R3]]}
36; CHECK-NEXT: ldm [[NLB]], {[[R1:[rl0-9]+]], [[R2:[rl0-9]+]], [[R3:[rl0-9]+]], [[R4:[rl0-9]+]]}
37; CHECK-NEXT: stm [[NSB]], {[[R1]], [[R2]], [[R3]], [[R4]]}
38  %0 = load ptr, ptr @a, align 4
39  %arrayidx = getelementptr inbounds i32, ptr %0, i32 1
40  %1 = load ptr, ptr @b, align 4
41  %arrayidx1 = getelementptr inbounds i32, ptr %1, i32 1
42  tail call void @llvm.memcpy.p0.p0.i32(ptr align 4 %arrayidx, ptr align 4 %arrayidx1, i32 28, i1 false)
43  ret void
44}
45
46define void @foo32() #0 {
47entry:
48; CHECK-LABEL: foo32:
49; CHECK: movt [[LB:[rl0-9]+]], :upper16:b
50; CHECK: movt [[SB:[rl0-9]+]], :upper16:a
51; CHECK: add [[NLB:[rl0-9]+]], [[LB]], #4
52; CHECK: add [[NSB:[rl0-9]+]], [[SB]], #4
53; CHECK-NEXT: ldm [[NLB]]!, {[[R1:[rl0-9]+]], [[R2:[rl0-9]+]], [[R3:[rl0-9]+]], [[R4:[rl0-9]+]]}
54; CHECK-NEXT: stm [[NSB]]!, {[[R1]], [[R2]], [[R3]], [[R4]]}
55; CHECK-NEXT: ldm [[NLB]], {[[R1:[rl0-9]+]], [[R2:[rl0-9]+]], [[R3:[rl0-9]+]], [[R4:[rl0-9]+]]}
56; CHECK-NEXT: stm [[NSB]], {[[R1]], [[R2]], [[R3]], [[R4]]}
57  %0 = load ptr, ptr @a, align 4
58  %arrayidx = getelementptr inbounds i32, ptr %0, i32 1
59  %1 = load ptr, ptr @b, align 4
60  %arrayidx1 = getelementptr inbounds i32, ptr %1, i32 1
61  tail call void @llvm.memcpy.p0.p0.i32(ptr align 4 %arrayidx, ptr align 4 %arrayidx1, i32 32, i1 false)
62  ret void
63}
64
65define void @foo36() #0 {
66entry:
67; CHECK-LABEL: foo36:
68; CHECK: movt [[LB:[rl0-9]+]], :upper16:b
69; CHECK: movt [[SB:[rl0-9]+]], :upper16:a
70; CHECK: add [[NLB:[rl0-9]+]], [[LB]], #4
71; CHECK: add [[NSB:[rl0-9]+]], [[SB]], #4
72; CHECK-NEXT: ldm [[NLB]]!, {[[R1:[rl0-9]+]], [[R2:[rl0-9]+]], [[R3:[rl0-9]+]], [[R4:[rl0-9]+]]}
73; CHECK-NEXT: stm [[NSB]]!, {[[R1]], [[R2]], [[R3]], [[R4]]}
74; CHECK-NEXT: ldm [[NLB]], {[[R1:[rl0-9]+]], [[R2:[rl0-9]+]], [[R3:[rl0-9]+]], [[R4:[rl0-9]+]], [[R5:[rl0-9]+]]}
75; CHECK-NEXT: stm [[NSB]], {[[R1]], [[R2]], [[R3]], [[R4]], [[R5]]}
76  %0 = load ptr, ptr @a, align 4
77  %arrayidx = getelementptr inbounds i32, ptr %0, i32 1
78  %1 = load ptr, ptr @b, align 4
79  %arrayidx1 = getelementptr inbounds i32, ptr %1, i32 1
80  tail call void @llvm.memcpy.p0.p0.i32(ptr align 4 %arrayidx, ptr align 4 %arrayidx1, i32 36, i1 false)
81  ret void
82}
83
84; Function Attrs: nounwind
85declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture readonly, i32, i1) #1
86