ARMFunctionInfo *ARMFI = MF.getInfo<ARMFunctionInfo>();
DebugLoc DL;
+ uint64_t StackSize = MFI->getStackSize();
+
+ // Do not generate a prologue for functions with a stack of size zero
+ if (StackSize == 0)
+ return;
+
// Use R4 and R5 as scratch registers.
// We save R4 and R5 before use and restore them before leaving the function.
unsigned ScratchReg0 = ARM::R4;
MF.push_front(PrevStackMBB);
// The required stack size that is aligned to ARM constant criterion.
- uint64_t StackSize = MFI->getStackSize();
-
AlignedStackSize = alignToARMConstant(StackSize);
// When the frame size is less than 256 we just compare the stack
!STI.isTargetWin32() && !STI.isTargetWin64() && !STI.isTargetFreeBSD())
report_fatal_error("Segmented stacks not supported on this platform.");
+ // Eventually StackSize will be calculated by a link-time pass; which will
+ // also decide whether checking code needs to be injected into this particular
+ // prologue.
+ StackSize = MFI->getStackSize();
+
+ // Do not generate a prologue for functions with a stack of size zero
+ if (StackSize == 0)
+ return;
+
MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock();
MachineBasicBlock *checkMBB = MF.CreateMachineBasicBlock();
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
MF.push_front(allocMBB);
MF.push_front(checkMBB);
- // Eventually StackSize will be calculated by a link-time pass; which will
- // also decide whether checking code needs to be injected into this particular
- // prologue.
- StackSize = MFI->getStackSize();
-
// When the frame size is less than 256 we just compare the stack
// boundary directly to the value of the stack pointer, per gcc.
bool CompareStackPointer = StackSize < kSplitStackAvailable;
define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
%addend = load i32 * %closure
%result = add i32 %other, %addend
+ %mem = alloca i32, i32 10
+ call void @dummy_use (i32* %mem, i32 10)
ret i32 %result
; ARM-linux: test_nested:
; ARM-linux-NEXT: cmp r4, r5
; ARM-linux-NEXT: blo .LBB1_2
-; ARM-linux: mov r4, #0
+; ARM-linux: mov r4, #56
; ARM-linux-NEXT: mov r5, #0
; ARM-linux-NEXT: stmdb sp!, {lr}
; ARM-linux-NEXT: bl __morestack
; ARM-android-NEXT: cmp r4, r5
; ARM-android-NEXT: blo .LBB1_2
-; ARM-android: mov r4, #0
+; ARM-android: mov r4, #56
; ARM-android-NEXT: mov r5, #0
; ARM-android-NEXT: stmdb sp!, {lr}
; ARM-android-NEXT: bl __morestack
}
+define void @test_nostack() #0 {
+ ret void
+
+; ARM-linux-LABEL: test_nostack:
+; ARM-linux-NOT: bl __morestack
+
+; ARM-android-LABEL: test_nostack:
+; ARM-android-NOT: bl __morestack
+}
+
attributes #0 = { "split-stack" }
define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
%addend = load i32 * %closure
%result = add i32 %other, %addend
+ %mem = alloca i32, i32 10
+ call void @dummy_use (i32* %mem, i32 10)
ret i32 %result
; Thumb-android: test_nested:
; Thumb-android-NEXT: cmp r4, r5
; Thumb-android-NEXT: blo .LBB1_2
-; Thumb-android: mov r4, #0
+; Thumb-android: mov r4, #56
; Thumb-android-NEXT: mov r5, #0
; Thumb-android-NEXT: push {lr}
; Thumb-android-NEXT: bl __morestack
; Thumb-linux-NEXT: cmp r4, r5
; Thumb-linux-NEXT: blo .LBB1_2
-; Thumb-linux: mov r4, #0
+; Thumb-linux: mov r4, #56
; Thumb-linux-NEXT: mov r5, #0
; Thumb-linux-NEXT: push {lr}
; Thumb-linux-NEXT: bl __morestack
}
+define void @test_nostack() #0 {
+ ret void
+
+; Thumb-android-LABEL: test_nostack:
+; Thumb-android-NOT: bl __morestack
+
+; Thumb-linux-LABEL: test_nostack:
+; Thumb-linux-NOT: bl __morestack
+}
+
attributes #0 = { "split-stack" }
define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
%addend = load i32 * %closure
%result = add i32 %other, %addend
+ %mem = alloca i32, i32 10
+ call void @dummy_use (i32* %mem, i32 10)
ret i32 %result
; X32-Linux: cmpl %gs:48, %esp
; X32-Linux-NEXT: ja .LBB1_2
; X32-Linux: pushl $4
-; X32-Linux-NEXT: pushl $0
+; X32-Linux-NEXT: pushl $60
; X32-Linux-NEXT: calll __morestack
; X32-Linux-NEXT: ret
; X64-Linux-NEXT: ja .LBB1_2
; X64-Linux: movq %r10, %rax
-; X64-Linux-NEXT: movabsq $0, %r10
+; X64-Linux-NEXT: movabsq $56, %r10
; X64-Linux-NEXT: movabsq $0, %r11
; X64-Linux-NEXT: callq __morestack
; X64-Linux-NEXT: ret
; X32-Darwin-NEXT: ja LBB1_2
; X32-Darwin: pushl $4
-; X32-Darwin-NEXT: pushl $0
+; X32-Darwin-NEXT: pushl $60
; X32-Darwin-NEXT: calll ___morestack
; X32-Darwin-NEXT: ret
; X64-Darwin-NEXT: ja LBB1_2
; X64-Darwin: movq %r10, %rax
-; X64-Darwin-NEXT: movabsq $0, %r10
+; X64-Darwin-NEXT: movabsq $56, %r10
; X64-Darwin-NEXT: movabsq $0, %r11
; X64-Darwin-NEXT: callq ___morestack
; X64-Darwin-NEXT: ret
; X32-MinGW-NEXT: ja LBB1_2
; X32-MinGW: pushl $4
-; X32-MinGW-NEXT: pushl $0
+; X32-MinGW-NEXT: pushl $52
; X32-MinGW-NEXT: calll ___morestack
; X32-MinGW-NEXT: ret
; X64-MinGW-NEXT: ja .LBB1_2
; X64-MinGW: movq %r10, %rax
-; X64-MinGW-NEXT: movabsq $0, %r10
+; X64-MinGW-NEXT: movabsq $88, %r10
; X64-MinGW-NEXT: movabsq $32, %r11
; X64-MinGW-NEXT: callq __morestack
; X64-MinGW-NEXT: retq
; X64-FreeBSD-NEXT: ja .LBB1_2
; X64-FreeBSD: movq %r10, %rax
-; X64-FreeBSD-NEXT: movabsq $0, %r10
+; X64-FreeBSD-NEXT: movabsq $56, %r10
; X64-FreeBSD-NEXT: movabsq $0, %r11
; X64-FreeBSD-NEXT: callq __morestack
; X64-FreeBSD-NEXT: ret
}
+define void @test_nostack() #0 {
+ ret void
+
+; X32-Linux-LABEL: test_nostack:
+; X32-Linux-NOT: calll __morestack
+
+; X64-Linux-LABEL: test_nostack:
+; X32-Linux-NOT: callq __morestack
+
+; X32-Darwin-LABEL: test_nostack:
+; X32-Darwin-NOT: calll __morestack
+
+; X64-Darwin-LABEL: test_nostack:
+; X64-Darwin-NOT: callq __morestack
+
+; X32-MinGW-LABEL: test_nostack:
+; X32-MinGW-NOT: calll __morestack
+
+; X64-MinGW-LABEL: test_nostack:
+; X64-MinGW-NOT: callq __morestack
+
+; X64-FreeBSD-LABEL: test_nostack:
+; X64-FreeBSD-NOT: callq __morestack
+}
+
attributes #0 = { "split-stack" }