[llvm] [IndVarSimplify] Fix `IndVarSimplify` to skip on unfolding predicates when the loop contains control convergence operations. (PR #165643)
Steven Perron via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 31 06:40:41 PDT 2025
================
@@ -1859,6 +1859,37 @@ bool IndVarSimplify::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
}
}
+ // If the loop body uses a convergence token defined within the loop, skip
+ // predication. This is to avoid changing the convergence behavior of the
+ // loop.
+ SmallVector<BasicBlock *, 16> blocks = ExitingBlocks;
+ SmallVector<Value *, 16> tokens = {};
+ size_t index = 0; // Assume Exiting Blocks are sorted.
+ while (index < blocks.size()) {
+ BasicBlock *BB = blocks[index];
+ index++;
+ const auto exitingBlockName = BB->getName();
+ for (Instruction &I : *BB) {
+ // Check if the instruction uses any convergence tokens.
+ if (auto *CB = dyn_cast<CallBase>(&I);
+ CB && !isa<ConvergenceControlInst>(&I)) {
+ auto token = CB->getConvergenceControlToken();
+ if (token && llvm::is_contained(tokens, token)) {
+ return false;
+ }
+ }
+ if (isa<ConvergenceControlInst>(&I)) {
+ tokens.push_back(cast<Value>(&I));
+ }
+ }
+
+ for (BasicBlock *Succ : successors(BB)) {
----------------
s-perron wrote:
> I don't think analyzeBasicBlock is appropriate here -- CodeMetrics is a utility for transforms that perform block cloning.
For the convergence tokens, the check if there is an extended loop does exactly what you suggested. If the loop has a convergence token and it is used outside the loop, then the convergence will be `ExtendedLoop`. However, it can be overkill because it checks for more than it necessary for this pass.
Also it is not appropriate if we want to generalized this to all tokens, which seems to be the right direction.
https://github.com/llvm/llvm-project/pull/165643
More information about the llvm-commits
mailing list