[GlobalISel][TableGen] Fix ConstrainOperandRC bug

TableGen would pick the largest RC for constraining the operands, which
could potentially be an unallocatable RC. This patch removes selection
of unallocatable RCs.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D93945
This commit is contained in:
Gabriel Hjort Åkerlund 2021-01-05 09:12:58 +01:00 committed by Mikael Holmen
parent 979c38cc74
commit 3c1d015edc
4 changed files with 15 additions and 3 deletions

View File

@ -36,6 +36,11 @@ def SOME_INSN : I<(outs DRegs:$dst), (ins DOP:$src), []>;
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)>;

View File

@ -344,7 +344,8 @@ CodeGenRegBank &CodeGenTarget::getRegBank() const {
Optional<CodeGenRegisterClass *>
CodeGenTarget::getSuperRegForSubReg(const ValueTypeByHwMode &ValueTy,
CodeGenRegBank &RegBank,
const CodeGenSubRegIndex *SubIdx) const {
const CodeGenSubRegIndex *SubIdx,
bool MustBeAllocatable) const {
std::vector<CodeGenRegisterClass *> Candidates;
auto &RegClasses = RegBank.getRegClasses();
@ -360,6 +361,10 @@ CodeGenTarget::getSuperRegForSubReg(const ValueTypeByHwMode &ValueTy,
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);

View File

@ -111,7 +111,8 @@ public:
/// covers \p SubIdx if it exists.
Optional<CodeGenRegisterClass *>
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.

View File

@ -4998,7 +4998,8 @@ GlobalISelEmitter::inferSuperRegisterClass(const TypeSetByHwMode &Ty,
// 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;