summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorJustin Holewinski <jholewinski@nvidia.com>2013-07-25 12:32:00 +0000
committerJustin Holewinski <jholewinski@nvidia.com>2013-07-25 12:32:00 +0000
commit563a9cf7ba3055921b7de9f05dd9223e82d20aba (patch)
treee6bf3be21c5ebeb8ee007129b2da3ab3fb3975ea /utils
parentc572005d7be00b824a105a313532529c678bd0d3 (diff)
downloadllvm-563a9cf7ba3055921b7de9f05dd9223e82d20aba.tar.gz
llvm-563a9cf7ba3055921b7de9f05dd9223e82d20aba.tar.bz2
llvm-563a9cf7ba3055921b7de9f05dd9223e82d20aba.tar.xz
Fix a bug in TableGen where the intrinsic function name recognizer could mis-identify names if one was a prefix substring of the other
For two intrinsics 'llvm.nvvm.texsurf.handle' and 'llvm.nvvm.texsurf.handle.internal', TableGen was emitting matching code like: if (Name.startswith("llvm.nvvm.texsurf.handle")) ... if (Name.startswith("llvm.nvvm.texsurf.handle.internal")) ... We can never match "llvm.nvvm.texsurf.handle.internal" here because it will always be erroneously matched by the first condition. The fix is to sort the intrinsic names and emit them in reverse order. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187119 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/IntrinsicEmitter.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index c83797c25d..c508795cc8 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -131,6 +131,20 @@ void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
OS << "#endif\n\n";
}
+struct IntrinsicNameSorter {
+ IntrinsicNameSorter(const std::vector<CodeGenIntrinsic> &I)
+ : Ints(I) {}
+
+ // Sort in reverse order of intrinsic name so "abc.def" appears after
+ // "abd.def.ghi" in the overridden name matcher
+ bool operator()(unsigned i, unsigned j) {
+ return Ints[i].Name > Ints[j].Name;
+ }
+
+private:
+ const std::vector<CodeGenIntrinsic> &Ints;
+};
+
void IntrinsicEmitter::
EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
raw_ostream &OS) {
@@ -144,12 +158,16 @@ EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
OS << " StringRef NameR(Name+6, Len-6); // Skip over 'llvm.'\n";
OS << " switch (Name[5]) { // Dispatch on first letter.\n";
OS << " default: break;\n";
+ IntrinsicNameSorter Sorter(Ints);
// Emit the intrinsic matching stuff by first letter.
for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(),
E = IntMapping.end(); I != E; ++I) {
OS << " case '" << I->first << "':\n";
std::vector<unsigned> &IntList = I->second;
+ // Sort intrinsics in reverse order of their names
+ std::sort(IntList.begin(), IntList.end(), Sorter);
+
// Emit all the overloaded intrinsics first, build a table of the
// non-overloaded ones.
std::vector<StringMatcher::StringPair> MatchTable;