summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/Verifier.cpp26
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp8
2 files changed, 32 insertions, 2 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 5621962497a..1b36eb9bd68 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -243,6 +243,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
/// Cache of constants visited in search of ConstantExprs.
SmallPtrSet<const Constant *, 32> ConstantExprVisited;
+ /// Cache of declarations of the llvm.experimental.deoptimize.<ty> intrinsic.
+ SmallVector<const Function *, 4> DeoptimizeDeclarations;
+
// Verify that this GlobalValue is only used in this module.
// This map is used to avoid visiting uses twice. We can arrive at a user
// twice, if they have multiple operands. In particular for very large
@@ -322,8 +325,11 @@ public:
visitGlobalValue(F);
// Check to make sure function prototypes are okay.
- if (F.isDeclaration())
+ if (F.isDeclaration()) {
visitFunction(F);
+ if (F.getIntrinsicID() == Intrinsic::experimental_deoptimize)
+ DeoptimizeDeclarations.push_back(&F);
+ }
}
// Now that we've visited every function, verify that we never asked to
@@ -346,6 +352,8 @@ public:
verifyCompileUnits();
+ verifyDeoptimizeCallingConvs();
+
return !Broken;
}
@@ -470,6 +478,10 @@ private:
/// Module-level debug info verification...
void verifyCompileUnits();
+
+ /// Module-level verification that all @llvm.experimental.deoptimize
+ /// declarations share the same calling convention.
+ void verifyDeoptimizeCallingConvs();
};
} // End anonymous namespace
@@ -4396,6 +4408,18 @@ void Verifier::verifyCompileUnits() {
CUVisited.clear();
}
+void Verifier::verifyDeoptimizeCallingConvs() {
+ if (DeoptimizeDeclarations.empty())
+ return;
+
+ const Function *First = DeoptimizeDeclarations[0];
+ for (auto *F : makeArrayRef(DeoptimizeDeclarations).slice(1))
+ Assert(First->getCallingConv() == F->getCallingConv(),
+ "All llvm.experimental.deoptimize declarations must have the same "
+ "calling convention",
+ First, F);
+}
+
//===----------------------------------------------------------------------===//
// Implement the public interfaces to this file...
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 5b0640c7237..c8d76f4d9e8 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1874,7 +1874,13 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
continue;
}
- auto CallingConv = DeoptCall->getCallingConv();
+ // The calling convention on the deoptimize call itself may be bogus,
+ // since the code we're inlining may have undefined behavior (and may
+ // never actually execute at runtime); but all
+ // @llvm.experimental.deoptimize declarations have to have the same
+ // calling convention in a well-formed module.
+ auto CallingConv = DeoptCall->getCalledFunction()->getCallingConv();
+ NewDeoptIntrinsic->setCallingConv(CallingConv);
auto *CurBB = RI->getParent();
RI->eraseFromParent();
OpenPOWER on IntegriCloud