Skip to content

Cherry-pick: fix stack update for x86_intrcc with error code #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
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" }