[llvm] f7b0951 - [LLVM] Add missing verifier checks for convergence control
Sameer Sahasrabuddhe via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 30 22:38:42 PDT 2023
Author: Sameer Sahasrabuddhe
Date: 2023-07-31T11:08:19+05:30
New Revision: f7b09516e466b5591914f520bdc45f7e0b64409f
URL: https://github.com/llvm/llvm-project/commit/f7b09516e466b5591914f520bdc45f7e0b64409f
DIFF: https://github.com/llvm/llvm-project/commit/f7b09516e466b5591914f520bdc45f7e0b64409f.diff
LOG: [LLVM] Add missing verifier checks for convergence control
Added:
Modified:
llvm/lib/IR/Verifier.cpp
llvm/test/Verifier/convergencectrl-invalid.ll
Removed:
################################################################################
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index ebd133a4aa61c2..21acb4185f7a8e 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);
diff --git a/llvm/test/Verifier/convergencectrl-invalid.ll b/llvm/test/Verifier/convergencectrl-invalid.ll
index a670ee1a905974..532e8d734f06e6 100644
--- a/llvm/test/Verifier/convergencectrl-invalid.ll
+++ b/llvm/test/Verifier/convergencectrl-invalid.ll
@@ -1,5 +1,14 @@
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+; CHECK: Convergence control tokens can only be produced by calls to the convergence control intrinsics.
+; CHECK-NEXT: %t04_tok1 = call token @produce_token()
+; CHECK-NEXT: call void @f() [ "convergencectrl"(token %t04_tok1) ]
+define void @wrong_token() {
+ %t04_tok1 = call token @produce_token()
+ call void @f() [ "convergencectrl"(token %t04_tok1) ]
+ ret void
+}
+
; CHECK: Expected convergent attribute on a controlled convergent call.
; CHECK-NEXT call void @g(){{.*}}%t05_tok1
define void @missing.attribute() {
@@ -8,6 +17,24 @@ define void @missing.attribute() {
ret void
}
+; CHECK: The 'convergencectrl' bundle requires exactly one token use.
+; CHECK-NEXT: call void @g()
+define void @multiple_tokens() {
+ %t06_tok1 = call token @llvm.experimental.convergence.anchor()
+ %t06_tok2 = call token @llvm.experimental.convergence.anchor()
+ call void @g() [ "convergencectrl"(token %t06_tok2, token %t06_tok1) ]
+ ret void
+}
+
+; CHECK: The 'convergencetrl' bundle can occur at most once on a call
+; CHECK-NEXT: call void @g()
+define void @multiple_bundles() {
+ %t07_tok1 = call token @llvm.experimental.convergence.anchor()
+ %t07_tok2 = call token @llvm.experimental.convergence.anchor()
+ call void @g() [ "convergencectrl"(token %t07_tok2), "convergencectrl"(token %t07_tok1) ]
+ ret void
+}
+
; CHECK: Cannot mix controlled and uncontrolled convergence in the same function
; CHECK-NEXT call void @f()
define void @mixed1() {
@@ -217,6 +244,8 @@ F:
ret void
}
+declare token @produce_token()
+
declare void @f() convergent
declare void @g()
More information about the llvm-commits
mailing list