xref: /llvm-project/llvm/test/CodeGen/Thumb/frame-chain.ll (revision 0c0f765cab4b16eb0342d514584cdf64cabc433a)
1; RUN: llc -mtriple thumbv6m-arm-none-eabi -filetype asm -o - %s -frame-pointer=all --verify-machineinstrs | FileCheck %s --check-prefixes=FP,LEAF-FP
2; RUN: llc -mtriple thumbv6m-arm-none-eabi -filetype asm -o - %s -frame-pointer=all -mattr=+aapcs-frame-chain --verify-machineinstrs | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-FP-AAPCS
3; RUN: llc -mtriple thumbv6m-arm-none-eabi -filetype asm -o - %s -frame-pointer=non-leaf --verify-machineinstrs | FileCheck %s --check-prefixes=FP,LEAF-NOFP
4; RUN: llc -mtriple thumbv6m-arm-none-eabi -filetype asm -o - %s -frame-pointer=non-leaf -mattr=+aapcs-frame-chain --verify-machineinstrs | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-NOFP-AAPCS
5; RUN: llc -mtriple thumbv6m-arm-none-eabi -filetype asm -o - %s -frame-pointer=none --verify-machineinstrs | FileCheck %s --check-prefixes=NOFP,LEAF-NOFP
6; RUN: llc -mtriple thumbv6m-arm-none-eabi -filetype asm -o - %s -frame-pointer=none -mattr=+aapcs-frame-chain --verify-machineinstrs | FileCheck %s --check-prefixes=NOFP-AAPCS,LEAF-NOFP-AAPCS
7
8define dso_local noundef i32 @leaf(i32 noundef %0) {
9; LEAF-FP-LABEL: leaf:
10; LEAF-FP:       @ %bb.0:
11; LEAF-FP-NEXT:    .save	{r7, lr}
12; LEAF-FP-NEXT:    push	{r7, lr}
13; LEAF-FP-NEXT:	   .setfp	r7, sp
14; LEAF-FP-NEXT:	   add	r7, sp, #0
15; LEAF-FP-NEXT:	   .pad	#4
16; LEAF-FP-NEXT:	   sub	sp, #4
17; LEAF-FP-NEXT:	   str	r0, [sp]
18; LEAF-FP-NEXT:	   adds	r0, r0, #4
19; LEAF-FP-NEXT:	   add	sp, #4
20; LEAF-FP-NEXT:	   pop	{r7, pc}
21;
22; LEAF-FP-AAPCS-LABEL: leaf:
23; LEAF-FP-AAPCS:       @ %bb.0:
24; LEAF-FP-AAPCS-NEXT:    .save {lr}
25; LEAF-FP-AAPCS-NEXT:    push {lr}
26; LEAF-FP-AAPCS-NEXT:    mov r3, r11
27; LEAF-FP-AAPCS-NEXT:    .save {r11}
28; LEAF-FP-AAPCS-NEXT:    push {r3}
29; LEAF-FP-AAPCS-NEXT:    .setfp r11, sp
30; LEAF-FP-AAPCS-NEXT:    mov r11, sp
31; LEAF-FP-AAPCS-NEXT:    .pad #4
32; LEAF-FP-AAPCS-NEXT:    sub sp, #4
33; LEAF-FP-AAPCS-NEXT:    str r0, [sp]
34; LEAF-FP-AAPCS-NEXT:    adds r0, r0, #4
35; LEAF-FP-AAPCS-NEXT:    add sp, #4
36; LEAF-FP-AAPCS-NEXT:    pop {r1}
37; LEAF-FP-AAPCS-NEXT:    mov r11, r1
38; LEAF-FP-AAPCS-NEXT:    pop {pc}
39;
40; LEAF-NOFP-LABEL: leaf:
41; LEAF-NOFP:       @ %bb.0:
42; LEAF-NOFP-NEXT:    .pad #4
43; LEAF-NOFP-NEXT:    sub sp, #4
44; LEAF-NOFP-NEXT:    str r0, [sp]
45; LEAF-NOFP-NEXT:    adds r0, r0, #4
46; LEAF-NOFP-NEXT:    add sp, #4
47; LEAF-NOFP-NEXT:    bx lr
48;
49; LEAF-NOFP-AAPCS-LABEL: leaf:
50; LEAF-NOFP-AAPCS:       @ %bb.0:
51; LEAF-NOFP-AAPCS-NEXT:    .pad #4
52; LEAF-NOFP-AAPCS-NEXT:    sub sp, #4
53; LEAF-NOFP-AAPCS-NEXT:    str r0, [sp]
54; LEAF-NOFP-AAPCS-NEXT:    adds r0, r0, #4
55; LEAF-NOFP-AAPCS-NEXT:    add sp, #4
56; LEAF-NOFP-AAPCS-NEXT:    bx lr
57  %2 = alloca i32, align 4
58  store i32 %0, ptr %2, align 4
59  %3 = load i32, ptr %2, align 4
60  %4 = add nsw i32 %3, 4
61  ret i32 %4
62}
63
64define dso_local noundef i32 @non_leaf(i32 noundef %0) {
65; FP-LABEL: non_leaf:
66; FP:       @ %bb.0:
67; FP-NEXT:    .save {r7, lr}
68; FP-NEXT:    push {r7, lr}
69; FP-NEXT:    .setfp r7, sp
70; FP-NEXT:    add r7, sp, #0
71; FP-NEXT:    .pad #8
72; FP-NEXT:    sub sp, #8
73; FP-NEXT:    str r0, [sp, #4]
74; FP-NEXT:    bl leaf
75; FP-NEXT:    adds r0, r0, #1
76; FP-NEXT:    add sp, #8
77; FP-NEXT:    pop {r7, pc}
78;
79; FP-AAPCS-LABEL: non_leaf:
80; FP-AAPCS:       @ %bb.0:
81; FP-AAPCS-NEXT:    .save {lr}
82; FP-AAPCS-NEXT:    push {lr}
83; FP-AAPCS-NEXT:    mov r3, r11
84; FP-AAPCS-NEXT:    .save {r11}
85; FP-AAPCS-NEXT:    push {r3}
86; FP-AAPCS-NEXT:    .setfp r11, sp
87; FP-AAPCS-NEXT:    mov r11, sp
88; FP-AAPCS-NEXT:    .pad #8
89; FP-AAPCS-NEXT:    sub sp, #8
90; FP-AAPCS-NEXT:    str r0, [sp, #4]
91; FP-AAPCS-NEXT:    bl leaf
92; FP-AAPCS-NEXT:    adds r0, r0, #1
93; FP-AAPCS-NEXT:    add sp, #8
94; FP-AAPCS-NEXT:    pop {r1}
95; FP-AAPCS-NEXT:    mov r11, r1
96; FP-AAPCS-NEXT:    pop {pc}
97;
98; NOFP-LABEL: non_leaf:
99; NOFP:       @ %bb.0:
100; NOFP-NEXT:    .save {r7, lr}
101; NOFP-NEXT:    push {r7, lr}
102; NOFP-NEXT:    .pad #8
103; NOFP-NEXT:    sub sp, #8
104; NOFP-NEXT:    str r0, [sp, #4]
105; NOFP-NEXT:    bl leaf
106; NOFP-NEXT:    adds r0, r0, #1
107; NOFP-NEXT:    add sp, #8
108; NOFP-NEXT:    pop {r7, pc}
109;
110; NOFP-AAPCS-LABEL: non_leaf:
111; NOFP-AAPCS:       @ %bb.0:
112; NOFP-AAPCS-NEXT:    .save {r7, lr}
113; NOFP-AAPCS-NEXT:    push {r7, lr}
114; NOFP-AAPCS-NEXT:    .pad #8
115; NOFP-AAPCS-NEXT:    sub sp, #8
116; NOFP-AAPCS-NEXT:    str r0, [sp, #4]
117; NOFP-AAPCS-NEXT:    bl leaf
118; NOFP-AAPCS-NEXT:    adds r0, r0, #1
119; NOFP-AAPCS-NEXT:    add sp, #8
120; NOFP-AAPCS-NEXT:    pop {r7, pc}
121  %2 = alloca i32, align 4
122  store i32 %0, ptr %2, align 4
123  %3 = load i32, ptr %2, align 4
124  %4 = call noundef i32 @leaf(i32 noundef %3)
125  %5 = add nsw i32 %4, 1
126  ret i32 %5
127}
128
129declare ptr @llvm.stacksave()
130define dso_local void @required_fp(i32 %0, i32 %1) {
131; FP-LABEL: required_fp:
132; FP:       @ %bb.0:
133; FP-NEXT:    .save {r4, r6, r7, lr}
134; FP-NEXT:    push {r4, r6, r7, lr}
135; FP-NEXT:    .setfp r7, sp, #8
136; FP-NEXT:    add r7, sp, #8
137; FP-NEXT:    .pad #24
138; FP-NEXT:    sub sp, #24
139; FP-NEXT:    mov r6, sp
140; FP-NEXT:    mov r2, r6
141; FP-NEXT:    str r1, [r2, #16]
142; FP-NEXT:    str r0, [r2, #20]
143; FP-NEXT:    mov r1, sp
144; FP-NEXT:    str r1, [r2, #8]
145; FP-NEXT:    lsls r1, r0, #2
146; FP-NEXT:    adds r1, r1, #7
147; FP-NEXT:    movs r3, #7
148; FP-NEXT:    bics r1, r3
149; FP-NEXT:    mov r3, sp
150; FP-NEXT:    subs r1, r3, r1
151; FP-NEXT:    mov sp, r1
152; FP-NEXT:    movs r1, #0
153; FP-NEXT:    str r1, [r6, #4]
154; FP-NEXT:    str r0, [r2]
155; FP-NEXT:    subs r6, r7, #7
156; FP-NEXT:    subs r6, #1
157; FP-NEXT:    mov sp, r6
158; FP-NEXT:    pop {r4, r6, r7, pc}
159;
160; FP-AAPCS-LABEL: required_fp:
161; FP-AAPCS:       @ %bb.0:
162; FP-AAPCS-NEXT:    .save {lr}
163; FP-AAPCS-NEXT:    push {lr}
164; FP-AAPCS-NEXT:    mov r3, r11
165; FP-AAPCS-NEXT:    .save {r11}
166; FP-AAPCS-NEXT:    push {r3}
167; FP-AAPCS-NEXT:    .setfp r11, sp
168; FP-AAPCS-NEXT:    mov r11, sp
169; FP-AAPCS-NEXT:    .save {r4, r6}
170; FP-AAPCS-NEXT:    push {r4, r6}
171; FP-AAPCS-NEXT:    .pad #24
172; FP-AAPCS-NEXT:    sub sp, #24
173; FP-AAPCS-NEXT:    mov r6, sp
174; FP-AAPCS-NEXT:    mov r2, r6
175; FP-AAPCS-NEXT:    str r1, [r2, #16]
176; FP-AAPCS-NEXT:    str r0, [r2, #20]
177; FP-AAPCS-NEXT:    mov r1, sp
178; FP-AAPCS-NEXT:    str r1, [r2, #8]
179; FP-AAPCS-NEXT:    lsls r1, r0, #2
180; FP-AAPCS-NEXT:    adds r1, r1, #7
181; FP-AAPCS-NEXT:    movs r3, #7
182; FP-AAPCS-NEXT:    bics r1, r3
183; FP-AAPCS-NEXT:    mov r3, sp
184; FP-AAPCS-NEXT:    subs r1, r3, r1
185; FP-AAPCS-NEXT:    mov sp, r1
186; FP-AAPCS-NEXT:    movs r1, #0
187; FP-AAPCS-NEXT:    str r1, [r6, #4]
188; FP-AAPCS-NEXT:    str r0, [r2]
189; FP-AAPCS-NEXT:    mov r6, r11
190; FP-AAPCS-NEXT:    subs r6, #8
191; FP-AAPCS-NEXT:    mov sp, r6
192; FP-AAPCS-NEXT:    pop {r4, r6}
193; FP-AAPCS-NEXT:    pop {r0}
194; FP-AAPCS-NEXT:    mov r11, r0
195; FP-AAPCS-NEXT:    pop {pc}
196;
197; NOFP-LABEL: required_fp:
198; NOFP:       @ %bb.0:
199; NOFP-NEXT:    .save {r4, r6, r7, lr}
200; NOFP-NEXT:    push {r4, r6, r7, lr}
201; NOFP-NEXT:    .setfp r7, sp, #8
202; NOFP-NEXT:    add r7, sp, #8
203; NOFP-NEXT:    .pad #24
204; NOFP-NEXT:    sub sp, #24
205; NOFP-NEXT:    mov r6, sp
206; NOFP-NEXT:    mov r2, r6
207; NOFP-NEXT:    str r1, [r2, #16]
208; NOFP-NEXT:    str r0, [r2, #20]
209; NOFP-NEXT:    mov r1, sp
210; NOFP-NEXT:    str r1, [r2, #8]
211; NOFP-NEXT:    lsls r1, r0, #2
212; NOFP-NEXT:    adds r1, r1, #7
213; NOFP-NEXT:    movs r3, #7
214; NOFP-NEXT:    bics r1, r3
215; NOFP-NEXT:    mov r3, sp
216; NOFP-NEXT:    subs r1, r3, r1
217; NOFP-NEXT:    mov sp, r1
218; NOFP-NEXT:    movs r1, #0
219; NOFP-NEXT:    str r1, [r6, #4]
220; NOFP-NEXT:    str r0, [r2]
221; NOFP-NEXT:    subs r6, r7, #7
222; NOFP-NEXT:    subs r6, #1
223; NOFP-NEXT:    mov sp, r6
224; NOFP-NEXT:    pop {r4, r6, r7, pc}
225;
226; NOFP-AAPCS-LABEL: required_fp:
227; NOFP-AAPCS:       @ %bb.0:
228; NOFP-AAPCS-NEXT:    .save {lr}
229; NOFP-AAPCS-NEXT:    push {lr}
230; NOFP-AAPCS-NEXT:    mov r3, r11
231; NOFP-AAPCS-NEXT:    .save {r11}
232; NOFP-AAPCS-NEXT:    push {r3}
233; NOFP-AAPCS-NEXT:    .setfp r11, sp
234; NOFP-AAPCS-NEXT:    mov r11, sp
235; NOFP-AAPCS-NEXT:    .save {r4, r6}
236; NOFP-AAPCS-NEXT:    push {r4, r6}
237; NOFP-AAPCS-NEXT:    .pad #24
238; NOFP-AAPCS-NEXT:    sub sp, #24
239; NOFP-AAPCS-NEXT:    mov r6, sp
240; NOFP-AAPCS-NEXT:    mov r2, r6
241; NOFP-AAPCS-NEXT:    str r1, [r2, #16]
242; NOFP-AAPCS-NEXT:    str r0, [r2, #20]
243; NOFP-AAPCS-NEXT:    mov r1, sp
244; NOFP-AAPCS-NEXT:    str r1, [r2, #8]
245; NOFP-AAPCS-NEXT:    lsls r1, r0, #2
246; NOFP-AAPCS-NEXT:    adds r1, r1, #7
247; NOFP-AAPCS-NEXT:    movs r3, #7
248; NOFP-AAPCS-NEXT:    bics r1, r3
249; NOFP-AAPCS-NEXT:    mov r3, sp
250; NOFP-AAPCS-NEXT:    subs r1, r3, r1
251; NOFP-AAPCS-NEXT:    mov sp, r1
252; NOFP-AAPCS-NEXT:    movs r1, #0
253; NOFP-AAPCS-NEXT:    str r1, [r6, #4]
254; NOFP-AAPCS-NEXT:    str r0, [r2]
255; NOFP-AAPCS-NEXT:    mov r6, r11
256; NOFP-AAPCS-NEXT:    subs r6, #8
257; NOFP-AAPCS-NEXT:    mov sp, r6
258; NOFP-AAPCS-NEXT:    pop {r4, r6}
259; NOFP-AAPCS-NEXT:    pop {r0}
260; NOFP-AAPCS-NEXT:    mov r11, r0
261; NOFP-AAPCS-NEXT:    pop {pc}
262  %3 = alloca i32, align 4
263  %4 = alloca i32, align 4
264  %5 = alloca ptr, align 8
265  %6 = alloca i64, align 8
266  store i32 %0, ptr %3, align 4
267  store i32 %1, ptr %4, align 4
268  %7 = load i32, ptr %3, align 4
269  %8 = zext i32 %7 to i64
270  %9 = call ptr @llvm.stacksave()
271  store ptr %9, ptr %5, align 8
272  %10 = alloca i32, i64 %8, align 4
273  store i64 %8, ptr %6, align 8
274  ret void
275}
276