diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h --- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -415,19 +415,11 @@ /// Returns true if the two registers are equal or alias each other. /// The registers may be virtual registers. - bool regsOverlap(Register regA, Register regB) const { - if (regA == regB) return true; - if (!regA.isPhysical() || !regB.isPhysical()) - return false; - - // Regunits are numerically ordered. Find a common unit. - MCRegUnitIterator RUA(regA.asMCReg(), this); - MCRegUnitIterator RUB(regB.asMCReg(), this); - do { - if (*RUA == *RUB) return true; - if (*RUA < *RUB) ++RUA; - else ++RUB; - } while (RUA.isValid() && RUB.isValid()); + bool regsOverlap(Register RegA, Register RegB) const { + if (RegA == RegB) + return true; + if (RegA.isPhysical() && RegB.isPhysical()) + return MCRegisterInfo::regsOverlap(RegA.asMCReg(), RegB.asMCReg()); return false; } diff --git a/llvm/include/llvm/MC/MCRegisterInfo.h b/llvm/include/llvm/MC/MCRegisterInfo.h --- a/llvm/include/llvm/MC/MCRegisterInfo.h +++ b/llvm/include/llvm/MC/MCRegisterInfo.h @@ -580,6 +580,9 @@ bool isSuperOrSubRegisterEq(MCRegister RegA, MCRegister RegB) const { return isSubRegisterEq(RegA, RegB) || isSuperRegister(RegA, RegB); } + + /// Returns true if the two registers are equal or alias each other. + bool regsOverlap(MCRegister RegA, MCRegister RegB) const; }; //===----------------------------------------------------------------------===// @@ -698,6 +701,11 @@ // unit, we can allow a 0 differential here. advance(); } + + MCRegUnitIterator &operator++() { + MCRegisterInfo::DiffListIterator::operator++(); + return *this; + } }; /// MCRegUnitMaskIterator enumerates a list of register units and their diff --git a/llvm/lib/MC/MCRegisterInfo.cpp b/llvm/lib/MC/MCRegisterInfo.cpp --- a/llvm/lib/MC/MCRegisterInfo.cpp +++ b/llvm/lib/MC/MCRegisterInfo.cpp @@ -122,3 +122,14 @@ : Twine(RegNum))); return I->second; } + +bool MCRegisterInfo::regsOverlap(MCRegister RegA, MCRegister RegB) const { + // Regunits are numerically ordered. Find a common unit. + MCRegUnitIterator RUA(RegA, this); + MCRegUnitIterator RUB(RegB, this); + do { + if (*RUA == *RUB) + return true; + } while (*RUA < *RUB ? (++RUA).isValid() : (++RUB).isValid()); + return false; +} diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -3370,7 +3370,6 @@ assert(DstIdx != -1); const MCOperand &Dst = Inst.getOperand(DstIdx); assert(Dst.isReg()); - const unsigned DstReg = mc2PseudoReg(Dst.getReg()); const int SrcIndices[] = { Src0Idx, Src1Idx, Src2Idx }; @@ -3378,8 +3377,8 @@ if (SrcIdx == -1) break; const MCOperand &Src = Inst.getOperand(SrcIdx); if (Src.isReg()) { - const unsigned SrcReg = mc2PseudoReg(Src.getReg()); - if (isRegIntersect(DstReg, SrcReg, TRI)) { + if (TRI->regsOverlap(Dst.getReg(), Src.getReg())) { + const unsigned SrcReg = mc2PseudoReg(Src.getReg()); Error(getRegLoc(SrcReg, Operands), "destination must be different than all sources"); return false; @@ -3642,7 +3641,7 @@ if (TRI->getRegClass(Desc.OpInfo[0].RegClass).getSizeInBits() <= 128) return true; - if (isRegIntersect(Src2Reg, DstReg, TRI)) { + if (TRI->regsOverlap(Src2Reg, DstReg)) { Error(getRegLoc(mc2PseudoReg(Src2Reg), Operands), "source 2 operand must not partially overlap with dst"); return false; diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -774,9 +774,6 @@ /// Is Reg - scalar register bool isSGPR(unsigned Reg, const MCRegisterInfo* TRI); -/// Is there any intersection between registers -bool isRegIntersect(unsigned Reg0, unsigned Reg1, const MCRegisterInfo* TRI); - /// If \p Reg is a pseudo reg, return the correct hardware register given /// \p STI otherwise return \p Reg. unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI); diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -1508,13 +1508,6 @@ Reg == AMDGPU::SCC; } -bool isRegIntersect(unsigned Reg0, unsigned Reg1, const MCRegisterInfo* TRI) { - for (MCRegAliasIterator R(Reg0, TRI, true); R.isValid(); ++R) { - if (*R == Reg1) return true; - } - return false; -} - #define MAP_REG2REG \ using namespace AMDGPU; \ switch(Reg) { \