brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 0ca7205 Raw
161 lines · plain
1; RUN: llc -mtriple=thumbv7m-none-eabi -o - %s | FileCheck %s2 3declare void @foo()4 5; Leaf function, no frame so no need for a frame pointer.6define void @leaf() {7; CHECK-LABEL: leaf:8; CHECK-NOT: push9; CHECK-NOT: sp10; CHECK-NOT: pop11; CHECK: bx lr12  ret void13}14 15; Leaf function, frame pointer is requested but we don't need any stack frame,16; so don't create a frame pointer.17define void @leaf_nofpelim() "frame-pointer"="none" {18; CHECK-LABEL: leaf_nofpelim:19; CHECK-NOT: push20; CHECK-NOT: sp21; CHECK-NOT: pop22; CHECK: bx lr23  ret void24}25 26; Leaf function, frame pointer is requested and we need a stack frame, so we27; need to use a frame pointer.28define void @leaf_lowreg_nofpelim() "frame-pointer"="all" {29; CHECK-LABEL: leaf_lowreg_nofpelim:30; CHECK: push {r4, r6, r7, lr}31; CHECK: add r7, sp, #832; CHECK: pop {r4, r6, r7, pc}33  call void asm sideeffect "", "~{r4}" ()34  ret void35}36 37; Leaf function, frame pointer is requested and we need a stack frame, so we38; need to use a frame pointer. A high register is pushed to the stack, so we39; must use two push/pop instructions to ensure that fp and sp are adjacent on40; the stack.41define void @leaf_highreg_nofpelim() "frame-pointer"="all" {42; CHECK-LABEL: leaf_highreg_nofpelim:43; CHECK: push {r6, r7, lr}44; CHECK: add r7, sp, #445; CHECK: str r8, [sp, #-4]!46; CHECK: ldr r8, [sp], #447; CHECK: pop {r6, r7, pc}48  call void asm sideeffect "", "~{r8}" ()49  ret void50}51 52; Leaf function, frame pointer requested for non-leaf functions only, so no53; need for a stack frame.54define void @leaf_nononleaffpelim() "frame-pointer"="non-leaf" {55; CHECK-LABEL: leaf_nononleaffpelim:56; CHECK-NOT: push57; CHECK-NOT: sp58; CHECK-NOT: pop59; CHECK: bx lr60  ret void61}62 63; Has a call, but still no need for a frame pointer.64define void @call() {65; CHECK-LABEL: call:66; CHECK: push {[[DUMMYREG:r[0-9]+]], lr}67; CHECK-NOT: sp68; CHECK: bl foo69; CHECK: pop {[[DUMMYREG]], pc}70  call void @foo()71  ret void72}73 74; Has a call, and frame pointer requested.75define void @call_nofpelim() "frame-pointer"="all" {76; CHECK-LABEL: call_nofpelim:77; CHECK: push {r7, lr}78; CHECK: mov r7, sp79; CHECK: bl foo80; CHECK: pop {r7, pc}81  call void @foo()82  ret void83}84 85; Has a call, and frame pointer requested for non-leaf function.86define void @call_nononleaffpelim() "frame-pointer"="non-leaf" {87; CHECK-LABEL: call_nononleaffpelim:88; CHECK: push {r7, lr}89; CHECK: mov r7, sp90; CHECK: bl foo91; CHECK: pop {r7, pc}92  call void @foo()93  ret void94}95 96define void @call_nononleaffpelim_tailcall() "frame-pointer"="non-leaf" {97; CHECK-LABEL: call_nononleaffpelim_tailcall:98; CHECK-NOT: push99; CHECK: b foo100  tail call void @foo()101  ret void102}103 104; Has a high register clobbered, no need for a frame pointer.105define void @highreg() {106; CHECK-LABEL: highreg:107; CHECK: push.w {r8, lr}108; CHECK-NOT: sp109; CHECK: bl foo110; CHECK: pop.w {r8, pc}111  call void asm sideeffect "", "~{r8}" ()112  call void @foo()113  ret void114}115 116; Has a high register clobbered, frame pointer requested. We need to split the117; push into two, to ensure that r7 and sp are adjacent on the stack.118define void @highreg_nofpelim() "frame-pointer"="all" {119; CHECK-LABEL: highreg_nofpelim:120; CHECK: push {[[DUMMYREG:r[0-9]+]], r7, lr}121; CHECK: add r7, sp, #4122; CHECK: str r8, [sp, #-4]!123; CHECK: bl foo124; CHECK: ldr r8, [sp], #4125; CHECK: pop {[[DUMMYREG]], r7, pc}126  call void asm sideeffect "", "~{r8}" ()127  call void @foo()128  ret void129}130 131; Has a high register clobbered, frame required due to variable-sized alloca.132; We need a frame pointer to correctly restore the stack, but don't need to133; split the push/pop here, because the frame pointer not required by the ABI.134define void @highreg_alloca(i32 %a) {135; CHECK-LABEL: highreg_alloca:136; CHECK: push.w {[[SOMEREGS:.*]], r7, r8, lr}137; CHECK: add r7, sp, #{{[0-9]+}}138; CHECK: bl foo139; CHECK: pop.w {[[SOMEREGS]], r7, r8, pc}140  %alloca = alloca i32, i32 %a, align 4141  call void @foo()142  call void asm sideeffect "", "~{r8}" ()143  ret void144}145 146; Has a high register clobbered, frame required due to both variable-sized147; alloca and ABI. We do need to split the push/pop here.148define void @highreg_alloca_nofpelim(i32 %a) "frame-pointer"="all" {149; CHECK-LABEL: highreg_alloca_nofpelim:150; CHECK: push {[[SOMEREGS:.*]], r7, lr}151; CHECK: add r7, sp, #{{[0-9]+}}152; CHECK: str r8, [sp, #-4]!153; CHECK: bl foo154; CHECK: ldr r8, [sp], #4155; CHECK: pop {[[SOMEREGS]], r7, pc}156  %alloca = alloca i32, i32 %a, align 4157  call void @foo()158  call void asm sideeffect "", "~{r8}" ()159  ret void160}161