Skip to content

Commit ee49453

Browse files
authored
[LLVM] convergence verifier should visit all instructions (llvm#66200)
The entry and loop intrinsics for convergence control cannot be preceded by convergent operations in their respective basic blocks. To check that, the verifier needs to reset its state at the start of the block. This was missed in the previous commit fa6dd7a.
1 parent e9dfe08 commit ee49453

File tree

4 files changed

+18
-11
lines changed

4 files changed

+18
-11
lines changed

Diff for: llvm/include/llvm/ADT/GenericConvergenceVerifier.h

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ template <typename ContextT> class GenericConvergenceVerifier {
4040
}
4141

4242
void clear();
43+
void visit(const BlockT &BB);
4344
void visit(const InstructionT &I);
4445
void verify(const DominatorTreeT &DT);
4546

Diff for: llvm/include/llvm/IR/GenericConvergenceVerifierImpl.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@ template <class ContextT> void GenericConvergenceVerifier<ContextT>::clear() {
6767
ConvergenceKind = NoConvergence;
6868
}
6969

70+
template <class ContextT>
71+
void GenericConvergenceVerifier<ContextT>::visit(const BlockT &BB) {
72+
SeenFirstConvOp = false;
73+
}
74+
7075
template <class ContextT>
7176
void GenericConvergenceVerifier<ContextT>::visit(const InstructionT &I) {
7277
auto ID = ContextT::getIntrinsicID(I);
7378
auto *TokenDef = findAndCheckConvergenceTokenUsed(I);
7479
bool IsCtrlIntrinsic = true;
7580

76-
// If this is the first instruction in the block, then we have not seen a
77-
// convergent op yet.
78-
if (!I.getPrevNode())
79-
SeenFirstConvOp = false;
80-
8181
switch (ID) {
8282
case Intrinsic::experimental_convergence_entry:
8383
Check(isInsideConvergentFunction(I),

Diff for: llvm/lib/IR/Verifier.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
363363
SmallVector<const DILocalVariable *, 16> DebugFnArgs;
364364

365365
TBAAVerifier TBAAVerifyHelper;
366-
ConvergenceVerifier CV;
366+
ConvergenceVerifier ConvergenceVerifyHelper;
367367

368368
SmallVector<IntrinsicInst *, 4> NoAliasScopeDecls;
369369

@@ -408,15 +408,15 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
408408
auto FailureCB = [this](const Twine &Message) {
409409
this->CheckFailed(Message);
410410
};
411-
CV.initialize(OS, FailureCB, F);
411+
ConvergenceVerifyHelper.initialize(OS, FailureCB, F);
412412

413413
Broken = false;
414414
// FIXME: We strip const here because the inst visitor strips const.
415415
visit(const_cast<Function &>(F));
416416
verifySiblingFuncletUnwinds();
417417

418-
if (CV.sawTokens())
419-
CV.verify(DT);
418+
if (ConvergenceVerifyHelper.sawTokens())
419+
ConvergenceVerifyHelper.verify(DT);
420420

421421
InstsInThisBlock.clear();
422422
DebugFnArgs.clear();
@@ -2867,6 +2867,7 @@ void Verifier::visitFunction(const Function &F) {
28672867
//
28682868
void Verifier::visitBasicBlock(BasicBlock &BB) {
28692869
InstsInThisBlock.clear();
2870+
ConvergenceVerifyHelper.visit(BB);
28702871

28712872
// Ensure that basic blocks have terminators!
28722873
Check(BB.getTerminator(), "Basic Block does not have terminator!", &BB);
@@ -3568,7 +3569,7 @@ void Verifier::visitCallBase(CallBase &Call) {
35683569
if (Call.isInlineAsm())
35693570
verifyInlineAsmCall(Call);
35703571

3571-
CV.visit(Call);
3572+
ConvergenceVerifyHelper.visit(Call);
35723573

35733574
visitInstruction(Call);
35743575
}

Diff for: llvm/test/Verifier/convergencectrl-invalid.ll

+6-1
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,18 @@ define void @entry_in_convergent(i32 %x, i32 %y) {
126126
}
127127

128128
; CHECK: Loop intrinsic cannot be preceded by a convergent operation in the same basic block.
129-
; CHECK: %t60_tok3
129+
; CHECK-NEXT: %h1
130+
; CHECK-SAME: %t60_tok3
130131
define void @loop_at_start(i32 %x, i32 %y) convergent {
131132
A:
132133
%t60_tok3 = call token @llvm.experimental.convergence.entry()
133134
br label %B
134135
B:
135136
%z = add i32 %x, %y
137+
; This is not an error
138+
%h2 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t60_tok3) ]
139+
br label %C
140+
C:
136141
call void @f()
137142
%h1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t60_tok3) ]
138143
ret void

0 commit comments

Comments
 (0)