Index: llvm/lib/CodeGen/RegAllocFast.cpp =================================================================== --- llvm/lib/CodeGen/RegAllocFast.cpp +++ llvm/lib/CodeGen/RegAllocFast.cpp @@ -30,6 +30,7 @@ #include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/CodeGen/RegisterClassInfo.h" #include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" @@ -76,6 +77,7 @@ MachineRegisterInfo *MRI; const TargetRegisterInfo *TRI; const TargetInstrInfo *TII; + const TargetLowering *TLI; RegisterClassInfo RegClassInfo; /// Basic block currently being allocated. @@ -1434,14 +1436,25 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) { this->MBB = &MBB; + const Constant *PersonalityFn = nullptr; + if (MBB.getParent()->getFunction().hasPersonalityFn()) + PersonalityFn = MBB.getParent()->getFunction().getPersonalityFn(); + LLVM_DEBUG(dbgs() << "\nAllocating " << MBB); RegUnitStates.assign(TRI->getNumRegUnits(), regFree); assert(LiveVirtRegs.empty() && "Mapping not cleared from last block?"); for (MachineBasicBlock *Succ : MBB.successors()) { - for (const MachineBasicBlock::RegisterMaskPair &LI : Succ->liveins()) + for (const MachineBasicBlock::RegisterMaskPair &LI : Succ->liveins()) { + // landingpad registers are defined by the runtime, not the basic block + // leading to an invoke. + if (Succ->isEHPad() && + (LI.PhysReg == TLI->getExceptionPointerRegister(PersonalityFn) || + LI.PhysReg == TLI->getExceptionSelectorRegister(PersonalityFn))) + continue; setPhysRegState(LI.PhysReg, regPreAssigned); + } } Coalesced.clear(); @@ -1507,6 +1520,7 @@ const TargetSubtargetInfo &STI = MF.getSubtarget(); TRI = STI.getRegisterInfo(); TII = STI.getInstrInfo(); + TLI = STI.getTargetLowering(); MFI = &MF.getFrameInfo(); MRI->freezeReservedRegs(MF); RegClassInfo.runOnMachineFunction(MF); Index: llvm/test/CodeGen/X86/fast-isel-cmp-branch.ll =================================================================== --- llvm/test/CodeGen/X86/fast-isel-cmp-branch.ll +++ llvm/test/CodeGen/X86/fast-isel-cmp-branch.ll @@ -19,7 +19,7 @@ ; different basic block, so its operands aren't necessarily exported ; for cross-block usage. -; CHECK: movb %cl, [[OFS:[0-9]*]](%rsp) +; CHECK: movb %al, [[OFS:[0-9]*]](%rsp) ; CHECK: callq {{_?}}bar ; CHECK: movb [[OFS]](%rsp), %al Index: llvm/test/CodeGen/X86/regalloc-tight-invoke.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/regalloc-tight-invoke.ll @@ -0,0 +1,53 @@ +; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o - | FileCheck %s +declare void @foo(i32, ...) + +declare i32 @__gxx_personality_v0(...) + +; We were running out of registers for this invoke, because: + +; 1. The lshr/and pattern gets matched to a no-REX MOV so that ah/bh/... can +; be used instead, cutting available registers for %b.arg down to eax, ebx, +; ecx, edx, esi, edi. +; 2. We have a base pointer taking ebx out of contention. +; 3. The landingpad block convinced us we should be defining rax here. +; 3. The al fiddling for the varargs call only noted down that al was spillable, +; not ah or hax. +; +; So by the time we need to allocate a register for the call all registers are +; tied up and unspillable. + +; CHECK-LABEL: bar: +; CHECK: xorl %edi, %edi +; CHECK: movb %dil, {{[0-9]+}}(%rbx) +; CHECK: movb {{[0-9]+}}(%rbx), %al + +define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d, ...) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { + %mem = alloca i32, i32 %a, align 32 ; Force rbx to be used as a base pointer + %b.tmp = lshr i32 %b, 8 + %b.arg = and i32 %b.tmp, 255 + invoke void(i32, ...) @foo(i32 42, i32* %mem, i32 %c, i32 %d, i32 %b.arg) to label %success unwind label %fail + +success: + ret i32 0 +fail: + %exc = landingpad { i8*, i32 } cleanup + %res = extractvalue { i8*, i32 } %exc, 1 + ret i32 %res +} + +; CHECK-LABEL: live: +; CHECK: movl {{%.*}}, %eax + +define i32 @live(i32 %a, i32 %b, i32 %c, i32 %d, ...) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { + %mem = alloca i32, i32 %a, align 32 ; Force rbx to be used as a base pointer + %b.tmp = lshr i32 %b, 8 + %b.arg = and i32 %b.tmp, 255 + invoke void(i32, ...) @foo(i32 42) to label %success unwind label %fail + +success: + ret i32 0 +fail: + %exc = landingpad { i8*, i32 } cleanup + %res = extractvalue { i8*, i32 } %exc, 1 + ret i32 %b.arg +}