aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Function.cpp
diff options
context:
space:
mode:
authorJeroen Dobbelaere <jeroen.dobbelaere@synopsys.com>2021-07-13 10:37:45 +0200
committerJeroen Dobbelaere <jeroen.dobbelaere@synopsys.com>2021-07-13 11:21:12 +0200
commit90a6bb30fafa4e68d4af1fef62987fe187fa70ab (patch)
tree324d60a0c39736d20036a49392fdccab4311b461 /llvm/lib/IR/Function.cpp
parent45430983ef8235f2a018e7daa10a0ad71ef7b85c (diff)
downloadllvm-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.cpp21
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");