Description
I got a segfault / LLVM assertion failure while compiling a target with ThinLTO enabled. This is the same failure as in #53912, albeit with a different root cause.
In my case, I was dealing with a global named switch.table._ZN77_$LT$omaha_client..protocol..request..Event$u20$as$u20$core..clone..Clone$GT$5clone17h829b64c9ab982ff5E.llvm.10390335839252477638.llvm.11308644296266801080
.
Note the presence of two .llvm.NNNN
extensions. This means that this was a local which was promoted to a global symbol twice. The implementation of getOriginalNameBeforePromote
doesn't handle this case correctly; it strips off both extensions:
/// Convenience method for creating a promoted global name
/// for the given value name of a local, and its original module's ID.
static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash) {
SmallString<256> NewName(Name);
NewName += ".llvm.";
NewName += utostr((uint64_t(ModHash[0]) << 32) |
ModHash[1]); // Take the first 64 bits
return NewName.str();
}
/// Helper to obtain the unpromoted name for a global value (or the original
/// name if not promoted).
static StringRef getOriginalNameBeforePromote(StringRef Name) {
std::pair<StringRef, StringRef> Pair = Name.split(".llvm.");
return Pair.first;
}
The fix is actually trivial; just have to change split
to rsplit
so that it only removes the last .llvm.NNNN
extension. Leaving this issue open to track the fix being cherry-picked.