diff --git a/llvm/test/TableGen/generic-tables-instruction.td b/llvm/test/TableGen/generic-tables-instruction.td index 3be2462c9ab69..7b99784f2d73a 100644 --- a/llvm/test/TableGen/generic-tables-instruction.td +++ b/llvm/test/TableGen/generic-tables-instruction.td @@ -18,14 +18,12 @@ def Arch : Target { let InstructionSet = ArchInstrInfo; } // A contiguous primary (Instruction) key should get a direct lookup instead of // binary search. // CHECK: const MyInstr *getCustomEncodingHelper(unsigned Opcode) { -// CHECK: if ((Opcode < B) || -// CHECK: (Opcode > D)) -// CHECK: return nullptr; +// CHECK: if ((unsigned)Opcode != std::clamp((unsigned)Opcode, (unsigned)B, (unsigned)D)) +// CHECK: return nullptr; // CHECK: auto Table = ArrayRef(InstrTable); // CHECK: size_t Idx = Opcode - B; // CHECK: return &Table[Idx]; - class MyInstr : Instruction { let OutOperandList = (outs); let InOperandList = (ins); @@ -56,8 +54,7 @@ def InstrTable : GenericTable { // // Verify contiguous check for SearchIndex. // const MyInfoEntry *getTable2ByValue(uint8_t Value) { -// CHECK: if ((Value < 0xB) || -// CHECK: (Value > 0xD)) +// CHECK: if ((uint8_t)Value != std::clamp((uint8_t)Value, (uint8_t)0xB, (uint8_t)0xD)) // CHECK: return nullptr; // CHECK: auto Table = ArrayRef(Index); // CHECK: size_t Idx = Value - 0xB; diff --git a/llvm/test/TableGen/generic-tables.td b/llvm/test/TableGen/generic-tables.td index 003b532093460..8638740a8e565 100644 --- a/llvm/test/TableGen/generic-tables.td +++ b/llvm/test/TableGen/generic-tables.td @@ -113,8 +113,7 @@ def lookupBTableByNameAndFlag : SearchIndex { // CHECK: const CEntry *lookupCEntry(StringRef Name, unsigned Kind); // CHECK-LABEL: GET_CTable_IMPL // CHECK: const CEntry *lookupCEntryByEncoding(uint16_t Encoding) { -// CHECK: if ((Encoding < 0xA) || -// CHECK: (Encoding > 0xF)) +// CHECK: if ((uint16_t)Encoding != std::clamp((uint16_t)Encoding, (uint16_t)0xA, (uint16_t)0xF)) // CHECK: return nullptr; // CHECK: const CEntry *lookupCEntry(StringRef Name, unsigned Kind) { diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp b/llvm/utils/TableGen/SearchableTableEmitter.cpp index 38b6f2b395137..e91baf98e9ffc 100644 --- a/llvm/utils/TableGen/SearchableTableEmitter.cpp +++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp @@ -212,19 +212,21 @@ class SearchableTableEmitter { int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index, const Record *Rec) { assert(Index.Fields.size() == 1); + const GenericField &Field = Index.Fields[0]; // To be consistent with compareBy and primaryRepresentation elsewhere, // we check for IsInstruction before Enum-- these fields are not exclusive. - if (Index.Fields[0].IsInstruction) { - const Record *TheDef = Rec->getValueAsDef(Index.Fields[0].Name); + if (Field.IsInstruction) { + const Record *TheDef = Rec->getValueAsDef(Field.Name); return Target->getInstrIntValue(TheDef); } - if (Index.Fields[0].Enum) { - const Record *EnumEntry = Rec->getValueAsDef(Index.Fields[0].Name); - return Index.Fields[0].Enum->EntryMap[EnumEntry]->second; + if (Field.Enum) { + const Record *EnumEntry = Rec->getValueAsDef(Field.Name); + return Field.Enum->EntryMap[EnumEntry]->second; } + assert(isa(Field.RecType) && "unexpected field type"); - return getInt(Rec, Index.Fields[0].Name); + return getInt(Rec, Field.Name); } /// Less-than style comparison between \p LHS and \p RHS according to the @@ -392,37 +394,31 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table, } } - if (IsContiguous) { + if (Index.EarlyOut || IsContiguous) { const GenericField &Field = Index.Fields[0]; std::string FirstRepr = primaryRepresentation( Index.Loc, Field, IndexRows[0]->getValueInit(Field.Name)); std::string LastRepr = primaryRepresentation( Index.Loc, Field, IndexRows.back()->getValueInit(Field.Name)); - OS << " if ((" << Field.Name << " < " << FirstRepr << ") ||\n"; - OS << " (" << Field.Name << " > " << LastRepr << "))\n"; - OS << " return nullptr;\n"; - OS << " auto Table = ArrayRef(" << IndexName << ");\n"; - OS << " size_t Idx = " << Index.Fields[0].Name << " - " << FirstRepr - << ";\n"; - OS << " return "; - if (IsPrimary) - OS << "&Table[Idx]"; - else - OS << "&" << Table.Name << "[Table[Idx]._index]"; - OS << ";\n"; - OS << "}\n"; - return; - } - - if (Index.EarlyOut) { - const GenericField &Field = Index.Fields[0]; - std::string FirstRepr = primaryRepresentation( - Index.Loc, Field, IndexRows[0]->getValueInit(Field.Name)); - std::string LastRepr = primaryRepresentation( - Index.Loc, Field, IndexRows.back()->getValueInit(Field.Name)); - OS << " if ((" << Field.Name << " < " << FirstRepr << ") ||\n"; - OS << " (" << Field.Name << " > " << LastRepr << "))\n"; + std::string TS = + '(' + searchableFieldType(Table, Index, Field, TypeInStaticStruct) + + ')'; + OS << " if (" << TS << Field.Name << " != std::clamp(" << TS << Field.Name + << ", " << TS << FirstRepr << ", " << TS << LastRepr << "))\n"; OS << " return nullptr;\n\n"; + + if (IsContiguous && !Index.EarlyOut) { + OS << " auto Table = ArrayRef(" << IndexName << ");\n"; + OS << " size_t Idx = " << Field.Name << " - " << FirstRepr << ";\n"; + OS << " return "; + if (IsPrimary) + OS << "&Table[Idx]"; + else + OS << "&" << Table.Name << "[Table[Idx]._index]"; + OS << ";\n"; + OS << "}\n"; + return; + } } OS << " struct KeyType {\n";