[llvm] [LoopInterchange] Don't consider loops with BTC=0 (PR #167113)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 8 01:20:55 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Sjoerd Meijer (sjoerdmeijer)
<details>
<summary>Changes</summary>
Do not consider loops with a zero backedge taken count as candidates for interchange. This seems like a sensible thing to do to me, because it suggests the loop doesn't execute and there is no point in interchanging.
This avoids triggering an assert about phis and their uses. I have a feeling that this fix might be hiding the issue, but I haven't yet been able to trigger the assert with other test cases; every time the loops are rejected for other reasons.
Since I think this is a self-contained improvement that avoids a lot of test failures, I propose to reject this loops while I investigate further if I can still trigger this in some way.
(Partial) fix for #<!-- -->163954
---
Full diff: https://github.com/llvm/llvm-project/pull/167113.diff
7 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/LoopInterchange.cpp (+14)
- (modified) llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-4.ll (+1-1)
- (modified) llvm/test/Transforms/LoopInterchange/lcssa-phi-outer-latch.ll (+1-1)
- (modified) llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll (+1-1)
- (modified) llvm/test/Transforms/LoopInterchange/pr43326.ll (+1-1)
- (modified) llvm/test/Transforms/LoopInterchange/pr57148.ll (+1-1)
- (modified) llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll (+1-1)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index 9aaf6a5aa4d6a..11e1723eb03d9 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -101,6 +101,12 @@ static cl::opt<unsigned int> MaxLoopNestDepth(
"loop-interchange-max-loop-nest-depth", cl::init(10), cl::Hidden,
cl::desc("Maximum depth of loop nest considered for the transform"));
+// This is mainly for testing purposes, and certain tests that rely on
+// behaviour that is more difficult to trigger otherwise.
+static cl::opt<bool> SkipLoopsWithZeroBTC(
+ "loop-interchange-skip-zero-btc", cl::init(true), cl::Hidden,
+ cl::desc("Do not consider loops with a backedge taken count of 0"));
+
// We prefer cache cost to vectorization by default.
static cl::list<RuleTy> Profitabilities(
"loop-interchange-profitabilities", cl::ZeroOrMore,
@@ -428,6 +434,13 @@ static bool isComputableLoopNest(ScalarEvolution *SE,
LLVM_DEBUG(dbgs() << "Couldn't compute backedge count\n");
return false;
}
+ // A loop with a backedge that isn't taken, e.g. an unconditional branch
+ // true, isn't really a loop and we don't want to consider it as a
+ // candidate.
+ if (ExitCountOuter && SkipLoopsWithZeroBTC && ExitCountOuter->isZero()) {
+ LLVM_DEBUG(dbgs() << "Single iteration loop\n");
+ return false;
+ }
if (L->getNumBackEdges() != 1) {
LLVM_DEBUG(dbgs() << "NumBackEdges is not equal to 1\n");
return false;
@@ -1808,6 +1821,7 @@ static void moveLCSSAPhis(BasicBlock *InnerExit, BasicBlock *InnerHeader,
assert(all_of(P.users(),
[OuterHeader, OuterExit, IncI, InnerHeader](User *U) {
+ dbgs() << "USER: "; U->dump();
return (cast<PHINode>(U)->getParent() == OuterHeader &&
IncI->getParent() == InnerHeader) ||
cast<PHINode>(U)->getParent() == OuterExit;
diff --git a/llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-4.ll b/llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-4.ll
index 70fff161154d8..a4dbd5a005082 100644
--- a/llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-4.ll
+++ b/llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-4.ll
@@ -1,5 +1,5 @@
; REQUIRES: asserts
-; RUN: opt < %s -passes="loop(loop-interchange,loop-interchange)" -cache-line-size=8 -verify-dom-info -verify-loop-info \
+; RUN: opt < %s -passes="loop(loop-interchange,loop-interchange)" -cache-line-size=8 -verify-dom-info -verify-loop-info -loop-interchange-skip-zero-btc=false \
; RUN: -debug-only=loop-interchange 2>&1 | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/llvm/test/Transforms/LoopInterchange/lcssa-phi-outer-latch.ll b/llvm/test/Transforms/LoopInterchange/lcssa-phi-outer-latch.ll
index a5e3accaf8e10..ec02110c90e3b 100644
--- a/llvm/test/Transforms/LoopInterchange/lcssa-phi-outer-latch.ll
+++ b/llvm/test/Transforms/LoopInterchange/lcssa-phi-outer-latch.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s
+; RUN: opt < %s -passes=loop-interchange -loop-interchange-skip-zero-btc=false -cache-line-size=64 -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s
; This test is checking that blocks outer.body and outer.latch, where outer.body is the exit
; block of the inner loop and outer.latch the latch of the outer loop, correctly
diff --git a/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll b/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll
index 6b25c3bc9a4ba..56140236825b7 100644
--- a/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll
+++ b/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -loop-interchange-skip-zero-btc=false -S
; RUN: FileCheck --input-file=%t %s
@b = external dso_local global [5 x i32], align 16
diff --git a/llvm/test/Transforms/LoopInterchange/pr43326.ll b/llvm/test/Transforms/LoopInterchange/pr43326.ll
index c25c4fadd3042..8ce3d59e3420f 100644
--- a/llvm/test/Transforms/LoopInterchange/pr43326.ll
+++ b/llvm/test/Transforms/LoopInterchange/pr43326.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
-; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa -stats 2>&1
+; RUN: -loop-interchange-skip-zero-btc=false -verify-dom-info -verify-loop-info -verify-loop-lcssa -stats 2>&1
; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s
@a = global i32 0
diff --git a/llvm/test/Transforms/LoopInterchange/pr57148.ll b/llvm/test/Transforms/LoopInterchange/pr57148.ll
index 0d4194762a692..51cad15964ed4 100644
--- a/llvm/test/Transforms/LoopInterchange/pr57148.ll
+++ b/llvm/test/Transforms/LoopInterchange/pr57148.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=4 -loop-interchange-threshold=-100 -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s
+; RUN: opt < %s -passes=loop-interchange -loop-interchange-skip-zero-btc=false -cache-line-size=4 -loop-interchange-threshold=-100 -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s
; Make sure the loops are in LCSSA form after loop interchange,
; and loop interchange does not hit assertion errors and crash.
diff --git a/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll b/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll
index 27d99e05e84ee..fad6a6e70037c 100644
--- a/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll
+++ b/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
-; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa -stats 2>&1 | FileCheck %s
+; RUN: -loop-interchange-skip-zero-btc=false -verify-dom-info -verify-loop-info -verify-loop-lcssa -stats 2>&1 | FileCheck %s
; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s
``````````
</details>
https://github.com/llvm/llvm-project/pull/167113
More information about the llvm-commits
mailing list