diff options
author | Jeroen Dobbelaere <jeroen.dobbelaere@synopsys.com> | 2021-07-13 10:37:45 +0200 |
---|---|---|
committer | Jeroen Dobbelaere <jeroen.dobbelaere@synopsys.com> | 2021-07-13 11:21:12 +0200 |
commit | 90a6bb30fafa4e68d4af1fef62987fe187fa70ab (patch) | |
tree | 324d60a0c39736d20036a49392fdccab4311b461 /llvm/lib/IR/Function.cpp | |
parent | 45430983ef8235f2a018e7daa10a0ad71ef7b85c (diff) | |
download | llvm-90a6bb30fafa4e68d4af1fef62987fe187fa70ab.zip llvm-90a6bb30fafa4e68d4af1fef62987fe187fa70ab.tar.gz llvm-90a6bb30fafa4e68d4af1fef62987fe187fa70ab.tar.bz2 |
[remangleIntrinsicFunction] Detect and resolve name clash
It is possible that the remangled name for an intrinsic already exists with a different (and wrong) prototype within the module.
As the bitcode reader keeps both versions of all remangled intrinsics around for a longer time, this can result in a
crash, as can be seen in https://bugs.llvm.org/show_bug.cgi?id=50923
This patch makes 'remangleIntrinsicFunction' aware of this situation. When it is detected, it moves the version with the wrong prototype to a different name. That version will be removed anyway once the module is completely loaded.
With thanks to @asbirlea for reporting this issue when trying out an lto build with the full restrict patches, and @efriedma for suggesting a sane resolution mechanism.
Reviewed By: apilipenko
Differential Revision: https://reviews.llvm.org/D105118
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index b502e5c..4f4a8db 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -1676,11 +1676,26 @@ Optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) { Intrinsic::ID ID = F->getIntrinsicID(); StringRef Name = F->getName(); - if (Name == - Intrinsic::getName(ID, ArgTys, F->getParent(), F->getFunctionType())) + std::string WantedName = + Intrinsic::getName(ID, ArgTys, F->getParent(), F->getFunctionType()); + if (Name == WantedName) return None; - auto NewDecl = Intrinsic::getDeclaration(F->getParent(), ID, ArgTys); + Function *NewDecl = [&] { + if (auto *ExistingGV = F->getParent()->getNamedValue(WantedName)) { + if (auto *ExistingF = dyn_cast<Function>(ExistingGV)) + if (ExistingF->getFunctionType() == F->getFunctionType()) + return ExistingF; + + // The name already exists, but is not a function or has the wrong + // prototype. Make place for the new one by renaming the old version. + // Either this old version will be removed later on or the module is + // invalid and we'll get an error. + ExistingGV->setName(WantedName + ".renamed"); + } + return Intrinsic::getDeclaration(F->getParent(), ID, ArgTys); + }(); + NewDecl->setCallingConv(F->getCallingConv()); assert(NewDecl->getFunctionType() == F->getFunctionType() && "Shouldn't change the signature"); |