From a62844c8d9f84a69752a3a99f3f8b169a173f002 Mon Sep 17 00:00:00 2001 From: bsteinbr Date: Tue, 7 Nov 2017 08:50:21 +0000 Subject: [PATCH] [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 --- lib/Target/X86/X86FrameLowering.cpp | 5 +++++ test/CodeGen/X86/pop-stack-cleanup-msvc.ll | 26 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 test/CodeGen/X86/pop-stack-cleanup-msvc.ll diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index e03dbe51e075..8c5530483b01 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -2535,6 +2535,7 @@ bool X86FrameLowering::adjustStackWithPops(MachineBasicBlock &MBB, unsigned Regs[2]; unsigned FoundRegs = 0; + auto &MRI = MBB.getParent()->getRegInfo(); auto RegMask = Prev->getOperand(1); auto &RegClass = @@ -2548,6 +2549,10 @@ bool X86FrameLowering::adjustStackWithPops(MachineBasicBlock &MBB, if (!RegMask.clobbersPhysReg(Candidate)) continue; + // Don't clobber reserved registers + if (MRI.isReserved(Candidate)) + continue; + bool IsDef = false; for (const MachineOperand &MO : Prev->implicit_operands()) { if (MO.isReg() && MO.isDef() && diff --git a/test/CodeGen/X86/pop-stack-cleanup-msvc.ll b/test/CodeGen/X86/pop-stack-cleanup-msvc.ll new file mode 100644 index 000000000000..6330d3de72f1 --- /dev/null +++ b/test/CodeGen/X86/pop-stack-cleanup-msvc.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s | FileCheck %s + +target triple = "i686--windows-msvc" + +declare { i8*, i32 } @param2_ret2(i32, i32) +declare i32 @__CxxFrameHandler3(...) + + +define void @test_reserved_regs() minsize optsize personality i32 (...)* @__CxxFrameHandler3 { +; CHECK-LABEL: test_reserved_regs: +; CHECK: calll _param2_ret2 +; CHECK-NEXT: popl %ecx +; CHECK-NEXT: popl %edi +start: + %s = alloca i64 + store i64 4, i64* %s + %0 = invoke { i8*, i32 } @param2_ret2(i32 0, i32 1) + to label %out unwind label %cleanup + +out: + ret void + +cleanup: + %cp = cleanuppad within none [] + cleanupret from %cp unwind to caller +}