Skip to content

Commit f405c68

Browse files
authored
[OPT] Search whole BB for convergence token. (#112728)
The spec for llvm.experimental.convergence.entry says that is must be in the entry block for a function, and must preceed any other convergent operation. It does not have to be the first instruction in the entry block. Inlining assumes that the call to llvm.experimental.convergence.entry will be the first instruction after any phi instructions. This commit modifies inlining to search the entire block for the call.
1 parent 4015e18 commit f405c68

File tree

2 files changed

+45
-17
lines changed

2 files changed

+45
-17
lines changed

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,21 @@ namespace {
181181
}
182182
}
183183
};
184-
185184
} // end anonymous namespace
186185

186+
static IntrinsicInst *getConvergenceEntry(BasicBlock &BB) {
187+
auto *I = BB.getFirstNonPHI();
188+
while (I) {
189+
if (auto *IntrinsicCall = dyn_cast<ConvergenceControlInst>(I)) {
190+
if (IntrinsicCall->isEntry()) {
191+
return IntrinsicCall;
192+
}
193+
}
194+
I = I->getNextNode();
195+
}
196+
return nullptr;
197+
}
198+
187199
/// Get or create a target for the branch from ResumeInsts.
188200
BasicBlock *LandingPadInliningInfo::getInnerResumeDest() {
189201
if (InnerResumeDest) return InnerResumeDest;
@@ -2496,15 +2508,10 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
24962508
// fully implements convergence control tokens, there is no mixing of
24972509
// controlled and uncontrolled convergent operations in the whole program.
24982510
if (CB.isConvergent()) {
2499-
auto *I = CalledFunc->getEntryBlock().getFirstNonPHI();
2500-
if (auto *IntrinsicCall = dyn_cast<IntrinsicInst>(I)) {
2501-
if (IntrinsicCall->getIntrinsicID() ==
2502-
Intrinsic::experimental_convergence_entry) {
2503-
if (!ConvergenceControlToken) {
2504-
return InlineResult::failure(
2505-
"convergent call needs convergencectrl operand");
2506-
}
2507-
}
2511+
if (!ConvergenceControlToken &&
2512+
getConvergenceEntry(CalledFunc->getEntryBlock())) {
2513+
return InlineResult::failure(
2514+
"convergent call needs convergencectrl operand");
25082515
}
25092516
}
25102517

@@ -2795,13 +2802,10 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
27952802
}
27962803

27972804
if (ConvergenceControlToken) {
2798-
auto *I = FirstNewBlock->getFirstNonPHI();
2799-
if (auto *IntrinsicCall = dyn_cast<IntrinsicInst>(I)) {
2800-
if (IntrinsicCall->getIntrinsicID() ==
2801-
Intrinsic::experimental_convergence_entry) {
2802-
IntrinsicCall->replaceAllUsesWith(ConvergenceControlToken);
2803-
IntrinsicCall->eraseFromParent();
2804-
}
2805+
IntrinsicInst *IntrinsicCall = getConvergenceEntry(*FirstNewBlock);
2806+
if (IntrinsicCall) {
2807+
IntrinsicCall->replaceAllUsesWith(ConvergenceControlToken);
2808+
IntrinsicCall->eraseFromParent();
28052809
}
28062810
}
28072811

llvm/test/Transforms/Inline/convergence-inline.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,30 @@ define void @test_two_calls() convergent {
185185
ret void
186186
}
187187

188+
define i32 @token_not_first(i32 %x) convergent alwaysinline {
189+
; CHECK-LABEL: @token_not_first(
190+
; CHECK-NEXT: {{%.*}} = alloca ptr, align 8
191+
; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry()
192+
; CHECK-NEXT: [[Y:%.*]] = call i32 @g(i32 [[X:%.*]]) [ "convergencectrl"(token [[TOKEN]]) ]
193+
; CHECK-NEXT: ret i32 [[Y]]
194+
;
195+
%p = alloca ptr, align 8
196+
%token = call token @llvm.experimental.convergence.entry()
197+
%y = call i32 @g(i32 %x) [ "convergencectrl"(token %token) ]
198+
ret i32 %y
199+
}
200+
201+
define void @test_token_not_first() convergent {
202+
; CHECK-LABEL: @test_token_not_first(
203+
; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry()
204+
; CHECK-NEXT: {{%.*}} = call i32 @g(i32 23) [ "convergencectrl"(token [[TOKEN]]) ]
205+
; CHECK-NEXT: ret void
206+
;
207+
%token = call token @llvm.experimental.convergence.entry()
208+
%x = call i32 @token_not_first(i32 23) [ "convergencectrl"(token %token) ]
209+
ret void
210+
}
211+
188212
declare void @f(i32) convergent
189213
declare i32 @g(i32) convergent
190214

0 commit comments

Comments
 (0)