diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 16a2be95396..eb997cddf23 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -321,7 +321,8 @@ public: /// getMinimalPhysRegClass - Returns the Register Class of a physical /// register of the given type. - const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg) const; + const TargetRegisterClass * + getMinimalPhysRegClass(unsigned Reg, EVT VT = MVT::Other) const; /// getAllocatableSet - Returns a bitset indexed by register number /// indicating if a register is allocatable or not. If a register class is diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 61a73412bbe..0cb463dcd39 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -123,7 +123,7 @@ EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, bool IsCloned, EVT VT = Node->getValueType(ResNo); const TargetRegisterClass *SrcRC = 0, *DstRC = 0; - SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, VT); + SrcRC = TRI->getMinimalPhysRegClass(SrcReg, VT); // Figure out the register class to create for the destreg. if (VRBase) { @@ -794,13 +794,13 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned, if (TargetRegisterInfo::isVirtualRegister(SrcReg)) SrcTRC = MRI->getRegClass(SrcReg); else - SrcTRC = TRI->getPhysicalRegisterRegClass(SrcReg,SrcVal.getValueType()); + SrcTRC = TRI->getMinimalPhysRegClass(SrcReg,SrcVal.getValueType()); if (TargetRegisterInfo::isVirtualRegister(DestReg)) DstTRC = MRI->getRegClass(DestReg); else - DstTRC = TRI->getPhysicalRegisterRegClass(DestReg, - Node->getOperand(1).getValueType()); + DstTRC = TRI->getMinimalPhysRegClass(DestReg, + Node->getOperand(1).getValueType()); bool Emitted = TII->copyRegToReg(*MBB, InsertPos, DestReg, SrcReg, DstTRC, SrcTRC, Node->getDebugLoc()); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp index ad8630afff4..3b86c328658 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp @@ -535,7 +535,7 @@ void ScheduleDAGFast::ListScheduleBottomUp() { SUnit *LRDef = LiveRegDefs[Reg]; EVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII); const TargetRegisterClass *RC = - TRI->getPhysicalRegisterRegClass(Reg, VT); + TRI->getMinimalPhysRegClass(Reg, VT); const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC); // If cross copy register class is null, then it must be possible copy diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index f5d4d658850..3ef521c398e 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -795,7 +795,7 @@ void ScheduleDAGRRList::ListScheduleBottomUp() { SUnit *LRDef = LiveRegDefs[Reg]; EVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII); const TargetRegisterClass *RC = - TRI->getPhysicalRegisterRegClass(Reg, VT); + TRI->getMinimalPhysRegClass(Reg, VT); const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC); // If cross copy register class is null, then it must be possible copy diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp index aa6ce05992c..ebc76e9b363 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -101,7 +101,7 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) { PhysReg = Reg; const TargetRegisterClass *RC = - TRI->getPhysicalRegisterRegClass(Reg, Def->getValueType(ResNo)); + TRI->getMinimalPhysRegClass(Reg, Def->getValueType(ResNo)); Cost = RC->getCopyCost(); } } diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index c0d05091be5..8b4d701fc71 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -707,6 +707,11 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, if (SrcRC == ARM::tGPRRegisterClass || SrcRC == ARM::tcGPRRegisterClass) SrcRC = ARM::GPRRegisterClass; + if (DestRC == ARM::SPR_8RegisterClass) + DestRC = ARM::SPRRegisterClass; + if (SrcRC == ARM::SPR_8RegisterClass) + SrcRC = ARM::SPRRegisterClass; + // Allow DPR / DPR_VFP2 / DPR_8 cross-class copies. if (DestRC == ARM::DPR_8RegisterClass) DestRC = ARM::DPR_VFP2RegisterClass; diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp index 32299f6c7e0..48374d93d88 100644 --- a/lib/Target/TargetRegisterInfo.cpp +++ b/lib/Target/TargetRegisterInfo.cpp @@ -63,7 +63,7 @@ TargetRegisterInfo::getPhysicalRegisterRegClass(unsigned reg, EVT VT) const { /// getMinimalPhysRegClass - Returns the Register Class of a physical /// register of the given type. const TargetRegisterClass * -TargetRegisterInfo::getMinimalPhysRegClass(unsigned reg) const { +TargetRegisterInfo::getMinimalPhysRegClass(unsigned reg, EVT VT) const { assert(isPhysicalRegister(reg) && "reg must be a physical register"); // Pick the most sub register class of the right type that contains @@ -71,7 +71,8 @@ TargetRegisterInfo::getMinimalPhysRegClass(unsigned reg) const { const TargetRegisterClass* BestRC = 0; for (regclass_iterator I = regclass_begin(), E = regclass_end(); I != E; ++I){ const TargetRegisterClass* RC = *I; - if (RC->contains(reg) && (!BestRC || BestRC->hasSubClass(RC))) + if ((VT == MVT::Other || RC->hasType(VT)) && RC->contains(reg) && + (!BestRC || BestRC->hasSubClass(RC))) BestRC = RC; } diff --git a/test/CodeGen/ARM/vget_lane.ll b/test/CodeGen/ARM/vget_lane.ll index 05e7f509095..bc10da09bb3 100644 --- a/test/CodeGen/ARM/vget_lane.ll +++ b/test/CodeGen/ARM/vget_lane.ll @@ -205,7 +205,7 @@ define <4 x i32> @vsetQ_lane32(<4 x i32>* %A, i32 %B) nounwind { define arm_aapcs_vfpcc <2 x float> @test_vset_lanef32(float %arg0_float32_t, <2 x float> %arg1_float32x2_t) nounwind { ;CHECK: test_vset_lanef32: ;CHECK: vmov.f32 s3, s0 -;CHECK: vmov.f64 d0, d1 +;CHECK: vmov d0, d1 entry: %0 = insertelement <2 x float> %arg1_float32x2_t, float %arg0_float32_t, i32 1 ; <<2 x float>> [#uses=1] ret <2 x float> %0