Index: llvm/trunk/include/llvm/CodeGen/VirtRegMap.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/VirtRegMap.h +++ llvm/trunk/include/llvm/CodeGen/VirtRegMap.h @@ -102,14 +102,7 @@ /// @brief creates a mapping for the specified virtual register to /// the specified physical register - void assignVirt2Phys(unsigned virtReg, unsigned physReg) { - assert(TargetRegisterInfo::isVirtualRegister(virtReg) && - TargetRegisterInfo::isPhysicalRegister(physReg)); - assert(Virt2PhysMap[virtReg] == NO_PHYS_REG && - "attempt to assign physical register to already mapped " - "virtual register"); - Virt2PhysMap[virtReg] = physReg; - } + void assignVirt2Phys(unsigned virtReg, MCPhysReg physReg); /// @brief clears the specified virtual register's, physical /// register mapping Index: llvm/trunk/lib/CodeGen/MachineVerifier.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineVerifier.cpp +++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp @@ -945,7 +945,6 @@ VerifyStackMapConstant(VarStart + StatepointOpers::NumDeoptOperandsOffset); // TODO: verify we have properly encoded deopt arguments - }; } @@ -1947,9 +1946,11 @@ SlotIndex PEnd = LiveInts->getMBBEndIdx(*PI); const VNInfo *PVNI = LR.getVNInfoBefore(PEnd); - // All predecessors must have a live-out value if this is not a - // subregister liverange. - if (!PVNI && LaneMask.none()) { + // All predecessors must have a live-out value. However for a phi + // instruction with subregister intervals + // only one of the subregisters (not necessarily the current one) needs to + // be defined. + if (!PVNI && (LaneMask.none() || !IsPHI) ) { report("Register not marked live out of predecessor", *PI); report_context(LR, Reg, LaneMask); report_context(*VNI); Index: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp =================================================================== --- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp +++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp @@ -738,7 +738,15 @@ if (PReg == 0) { const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg); - PReg = RC.getRawAllocationOrder(MF).front(); + const ArrayRef RawPRegOrder = RC.getRawAllocationOrder(MF); + for (unsigned CandidateReg : RawPRegOrder) { + if (!VRM.getRegInfo().isReserved(CandidateReg)) { + PReg = CandidateReg; + break; + } + } + assert(PReg && + "No un-reserved physical registers in this register class"); } VRM.assignVirt2Phys(LI.reg, PReg); Index: llvm/trunk/lib/CodeGen/VirtRegMap.cpp =================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp @@ -72,6 +72,17 @@ Virt2SplitMap.resize(NumRegs); } +void VirtRegMap::assignVirt2Phys(unsigned virtReg, MCPhysReg physReg) { + assert(TargetRegisterInfo::isVirtualRegister(virtReg) && + TargetRegisterInfo::isPhysicalRegister(physReg)); + assert(Virt2PhysMap[virtReg] == NO_PHYS_REG && + "attempt to assign physical register to already mapped " + "virtual register"); + assert(!getRegInfo().isReserved(physReg) && + "Attempt to map virtReg to a reserved physReg"); + Virt2PhysMap[virtReg] = physReg; +} + unsigned VirtRegMap::createSpillSlot(const TargetRegisterClass *RC) { unsigned Size = TRI->getSpillSize(*RC); unsigned Align = TRI->getSpillAlignment(*RC); Index: llvm/trunk/test/CodeGen/Mips/pbqp-reserved-physreg.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/pbqp-reserved-physreg.ll +++ llvm/trunk/test/CodeGen/Mips/pbqp-reserved-physreg.ll @@ -0,0 +1,35 @@ +; RUN: llc -march=mips -regalloc=pbqp <%s > %t +; ModuleID = 'bugpoint-reduced-simplified.bc' + +; Function Attrs: nounwind +define void @ham.928() local_unnamed_addr #0 align 2 { +bb: + switch i32 undef, label %bb35 [ + i32 1, label %bb18 + i32 0, label %bb19 + i32 3, label %bb20 + i32 2, label %bb21 + i32 4, label %bb17 + ] + +bb17: ; preds = %bb + unreachable + +bb18: ; preds = %bb + unreachable + +bb19: ; preds = %bb + unreachable + +bb20: ; preds = %bb + unreachable + +bb21: ; preds = %bb + unreachable + +bb35: ; preds = %bb + unreachable +} + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } +