summaryrefslogtreecommitdiff
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.cpp77
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);
+}