summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2018-06-26 14:11:30 +0000
committerThan McIntosh <thanm@google.com>2018-06-26 14:11:30 +0000
commit3190993a023d5f4faf68f98a13bbf5272f23e650 (patch)
tree051699a33ae217690513ce9bd58d97c6c06e46b8
parentcfe2f9d4d2d65417a9b28e439901b7a3f6de4dc0 (diff)
downloadbcm5719-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.cpp6
-rw-r--r--llvm/lib/Target/X86/X86FrameLowering.cpp6
-rw-r--r--llvm/test/CodeGen/ARM/segmented-stacks.ll18
-rw-r--r--llvm/test/CodeGen/X86/segmented-stacks.ll46
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
OpenPOWER on IntegriCloud