diff --git a/llvm/test/TableGen/GlobalISelEmitterSubreg.td b/llvm/test/TableGen/GlobalISelEmitterSubreg.td --- a/llvm/test/TableGen/GlobalISelEmitterSubreg.td +++ b/llvm/test/TableGen/GlobalISelEmitterSubreg.td @@ -36,6 +36,11 @@ def SUBSOME_INSN : I<(outs SRegs:$dst), (ins SOP:$src), []>; def SUBSOME_INSN2 : I<(outs SRegs:$dst), (ins SOP:$src), []>; +// Adding this enables the tests below to check that we are not using this class +// for constraining the operand register classes, since it is unallocatable. +let isAllocatable = 0 in +def SuperDRegs : MyClass<32, [i32], (add DRegs, ERegs)>; + // We should skip cases where we don't have a given register class for the // subregister source. // SKIPPED: def : Pat<(i32 (anyext i16:$src)), (INSERT_SUBREG (i32 (IMPLICIT_DEF)), i16:$src, sub0)>; diff --git a/llvm/utils/TableGen/CodeGenTarget.h b/llvm/utils/TableGen/CodeGenTarget.h --- a/llvm/utils/TableGen/CodeGenTarget.h +++ b/llvm/utils/TableGen/CodeGenTarget.h @@ -111,7 +111,8 @@ /// covers \p SubIdx if it exists. Optional getSuperRegForSubReg(const ValueTypeByHwMode &Ty, CodeGenRegBank &RegBank, - const CodeGenSubRegIndex *SubIdx) const; + const CodeGenSubRegIndex *SubIdx, + bool MustBeAllocatable = false) const; /// getRegisterByName - If there is a register with the specific AsmName, /// return it. diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -344,7 +344,8 @@ Optional CodeGenTarget::getSuperRegForSubReg(const ValueTypeByHwMode &ValueTy, CodeGenRegBank &RegBank, - const CodeGenSubRegIndex *SubIdx) const { + const CodeGenSubRegIndex *SubIdx, + bool MustBeAllocatable) const { std::vector Candidates; auto &RegClasses = RegBank.getRegClasses(); @@ -360,6 +361,10 @@ if (!llvm::is_contained(SubClassWithSubReg->VTs, ValueTy)) continue; + // If necessary, check that it is allocatable. + if (MustBeAllocatable && !SubClassWithSubReg->Allocatable) + continue; + // We have a register class which supports both the value type and // subregister index. Remember it. Candidates.push_back(SubClassWithSubReg); diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -4998,7 +4998,8 @@ // Use the information we found above to find a minimal register class which // supports the subregister and type we want. auto RC = - Target.getSuperRegForSubReg(Ty.getValueTypeByHwMode(), CGRegs, SubIdx); + Target.getSuperRegForSubReg(Ty.getValueTypeByHwMode(), CGRegs, SubIdx, + /* MustBeAllocatable */ true); if (!RC) return None; return *RC;