[llvm] [SimpleLoopUnswitch][NFC] Factor out conditional clone legality check (PR #217884)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 21 10:07:45 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Keno Fischer (Keno)
<details>
<summary>Changes</summary>
Move the caller-side legality checks of isSafeForNoNTrivialUnswitching (no token values used outside their defining block, no convergent calls, plus the existing Loop::isSafeToClone conditions) into a new Loop::isSafeToCloneConditionally helper, preserving current behavior exactly.
Transformations that may cause cloned loop bodies to execute conditionally need these stricter conditions than plain cloning; a follow-up commit will use the helper from IRCE's LoopConstrainer as well, which is currently missing this check entirely.
Factored out of #<!-- -->151062 by review request.
---
Full diff: https://github.com/llvm/llvm-project/pull/217884.diff
3 Files Affected:
- (modified) llvm/include/llvm/Analysis/LoopInfo.h (+6)
- (modified) llvm/lib/Analysis/LoopInfo.cpp (+18)
- (modified) llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp (+1-11)
``````````diff
diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h
index 15c22e43c44bf..bbac76c85f1ed 100644
--- a/llvm/include/llvm/Analysis/LoopInfo.h
+++ b/llvm/include/llvm/Analysis/LoopInfo.h
@@ -328,6 +328,12 @@ class LLVM_ABI Loop : public LoopBase<BasicBlock, Loop> {
/// Return true if the loop body is safe to clone in practice.
bool isSafeToClone() const;
+ /// Like `isSafeToClone`, but for transformations where the cloned loop
+ /// bodies may run conditionally. This additionally rejects convergent
+ /// calls (which must not gain new control dependencies) and token values
+ /// that are used outside their defining block.
+ bool isSafeToCloneConditionally() const;
+
/// Returns true if the loop is annotated parallel.
///
/// A parallel loop can be assumed to not contain any dependencies between
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index 16a7690092ff5..ab535e302b305 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -530,6 +530,24 @@ bool Loop::isSafeToClone() const {
return true;
}
+bool Loop::isSafeToCloneConditionally() const {
+ if (!isSafeToClone())
+ return false;
+
+ for (BasicBlock *BB : this->blocks()) {
+ for (Instruction &I : *BB) {
+ if (I.getType()->isTokenTy() && I.isUsedOutsideOfBlock(BB))
+ return false;
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ assert(!CB->cannotDuplicate() && "Checked by isSafeToClone().");
+ if (CB->isConvergent())
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
MDNode *Loop::getLoopID() const {
MDNode *LoopID = nullptr;
diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
index 9425c8a8ac520..619e48f0ce509 100644
--- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -3359,18 +3359,8 @@ static bool collectUnswitchCandidatesWithInjections(
}
static bool isSafeForNoNTrivialUnswitching(Loop &L, LoopInfo &LI) {
- if (!L.isSafeToClone())
+ if (!L.isSafeToCloneConditionally())
return false;
- for (auto *BB : L.blocks())
- for (auto &I : *BB) {
- if (I.getType()->isTokenTy() && I.isUsedOutsideOfBlock(BB))
- return false;
- if (auto *CB = dyn_cast<CallBase>(&I)) {
- assert(!CB->cannotDuplicate() && "Checked by L.isSafeToClone().");
- if (CB->isConvergent())
- return false;
- }
- }
// Check if there are irreducible CFG cycles in this loop. If so, we cannot
// easily unswitch non-trivial edges out of the loop. Doing so might turn the
``````````
</details>
https://github.com/llvm/llvm-project/pull/217884
More information about the llvm-commits
mailing list