diff options
author | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-06-23 15:25:09 +0000 |
---|---|---|
committer | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-06-23 15:25:09 +0000 |
commit | f0c9f813796cd0cf210ba21833c5cfbaa7d65399 (patch) | |
tree | 53582157dfa1bdee5e81241e84dc0fe3bcb7735a /llvm/lib/IR/Function.cpp | |
parent | b1a2b5a708ec9993ec6c7a5eb2068864b109a43c (diff) | |
download | bcm5719-llvm-f0c9f813796cd0cf210ba21833c5cfbaa7d65399.tar.gz bcm5719-llvm-f0c9f813796cd0cf210ba21833c5cfbaa7d65399.zip |
Remangle intrinsics names when types are renamed
This is a fix for the problem mentioned in "LTO and intrinsics mangling" llvm-dev mail thread:
http://lists.llvm.org/pipermail/llvm-dev/2016-April/098387.html
Reviewers: mehdi_amini, reames
Differential Revision: http://reviews.llvm.org/D19373
llvm-svn: 273568
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index dbe8125b402..60523584034 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -1060,6 +1060,37 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> llvm_unreachable("unhandled"); } +Optional<Function*> Intrinsic::remangleIntrinsicFunction(Function *F) { + Intrinsic::ID ID = F->getIntrinsicID(); + if (!ID) + return None; + + // Accumulate an array of overloaded types for the given intrinsic + SmallVector<Type *, 4> ArgTys; + { + SmallVector<Intrinsic::IITDescriptor, 8> Table; + getIntrinsicInfoTableEntries(ID, Table); + ArrayRef<Intrinsic::IITDescriptor> TableRef = Table; + FunctionType *FTy = F->getFunctionType(); + + // If we encounter any problems matching the signature with the descriptor + // just give up remangling. It's up to verifier to report the discrepancy. + if (Intrinsic::matchIntrinsicType(FTy->getReturnType(), TableRef, ArgTys)) + return None; + for (auto Ty : FTy->params()) + if (Intrinsic::matchIntrinsicType(Ty, TableRef, ArgTys)) + return None; + } + + StringRef Name = F->getName(); + if (Name == Intrinsic::getName(ID, ArgTys)) + return None; + + auto NewDecl = Intrinsic::getDeclaration(F->getParent(), ID, ArgTys); + NewDecl->setCallingConv(F->getCallingConv()); + return NewDecl; +} + /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it. bool Function::hasAddressTaken(const User* *PutOffender) const { |