diff options
author | Than McIntosh <thanm@google.com> | 2018-06-26 14:11:30 +0000 |
---|---|---|
committer | Than McIntosh <thanm@google.com> | 2018-06-26 14:11:30 +0000 |
commit | 3190993a023d5f4faf68f98a13bbf5272f23e650 (patch) | |
tree | 051699a33ae217690513ce9bd58d97c6c06e46b8 | |
parent | cfe2f9d4d2d65417a9b28e439901b7a3f6de4dc0 (diff) | |
download | bcm5719-llvm-3190993a023d5f4faf68f98a13bbf5272f23e650.tar.gz bcm5719-llvm-3190993a023d5f4faf68f98a13bbf5272f23e650.zip |
[X86,ARM] Retain split-stack prolog check for sibling calls
Summary:
If a routine with no stack frame makes a sibling call, we need to
preserve the stack space check even if the local stack frame is empty,
since the call target could be a "no-split" function (in which case
the linker needs to be able to fix up the prolog sequence in order to
switch to a larger stack).
This fixes PR37807.
Reviewers: cherry, javed.absar
Subscribers: srhines, llvm-commits
Differential Revision: https://reviews.llvm.org/D48444
llvm-svn: 335604
-rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 6 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/segmented-stacks.ll | 18 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/segmented-stacks.ll | 46 |
4 files changed, 72 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index f350f3e8b30..af983ce2606 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -2148,8 +2148,10 @@ void ARMFrameLowering::adjustForSegmentedStacks( uint64_t StackSize = MFI.getStackSize(); - // Do not generate a prologue for functions with a stack of size zero - if (StackSize == 0) + // Do not generate a prologue for leaf functions with a stack of size zero. + // For non-leaf functions we have to allow for the possibility that the + // call is to a non-split function, as in PR37807. + if (StackSize == 0 && !MFI.hasTailCall()) return; // Use R4 and R5 as scratch registers. diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 18f62e06afa..a257ec41f75 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -2241,8 +2241,10 @@ void X86FrameLowering::adjustForSegmentedStacks( // prologue. StackSize = MFI.getStackSize(); - // Do not generate a prologue for functions with a stack of size zero - if (StackSize == 0) + // Do not generate a prologue for leaf functions with a stack of size zero. + // For non-leaf functions we have to allow for the possibility that the + // call is to a non-split function, as in PR37807. + if (StackSize == 0 && !MFI.hasTailCall()) return; MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock(); diff --git a/llvm/test/CodeGen/ARM/segmented-stacks.ll b/llvm/test/CodeGen/ARM/segmented-stacks.ll index 4fe84faa17f..971fdd96606 100644 --- a/llvm/test/CodeGen/ARM/segmented-stacks.ll +++ b/llvm/test/CodeGen/ARM/segmented-stacks.ll @@ -246,4 +246,22 @@ define void @test_nostack() #0 { ; ARM-android-NOT: bl __morestack } +; Test to make sure that a morestack call is generated if there is a +; sibling call, even if the function in question has no stack frame +; (PR37807). + +declare i32 @callee(i32) + +define i32 @test_sibling_call_empty_frame(i32 %x) #0 { + %call = tail call i32 @callee(i32 %x) #0 + ret i32 %call + +; ARM-linux: test_sibling_call_empty_frame: +; ARM-linux: bl __morestack + +; ARM-android: test_sibling_call_empty_frame: +; ARM-android: bl __morestack + +} + attributes #0 = { "split-stack" } diff --git a/llvm/test/CodeGen/X86/segmented-stacks.ll b/llvm/test/CodeGen/X86/segmented-stacks.ll index a4861efac0e..588262bbb39 100644 --- a/llvm/test/CodeGen/X86/segmented-stacks.ll +++ b/llvm/test/CodeGen/X86/segmented-stacks.ll @@ -640,6 +640,52 @@ define void @test_nosplitstck() { ret void } +; Test to make sure that a morestack call is generated if there is a +; sibling call, even if the function in question has no stack frame +; (PR37807). + +declare i32 @callee(i32) + +define i32 @test_sibling_call_empty_frame(i32 %x) #0 { + %call = tail call i32 @callee(i32 %x) #0 + ret i32 %call + +; X32-Linux-LABEL: test_sibling_call_empty_frame: +; X32-Linux: calll __morestack + +; X64-Linux-LABEL: test_sibling_call_empty_frame: +; X64-Linux: callq __morestack + +; X64-Linux-Large-LABEL: test_sibling_call_empty_frame: +; X64-Linux-Large: callq *__morestack_addr(%rip) + +; X32ABI-LABEL: test_sibling_call_empty_frame: +; X32ABI: callq __morestack + +; X32-Darwin-LABEL: test_sibling_call_empty_frame: +; X32-Darwin: calll ___morestack + +; X64-Darwin-LABEL: test_sibling_call_empty_frame: +; X64-Darwin: callq ___morestack + +; X32-MinGW-LABEL: test_sibling_call_empty_frame: +; X32-MinGW: calll ___morestack + +; X64-MinGW-LABEL: test_sibling_call_empty_frame: +; X64-MinGW: callq __morestack + +; X64-FreeBSD-LABEL: test_sibling_call_empty_frame: +; X64-FreeBSD: callq __morestack + +; X32-DFlyBSD-LABEL: test_sibling_call_empty_frame: +; X32-DFlyBSD: calll __morestack +; X32-DFlyBSD-NEXT: ret + +; X64-DFlyBSD-LABEL: test_sibling_call_empty_frame: +; X64-DFlyBSD: callq __morestack + +} + attributes #0 = { "split-stack" } ; X64-Linux-Large: .rodata |