diff options
Diffstat (limited to 'llvm/lib/IR/AutoUpgrade.cpp')
-rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 79f580d0e14d..6e2beeb839b6 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -22,6 +22,9 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/IntrinsicsAArch64.h" +#include "llvm/IR/IntrinsicsARM.h" +#include "llvm/IR/IntrinsicsX86.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" @@ -559,14 +562,33 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::thread_pointer); return true; } + if (Name.startswith("arm.neon.vqadds.")) { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::sadd_sat, + F->arg_begin()->getType()); + return true; + } + if (Name.startswith("arm.neon.vqaddu.")) { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::uadd_sat, + F->arg_begin()->getType()); + return true; + } + if (Name.startswith("arm.neon.vqsubs.")) { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ssub_sat, + F->arg_begin()->getType()); + return true; + } + if (Name.startswith("arm.neon.vqsubu.")) { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::usub_sat, + F->arg_begin()->getType()); + return true; + } if (Name.startswith("aarch64.neon.addp")) { if (F->arg_size() != 2) break; // Invalid IR. - auto fArgs = F->getFunctionType()->params(); - VectorType *ArgTy = dyn_cast<VectorType>(fArgs[0]); - if (ArgTy && ArgTy->getElementType()->isFloatingPointTy()) { + VectorType *Ty = dyn_cast<VectorType>(F->getReturnType()); + if (Ty && Ty->getElementType()->isFloatingPointTy()) { NewFn = Intrinsic::getDeclaration(F->getParent(), - Intrinsic::aarch64_neon_faddp, fArgs); + Intrinsic::aarch64_neon_faddp, Ty); return true; } } @@ -3877,15 +3899,36 @@ void llvm::UpgradeARCRuntime(Module &M) { FunctionType *NewFuncTy = NewFn->getFunctionType(); SmallVector<Value *, 2> Args; + // Don't upgrade the intrinsic if it's not valid to bitcast the return + // value to the return type of the old function. + if (NewFuncTy->getReturnType() != CI->getType() && + !CastInst::castIsValid(Instruction::BitCast, CI, + NewFuncTy->getReturnType())) + continue; + + bool InvalidCast = false; + for (unsigned I = 0, E = CI->getNumArgOperands(); I != E; ++I) { Value *Arg = CI->getArgOperand(I); + // Bitcast argument to the parameter type of the new function if it's // not a variadic argument. - if (I < NewFuncTy->getNumParams()) + if (I < NewFuncTy->getNumParams()) { + // Don't upgrade the intrinsic if it's not valid to bitcast the argument + // to the parameter type of the new function. + if (!CastInst::castIsValid(Instruction::BitCast, Arg, + NewFuncTy->getParamType(I))) { + InvalidCast = true; + break; + } Arg = Builder.CreateBitCast(Arg, NewFuncTy->getParamType(I)); + } Args.push_back(Arg); } + if (InvalidCast) + continue; + // Create a call instruction that calls the new function. CallInst *NewCall = Builder.CreateCall(NewFuncTy, NewFn, Args); NewCall->setTailCallKind(cast<CallInst>(CI)->getTailCallKind()); @@ -4119,9 +4162,7 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { // If X86, and the datalayout matches the expected format, add pointer size // address spaces to the datalayout. - Triple::ArchType Arch = Triple(TT).getArch(); - if ((Arch != llvm::Triple::x86 && Arch != llvm::Triple::x86_64) || - DL.contains(AddrSpaces)) + if (!Triple(TT).isX86() || DL.contains(AddrSpaces)) return DL; SmallVector<StringRef, 4> Groups; @@ -4133,3 +4174,23 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { std::string Res = (Groups[1] + AddrSpaces + Groups[3]).toStringRef(Buf).str(); return Res; } + +void llvm::UpgradeFramePointerAttributes(AttrBuilder &B) { + StringRef FramePointer; + if (B.contains("no-frame-pointer-elim")) { + // The value can be "true" or "false". + for (const auto &I : B.td_attrs()) + if (I.first == "no-frame-pointer-elim") + FramePointer = I.second == "true" ? "all" : "none"; + B.removeAttribute("no-frame-pointer-elim"); + } + if (B.contains("no-frame-pointer-elim-non-leaf")) { + // The value is ignored. "no-frame-pointer-elim"="true" takes priority. + if (FramePointer != "all") + FramePointer = "non-leaf"; + B.removeAttribute("no-frame-pointer-elim-non-leaf"); + } + + if (!FramePointer.empty()) + B.addAttribute("frame-pointer", FramePointer); +} |