diff --git a/llvm/test/TableGen/RegClassByHwModeErrors.td b/llvm/test/TableGen/RegClassByHwModeErrors.td index 0ee6370ccd0ce..c7731312e28a6 100644 --- a/llvm/test/TableGen/RegClassByHwModeErrors.td +++ b/llvm/test/TableGen/RegClassByHwModeErrors.td @@ -9,6 +9,8 @@ // RUN: %t/compress-regclass-by-hwmode-2.td -o /dev/null 2>&1 | FileCheck %t/compress-regclass-by-hwmode-2.td --implicit-check-not="error:" // RUN: not llvm-tblgen --gen-dag-isel -I %p/../../include -I %t -I %S \ // RUN: %t/vt-by-hwmode-missing.td -o /dev/null 2>&1 | FileCheck %t/vt-by-hwmode-missing.td --implicit-check-not="error:" +// RUN: not llvm-tblgen --gen-dag-isel -I %p/../../include -I %t -I %S \ +// RUN: %t/multiple-entries-for-same-mode.td -o /dev/null 2>&1 | FileCheck %t/multiple-entries-for-same-mode.td --implicit-check-not="error:" //--- Common.td include "Common/RegClassByHwModeCommon.td" @@ -119,3 +121,22 @@ def TEST : TestInstruction { def MyTargetISA : InstrInfo; def MyTarget : Target { let InstructionSet = MyTargetISA; } + + +//--- multiple-entries-for-same-mode.td +include "Common.td" +/// We should get an error if the same mode is listed more than once +defvar Ptr64Alias = Ptr64; +def BadRegClass : RegClassByHwMode<[Ptr32, Ptr64, Ptr64Alias], [XRegs, YRegs, YRegs]>; +// CHECK: [[#@LINE-1]]:5: error: duplicate RegisterClass entry for HwMode Ptr64: YRegs +// Need at least one CompressPat use of the bad reg class to trigger the error: +def USE_BAD_REG_CLASS : TestInstruction { + let OutOperandList = (outs BadRegClass:$dst); + let InOperandList = (ins BadRegClass:$src1, BadRegClass:$src2); + let AsmString = "bad $dst"; + let Pattern = [(set BadRegClass:$dst, (add BadRegClass:$src1, BadRegClass:$src2))]; +} +def MyTargetISA : InstrInfo; +def MyTarget : Target { + let InstructionSet = MyTargetISA; +} diff --git a/llvm/utils/TableGen/Common/InfoByHwMode.cpp b/llvm/utils/TableGen/Common/InfoByHwMode.cpp index a3f8909c36090..4ab27a610249d 100644 --- a/llvm/utils/TableGen/Common/InfoByHwMode.cpp +++ b/llvm/utils/TableGen/Common/InfoByHwMode.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include @@ -32,10 +33,12 @@ std::string llvm::getModeName(unsigned Mode) { ValueTypeByHwMode::ValueTypeByHwMode(const Record *R, const CodeGenHwModes &CGH) : InfoByHwMode(R) { const HwModeSelect &MS = CGH.getHwModeSelect(R); - for (const HwModeSelect::PairType &P : MS.Items) { - auto I = Map.try_emplace(P.first, MVT(llvm::getValueType(P.second))); - assert(I.second && "Duplicate entry?"); - (void)I; + for (auto [ModeID, VT] : MS.Items) { + assert(VT && VT->isSubClassOf("ValueType")); + if (!Map.try_emplace(ModeID, MVT(llvm::getValueType(VT))).second) + PrintFatalError(R->getLoc(), "duplicate ValueType entry for HwMode " + + CGH.getModeName(ModeID, true) + ": " + + VT->getName()); } if (R->isSubClassOf("PtrValueType")) PtrAddrSpace = R->getValueAsInt("AddrSpace"); @@ -143,10 +146,12 @@ RegSizeInfoByHwMode::RegSizeInfoByHwMode(const Record *R, const CodeGenHwModes &CGH) : InfoByHwMode(R) { const HwModeSelect &MS = CGH.getHwModeSelect(R); - for (const HwModeSelect::PairType &P : MS.Items) { - auto I = Map.try_emplace(P.first, RegSizeInfo(P.second)); - assert(I.second && "Duplicate entry?"); - (void)I; + for (auto [ModeID, RegInfo] : MS.Items) { + assert(RegInfo && RegInfo->isSubClassOf("RegInfo")); + if (!Map.try_emplace(ModeID, RegSizeInfo(RegInfo)).second) + PrintFatalError(R->getLoc(), "duplicate RegInfo entry for HwMode " + + CGH.getModeName(ModeID, true) + ": " + + RegInfo->getName()); } } @@ -198,7 +203,9 @@ RegClassByHwMode::RegClassByHwMode(const Record *R, const CodeGenHwModes &CGH, "Register class must subclass RegisterClass"); const CodeGenRegisterClass *RegClass = RegBank.getRegClass(RegClassRec); if (!Map.try_emplace(ModeID, RegClass).second) - llvm_unreachable("duplicate entry"); + PrintFatalError(R->getLoc(), "duplicate RegisterClass entry for HwMode " + + CGH.getModeName(ModeID, true) + ": " + + RegClass->getName()); } } @@ -211,10 +218,12 @@ SubRegRangeByHwMode::SubRegRangeByHwMode(const Record *R, const CodeGenHwModes &CGH) : InfoByHwMode(R) { const HwModeSelect &MS = CGH.getHwModeSelect(R); - for (const HwModeSelect::PairType &P : MS.Items) { - auto I = Map.try_emplace(P.first, SubRegRange(P.second)); - assert(I.second && "Duplicate entry?"); - (void)I; + for (auto [ModeID, Range] : MS.Items) { + assert(Range && Range->isSubClassOf("SubRegRange")); + if (!Map.try_emplace(ModeID, SubRegRange(Range)).second) + PrintFatalError(R->getLoc(), "duplicate SubRegRange entry for HwMode " + + CGH.getModeName(ModeID, true) + ": " + + Range->getName()); } } @@ -222,12 +231,14 @@ EncodingInfoByHwMode::EncodingInfoByHwMode(const Record *R, const CodeGenHwModes &CGH) : InfoByHwMode(R) { const HwModeSelect &MS = CGH.getHwModeSelect(R); - for (const HwModeSelect::PairType &P : MS.Items) { - assert(P.second && P.second->isSubClassOf("InstructionEncoding") && + for (auto [ModeID, Encoding] : MS.Items) { + assert(Encoding && Encoding->isSubClassOf("InstructionEncoding") && "Encoding must subclass InstructionEncoding"); - auto I = Map.try_emplace(P.first, P.second); - assert(I.second && "Duplicate entry?"); - (void)I; + if (!Map.try_emplace(ModeID, Encoding).second) + PrintFatalError(R->getLoc(), + "duplicate InstructionEncoding entry for HwMode " + + CGH.getModeName(ModeID, true) + ": " + + Encoding->getName()); } }