Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion llvm/lib/Target/X86/X86FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1557,7 +1557,19 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
Fn.arg_size() == 2) {
StackSize += 8;
MFI.setStackSize(StackSize);
emitSPUpdate(MBB, MBBI, DL, -8, /*InEpilogue=*/false);

// Update the stack pointer by pushing a register. This is the instruction
// emitted that would be end up being emitted by a call to `emitSPUpdate`.
// Hard-coding the update to a push avoids emitting a second
// `STACKALLOC_W_PROBING` instruction in the save block: We know that stack
// probing isn't needed anyways for an 8-byte update.
// Pushing a register leaves us in a similar situation to a regular
// function call where we know that the address at (rsp-8) is writeable.
// That way we avoid any off-by-ones with stack probing for additional
// stack pointer updates later on.
BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r))
.addReg(X86::RAX, RegState::Undef)
.setMIFlag(MachineInstr::FrameSetup);
}

// If this is x86-64 and the Red Zone is not disabled, if we are a leaf
Expand Down
17 changes: 17 additions & 0 deletions llvm/test/CodeGen/X86/x86-64-intrcc.ll
Original file line number Diff line number Diff line change
Expand Up @@ -174,5 +174,22 @@ entry:
ret void
}

define x86_intrcc void @test_stack_allocation(ptr byval(%struct.interrupt_frame) %frame, i64 %err) #1 {
; CHECK-LABEL: test_stack_allocation:
; CHECK: # %bb.0: # %entry

;; Ensure that STACKALLOC_W_PROBING isn't emitted.
; CHECK-NOT: # fixed size alloca with probing
;; Ensure that stack space is allocated.
; CHECK: subq $280, %rsp
entry:
%some_allocation = alloca i64
;; Call a un-inlineable function to ensure the allocation isn't put in the red zone.
call void @external_function(ptr %some_allocation)
ret void
}

declare void @external_function(ptr)

attributes #0 = { nounwind "frame-pointer"="all" }
attributes #1 = { nounwind "probe-stack"="inline-asm" }