Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit a62844c

Browse files
bsteinbrdotdash
bsteinbr
authored andcommitted
[X86] Don't clobber reserved registers with stack adjustments
Summary: Calls using invoke in funclet based functions are assumed to clobber all registers, which causes the stack adjustment using pops to consider all registers not defined by the call to be undefined, which can unfortunately include the base pointer, if one is needed. To prevent this (and possibly other hazards), skip reserved registers when looking for candidate registers. This fixes issue #45034 in the Rust compiler. Reviewers: mkuper Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39636 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317551 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 83b72ce commit a62844c

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

lib/Target/X86/X86FrameLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2535,6 +2535,7 @@ bool X86FrameLowering::adjustStackWithPops(MachineBasicBlock &MBB,
25352535
unsigned Regs[2];
25362536
unsigned FoundRegs = 0;
25372537

2538+
auto &MRI = MBB.getParent()->getRegInfo();
25382539
auto RegMask = Prev->getOperand(1);
25392540

25402541
auto &RegClass =
@@ -2548,6 +2549,10 @@ bool X86FrameLowering::adjustStackWithPops(MachineBasicBlock &MBB,
25482549
if (!RegMask.clobbersPhysReg(Candidate))
25492550
continue;
25502551

2552+
// Don't clobber reserved registers
2553+
if (MRI.isReserved(Candidate))
2554+
continue;
2555+
25512556
bool IsDef = false;
25522557
for (const MachineOperand &MO : Prev->implicit_operands()) {
25532558
if (MO.isReg() && MO.isDef() &&
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: llc < %s | FileCheck %s
2+
3+
target triple = "i686--windows-msvc"
4+
5+
declare { i8*, i32 } @param2_ret2(i32, i32)
6+
declare i32 @__CxxFrameHandler3(...)
7+
8+
9+
define void @test_reserved_regs() minsize optsize personality i32 (...)* @__CxxFrameHandler3 {
10+
; CHECK-LABEL: test_reserved_regs:
11+
; CHECK: calll _param2_ret2
12+
; CHECK-NEXT: popl %ecx
13+
; CHECK-NEXT: popl %edi
14+
start:
15+
%s = alloca i64
16+
store i64 4, i64* %s
17+
%0 = invoke { i8*, i32 } @param2_ret2(i32 0, i32 1)
18+
to label %out unwind label %cleanup
19+
20+
out:
21+
ret void
22+
23+
cleanup:
24+
%cp = cleanuppad within none []
25+
cleanupret from %cp unwind to caller
26+
}

0 commit comments

Comments
 (0)