[PATCH] D88134: [LLVM-TablGen] Incorrect base type for field 'Classes' of 'struct MatchEntry' in <Target>GenAsmMatcher.inc when AsmMatcherInfo.Classes size > 252 in TableGen
li.zhou via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 22:59:33 PDT 2020
tinytinymelon created this revision.
tinytinymelon added a project: LLVM.
Herald added subscribers: llvm-commits, dexonsmith, arichardson.
tinytinymelon requested review of this revision.
**Backgroud:**
- TableGen generates `enum MatchClassKind` in <Target>GenAsmMathcer.inc to show kinds of classes which participate in instruction matching.
/// MatchClassKind - The kinds of classes which participate in
/// instruction matching.
enum MatchClassKind {
InvalidMatchClass = 0,
OptionalMatchClass = 1,
MCK__DOT_1, // '.1'
MCK__DOT_2, // '.2'
MCK__DOT_3, // '.3'
...
NumMatchClassKinds
};
- field `Classes` of `struct MatchEntry` in same file is used to store the `enum MatchClassKind`
struct MatchEntry {
uint16_t Mnemonic;
uint16_t Opcode;
uint16_t ConvertFn;
uint8_t RequiredFeatures;
uint8_t Classes[13];
...
};
- the base type of field `Classes` is calculated by function `getMinimalTypeForRange` in file `AsmMatcherEmitter.cpp`:
...
OS << " " << getMinimalTypeForRange(
std::distance(Info.Classes.begin(), Info.Classes.end()))
<< " Classes[" << MaxNumOperands << "];\n";
...
- logic of function `getMinimalTypeForRange` shows that if the Range <= 255, it should use `uint8_t`:
c++
const char *llvm::getMinimalTypeForRange(uint64_t Range, unsigned MaxSize LLVM_ATTRIBUTE_UNUSED) {
// TODO: The original callers only used 32 and 64 so these are the only
// values permitted. Rather than widen the supported values we should
// allow 64 for the callers that currently use 32 and remove the
// argument altogether.
assert((MaxSize == 32 || MaxSize == 64) && "Unexpected size");
assert(MaxSize <= 64 && "Unexpected size");
assert(((MaxSize > 32) ? Range <= 0xFFFFFFFFFFFFFFFFULL
: Range <= 0xFFFFFFFFULL) &&
"Enum too large");
if (Range > 0xFFFFFFFFULL)
return "uint64_t";
if (Range > 0xFFFF)
return "uint32_t";
if (Range > 0xFF)
return "uint16_t";
return "uint8_t";
}
**Issue Description**
When decide the base type of field 'Classes', which should be decided by the size of `enum MatchClassKind` indeed, TablGen only consider the Classes defined in the `AsmMatcherInfo.Classes`, but forget the fixed header and tail enum value :
- InvalidMatchClass = 0
- OptionalMatchClass = 1
- NumMatchClassKinds
In such case, when the `AsmMatcherInfo.Classes` is larger than 252, the enum size is larger than 255 which should be represented by `uint16_t`. But the logic in file AsmMatcherEmitter.cpp gives `uint8_t` since it only check the size of `AsmMatcherInfo.Classes`.
It will bring error message as :
> error: narrowing conversion of '(<unnamed>::MatchClassKind)256u' from 'unsigned int' to 'uin8_t {aka unsigned char}' inside { } [-Wnarrowing]
Some of Classes with enum value > 255 will be also lost which brings to potential problems.
**Solution**
Take the 3 extra enum value in to consider when calculate the based type of field `Classes` in `struct MapEntry` as following shows:
...
OS << " " << getMinimalTypeForRange(
std::distance(Info.Classes.begin(), Info.Classes.end()) + 3)
<< " Classes[" << MaxNumOperands << "];\n";
...
It removes the error message.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D88134
Files:
utils/TableGen/AsmMatcherEmitter.cpp
Index: utils/TableGen/AsmMatcherEmitter.cpp
===================================================================
--- utils/TableGen/AsmMatcherEmitter.cpp
+++ utils/TableGen/AsmMatcherEmitter.cpp
@@ -2844,7 +2844,8 @@
OS << " " << getMinimalTypeForRange(MaxMask)
<< " OperandMask;\n";
OS << " " << getMinimalTypeForRange(std::distance(
- Info.Classes.begin(), Info.Classes.end())) << " Class;\n";
+ Info.Classes.begin(), Info.Classes.end()) + 3)
+ << " Class;\n";
OS << " " << getMinimalTypeForRange(MaxFeaturesIndex)
<< " RequiredFeaturesIdx;\n\n";
OS << " StringRef getMnemonic() const {\n";
@@ -3402,7 +3403,7 @@
OS << " " << getMinimalTypeForRange(FeatureBitsets.size())
<< " RequiredFeaturesIdx;\n";
OS << " " << getMinimalTypeForRange(
- std::distance(Info.Classes.begin(), Info.Classes.end()))
+ std::distance(Info.Classes.begin(), Info.Classes.end()) + 3)
<< " Classes[" << MaxNumOperands << "];\n";
OS << " StringRef getMnemonic() const {\n";
OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n";
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D88134.293647.patch
Type: text/x-patch
Size: 1212 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200923/fc2d5ad7/attachment.bin>
More information about the llvm-commits
mailing list