Skip to content

Commit 271b338

Browse files
authored
[TableGen][NFC] Factor early-out range check. (#123645)
Combine the EarlyOut and IsContiguous range check. Also avoid "comparison is always false" warnings in emitted code when the lower-bound check is against 0.
1 parent a0c6811 commit 271b338

File tree

3 files changed

+31
-39
lines changed

3 files changed

+31
-39
lines changed

llvm/test/TableGen/generic-tables-instruction.td

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ def Arch : Target { let InstructionSet = ArchInstrInfo; }
1818
// A contiguous primary (Instruction) key should get a direct lookup instead of
1919
// binary search.
2020
// CHECK: const MyInstr *getCustomEncodingHelper(unsigned Opcode) {
21-
// CHECK: if ((Opcode < B) ||
22-
// CHECK: (Opcode > D))
23-
// CHECK: return nullptr;
21+
// CHECK: if ((unsigned)Opcode != std::clamp((unsigned)Opcode, (unsigned)B, (unsigned)D))
22+
// CHECK: return nullptr;
2423
// CHECK: auto Table = ArrayRef(InstrTable);
2524
// CHECK: size_t Idx = Opcode - B;
2625
// CHECK: return &Table[Idx];
2726

28-
2927
class MyInstr<int op> : Instruction {
3028
let OutOperandList = (outs);
3129
let InOperandList = (ins);
@@ -56,8 +54,7 @@ def InstrTable : GenericTable {
5654
//
5755
// Verify contiguous check for SearchIndex.
5856
// const MyInfoEntry *getTable2ByValue(uint8_t Value) {
59-
// CHECK: if ((Value < 0xB) ||
60-
// CHECK: (Value > 0xD))
57+
// CHECK: if ((uint8_t)Value != std::clamp((uint8_t)Value, (uint8_t)0xB, (uint8_t)0xD))
6158
// CHECK: return nullptr;
6259
// CHECK: auto Table = ArrayRef(Index);
6360
// CHECK: size_t Idx = Value - 0xB;

llvm/test/TableGen/generic-tables.td

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ def lookupBTableByNameAndFlag : SearchIndex {
113113
// CHECK: const CEntry *lookupCEntry(StringRef Name, unsigned Kind);
114114
// CHECK-LABEL: GET_CTable_IMPL
115115
// CHECK: const CEntry *lookupCEntryByEncoding(uint16_t Encoding) {
116-
// CHECK: if ((Encoding < 0xA) ||
117-
// CHECK: (Encoding > 0xF))
116+
// CHECK: if ((uint16_t)Encoding != std::clamp((uint16_t)Encoding, (uint16_t)0xA, (uint16_t)0xF))
118117
// CHECK: return nullptr;
119118

120119
// CHECK: const CEntry *lookupCEntry(StringRef Name, unsigned Kind) {

llvm/utils/TableGen/SearchableTableEmitter.cpp

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -212,19 +212,21 @@ class SearchableTableEmitter {
212212
int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index,
213213
const Record *Rec) {
214214
assert(Index.Fields.size() == 1);
215+
const GenericField &Field = Index.Fields[0];
215216

216217
// To be consistent with compareBy and primaryRepresentation elsewhere,
217218
// we check for IsInstruction before Enum-- these fields are not exclusive.
218-
if (Index.Fields[0].IsInstruction) {
219-
const Record *TheDef = Rec->getValueAsDef(Index.Fields[0].Name);
219+
if (Field.IsInstruction) {
220+
const Record *TheDef = Rec->getValueAsDef(Field.Name);
220221
return Target->getInstrIntValue(TheDef);
221222
}
222-
if (Index.Fields[0].Enum) {
223-
const Record *EnumEntry = Rec->getValueAsDef(Index.Fields[0].Name);
224-
return Index.Fields[0].Enum->EntryMap[EnumEntry]->second;
223+
if (Field.Enum) {
224+
const Record *EnumEntry = Rec->getValueAsDef(Field.Name);
225+
return Field.Enum->EntryMap[EnumEntry]->second;
225226
}
227+
assert(isa<BitsRecTy>(Field.RecType) && "unexpected field type");
226228

227-
return getInt(Rec, Index.Fields[0].Name);
229+
return getInt(Rec, Field.Name);
228230
}
229231

230232
/// Less-than style comparison between \p LHS and \p RHS according to the
@@ -392,37 +394,31 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
392394
}
393395
}
394396

395-
if (IsContiguous) {
397+
if (Index.EarlyOut || IsContiguous) {
396398
const GenericField &Field = Index.Fields[0];
397399
std::string FirstRepr = primaryRepresentation(
398400
Index.Loc, Field, IndexRows[0]->getValueInit(Field.Name));
399401
std::string LastRepr = primaryRepresentation(
400402
Index.Loc, Field, IndexRows.back()->getValueInit(Field.Name));
401-
OS << " if ((" << Field.Name << " < " << FirstRepr << ") ||\n";
402-
OS << " (" << Field.Name << " > " << LastRepr << "))\n";
403-
OS << " return nullptr;\n";
404-
OS << " auto Table = ArrayRef(" << IndexName << ");\n";
405-
OS << " size_t Idx = " << Index.Fields[0].Name << " - " << FirstRepr
406-
<< ";\n";
407-
OS << " return ";
408-
if (IsPrimary)
409-
OS << "&Table[Idx]";
410-
else
411-
OS << "&" << Table.Name << "[Table[Idx]._index]";
412-
OS << ";\n";
413-
OS << "}\n";
414-
return;
415-
}
416-
417-
if (Index.EarlyOut) {
418-
const GenericField &Field = Index.Fields[0];
419-
std::string FirstRepr = primaryRepresentation(
420-
Index.Loc, Field, IndexRows[0]->getValueInit(Field.Name));
421-
std::string LastRepr = primaryRepresentation(
422-
Index.Loc, Field, IndexRows.back()->getValueInit(Field.Name));
423-
OS << " if ((" << Field.Name << " < " << FirstRepr << ") ||\n";
424-
OS << " (" << Field.Name << " > " << LastRepr << "))\n";
403+
std::string TS =
404+
'(' + searchableFieldType(Table, Index, Field, TypeInStaticStruct) +
405+
')';
406+
OS << " if (" << TS << Field.Name << " != std::clamp(" << TS << Field.Name
407+
<< ", " << TS << FirstRepr << ", " << TS << LastRepr << "))\n";
425408
OS << " return nullptr;\n\n";
409+
410+
if (IsContiguous && !Index.EarlyOut) {
411+
OS << " auto Table = ArrayRef(" << IndexName << ");\n";
412+
OS << " size_t Idx = " << Field.Name << " - " << FirstRepr << ";\n";
413+
OS << " return ";
414+
if (IsPrimary)
415+
OS << "&Table[Idx]";
416+
else
417+
OS << "&" << Table.Name << "[Table[Idx]._index]";
418+
OS << ";\n";
419+
OS << "}\n";
420+
return;
421+
}
426422
}
427423

428424
OS << " struct KeyType {\n";

0 commit comments

Comments
 (0)