summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/AutoUpgrade.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/AutoUpgrade.cpp')
-rw-r--r--llvm/lib/IR/AutoUpgrade.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 12c354c89b2..c83313fa654 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -144,6 +144,36 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
}
+ case 'm': {
+ if (Name.startswith("memcpy.") && F->arg_size() == 5) {
+ F->setName(Name + ".old");
+ // Get the types of dest, src, and len.
+ ArrayRef<Type *> ParamTypes = F->getFunctionType()->params().slice(0, 3);
+ NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memcpy,
+ ParamTypes);
+ return true;
+ }
+ if (Name.startswith("memmove.") && F->arg_size() == 5) {
+ F->setName(Name + ".old");
+ // Get the types of dest, src, and len.
+ ArrayRef<Type *> ParamTypes = F->getFunctionType()->params().slice(0, 3);
+ NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memmove,
+ ParamTypes);
+ return true;
+ }
+ if (Name.startswith("memset.") && F->arg_size() == 5) {
+ F->setName(Name + ".old");
+ // Get the types of dest and len.
+ Type *ParamTypes[2] = {
+ F->getFunctionType()->getParamType(0),
+ F->getFunctionType()->getParamType(2)
+ };
+ NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memset,
+ ParamTypes);
+ return true;
+ }
+ break;
+ }
case 'o':
// We only need to change the name to match the mangling including the
@@ -727,6 +757,31 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
CI->eraseFromParent();
return;
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove:
+ case Intrinsic::memset: {
+ // Remove alignment argument (3), and add alignment attributes to the
+ // dest/src pointers.
+ Value *Args[4] = {
+ CI->getArgOperand(0),
+ CI->getArgOperand(1),
+ CI->getArgOperand(2),
+ CI->getArgOperand(4)
+ };
+ auto *MemCI = cast<MemIntrinsic>(Builder.CreateCall(NewFn, Args, Name));
+
+ // All mem intrinsics support dest alignment.
+ const ConstantInt *Align = cast<ConstantInt>(CI->getArgOperand(3));
+ MemCI->setDestAlignment(Align->getZExtValue());
+
+ // Memcpy/Memmove also support source alignment.
+ if (auto *MemTransferI = dyn_cast<MemTransferInst>(MemCI))
+ MemTransferI->setSrcAlignment(Align->getZExtValue());
+ CI->replaceAllUsesWith(MemCI);
+ CI->eraseFromParent();
+ return;
+ }
+
case Intrinsic::objectsize:
CI->replaceAllUsesWith(Builder.CreateCall(
NewFn, {CI->getArgOperand(0), CI->getArgOperand(1)}, Name));
OpenPOWER on IntegriCloud