aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorSameer Sahasrabuddhe <sameer.sahasrabuddhe@amd.com>2023-07-31 09:33:42 +0530
committerSameer Sahasrabuddhe <sameer.sahasrabuddhe@amd.com>2023-07-31 11:08:19 +0530
commitf7b09516e466b5591914f520bdc45f7e0b64409f (patch)
treef8f6708678344b7dc3ed62d3a7311a5f9f071b84 /llvm/lib/IR/Verifier.cpp
parenteff53ce8fc06b2379114955d5a2f77c24f483d1a (diff)
downloadllvm-f7b09516e466b5591914f520bdc45f7e0b64409f.zip
llvm-f7b09516e466b5591914f520bdc45f7e0b64409f.tar.gz
llvm-f7b09516e466b5591914f520bdc45f7e0b64409f.tar.bz2
[LLVM] Add missing verifier checks for convergence control
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp42
1 files changed, 24 insertions, 18 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index ebd133a..21acb41 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2535,6 +2535,23 @@ void Verifier::verifySiblingFuncletUnwinds() {
}
}
+static bool isConvergenceControlIntrinsic(const CallBase &Call) {
+ switch (Call.getIntrinsicID()) {
+ case Intrinsic::experimental_convergence_anchor:
+ case Intrinsic::experimental_convergence_entry:
+ case Intrinsic::experimental_convergence_loop:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool isControlledConvergent(const CallBase &Call) {
+ if (Call.countOperandBundlesOfType(LLVMContext::OB_convergencectrl))
+ return true;
+ return isConvergenceControlIntrinsic(Call);
+}
+
void Verifier::verifyConvergenceControl(Function &F) {
DenseMap<BasicBlock *, SmallVector<CallBase *, 8>> LiveTokenMap;
DenseMap<const Cycle *, const CallBase *> CycleHearts;
@@ -2552,10 +2569,10 @@ void Verifier::verifyConvergenceControl(Function &F) {
Value *Token = Bundle.Inputs[0].get();
auto *Def = dyn_cast<CallBase>(Token);
- Check(Def != nullptr,
- "Convergence control tokens can only be produced by call "
- "instructions.",
- Token);
+ Check(Def && isConvergenceControlIntrinsic(*Def),
+ "Convergence control tokens can only be produced by calls to the "
+ "convergence control intrinsics.",
+ Token, CB);
Check(llvm::is_contained(LiveTokens, Token),
"Convergence region is not well-nested.", Token, CB);
@@ -2615,6 +2632,9 @@ void Verifier::verifyConvergenceControl(Function &F) {
if (!CB)
continue;
+ Check(CB->countOperandBundlesOfType(LLVMContext::OB_convergencectrl) <= 1,
+ "The 'convergencetrl' bundle can occur at most once on a call", CB);
+
auto Bundle = CB->getOperandBundle(LLVMContext::OB_convergencectrl);
if (Bundle)
checkBundle(*Bundle, CB, LiveTokens);
@@ -3375,20 +3395,6 @@ void Verifier::visitPHINode(PHINode &PN) {
visitInstruction(PN);
}
-static bool isControlledConvergent(const CallBase &Call) {
- if (Call.getOperandBundle(LLVMContext::OB_convergencectrl))
- return true;
- if (const auto *F = dyn_cast<Function>(Call.getCalledOperand())) {
- switch (F->getIntrinsicID()) {
- case Intrinsic::experimental_convergence_anchor:
- case Intrinsic::experimental_convergence_entry:
- case Intrinsic::experimental_convergence_loop:
- return true;
- }
- }
- return false;
-}
-
void Verifier::visitCallBase(CallBase &Call) {
Check(Call.getCalledOperand()->getType()->isPointerTy(),
"Called function must be a pointer!", Call);