Index: lib/Target/ARM/ARMFrameLowering.cpp =================================================================== --- lib/Target/ARM/ARMFrameLowering.cpp +++ lib/Target/ARM/ARMFrameLowering.cpp @@ -2148,8 +2148,10 @@ 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. Index: lib/Target/X86/X86FrameLowering.cpp =================================================================== --- lib/Target/X86/X86FrameLowering.cpp +++ lib/Target/X86/X86FrameLowering.cpp @@ -2241,8 +2241,10 @@ // 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(); Index: test/CodeGen/ARM/segmented-stacks.ll =================================================================== --- test/CodeGen/ARM/segmented-stacks.ll +++ test/CodeGen/ARM/segmented-stacks.ll @@ -246,4 +246,22 @@ ; 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" } Index: test/CodeGen/X86/segmented-stacks.ll =================================================================== --- test/CodeGen/X86/segmented-stacks.ll +++ test/CodeGen/X86/segmented-stacks.ll @@ -640,6 +640,52 @@ 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