From 3c1d015edc755e8f3fa9c2a92d0b9bc81ba4d5fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Hjort=20=C3=85kerlund?= Date: Tue, 5 Jan 2021 09:12:58 +0100 Subject: [PATCH] [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 --- llvm/test/TableGen/GlobalISelEmitterSubreg.td | 5 +++++ llvm/utils/TableGen/CodeGenTarget.cpp | 7 ++++++- llvm/utils/TableGen/CodeGenTarget.h | 3 ++- llvm/utils/TableGen/GlobalISelEmitter.cpp | 3 ++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/llvm/test/TableGen/GlobalISelEmitterSubreg.td b/llvm/test/TableGen/GlobalISelEmitterSubreg.td index e8dc4a9ac4a0..2865cbc70038 100644 --- a/llvm/test/TableGen/GlobalISelEmitterSubreg.td +++ b/llvm/test/TableGen/GlobalISelEmitterSubreg.td @@ -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)>; diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp index 37bce3afa05a..2ed29b10fba6 100644 --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -344,7 +344,8 @@ CodeGenRegBank &CodeGenTarget::getRegBank() const { 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 @@ 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); diff --git a/llvm/utils/TableGen/CodeGenTarget.h b/llvm/utils/TableGen/CodeGenTarget.h index cc5bbe7a8bfe..1852bac15511 100644 --- a/llvm/utils/TableGen/CodeGenTarget.h +++ b/llvm/utils/TableGen/CodeGenTarget.h @@ -111,7 +111,8 @@ public: /// 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/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 07130e4e0ab7..29ca558580fe 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -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;