[llvm] 2c3453a - [LoopInterchange] Bail out when finding a dependency with all `*` elements (#149049)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 25 02:37:45 PDT 2025
Author: Ryotaro Kasuga
Date: 2025-09-25T09:37:41Z
New Revision: 2c3453afd2d28d1a4d802af071c15b8620896ed3
URL: https://github.com/llvm/llvm-project/commit/2c3453afd2d28d1a4d802af071c15b8620896ed3
DIFF: https://github.com/llvm/llvm-project/commit/2c3453afd2d28d1a4d802af071c15b8620896ed3.diff
LOG: [LoopInterchange] Bail out when finding a dependency with all `*` elements (#149049)
If a direction vector with all `*` elements, like `[* * *]`, is present,
it indicates that none of the loop pairs are legal to interchange. In
such cases, continuing the analysis is meaningless.
This patch introduces a check to detect such direction vectors and exits
early when one is found. This slightly reduces compile time.
Added:
llvm/test/Transforms/LoopInterchange/bail-out-all-deps.ll
Modified:
llvm/lib/Transforms/Scalar/LoopInterchange.cpp
llvm/test/Transforms/LoopInterchange/confused-dependence.ll
llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll
llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll
llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index 08446ccaa9fca..28ae4f0a0aad9 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -260,6 +260,17 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
Dep.push_back('I');
}
+ // If all the elements of any direction vector have only '*', legality
+ // can't be proven. Exit early to save compile time.
+ if (all_of(Dep, [](char C) { return C == '*'; })) {
+ ORE->emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "Dependence",
+ L->getStartLoc(), L->getHeader())
+ << "All loops have dependencies in all directions.";
+ });
+ return false;
+ }
+
// Test whether the dependency is forward or not.
bool IsKnownForward = true;
if (Src->getParent() != Dst->getParent()) {
diff --git a/llvm/test/Transforms/LoopInterchange/bail-out-all-deps.ll b/llvm/test/Transforms/LoopInterchange/bail-out-all-deps.ll
new file mode 100644
index 0000000000000..83cfd91c4da4c
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/bail-out-all-deps.ll
@@ -0,0 +1,44 @@
+; RUN: opt < %s -passes=loop-interchange -pass-remarks-output=%t \
+; RUN: -disable-output
+; RUN: FileCheck -input-file %t %s
+
+; Check that loop interchange bails out early when finding a direction vector
+; with all '*' elements.
+;
+; for (int i = 0; i < 4; i++)
+; for (int j = 0; j < 4; j++)
+; A[i & val][j & val] = 0;
+
+; CHECK: --- !Missed
+; CHECK-NEXT: Pass: loop-interchange
+; CHECK-NEXT: Name: Dependence
+; CHECK-NEXT: Function: f
+; CHECK-NEXT: Args:
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
+; CHECK-NEXT: ...
+define void @f(ptr %A, i64 %val) {
+entry:
+ br label %for.i.header
+
+for.i.header:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %for.i.latch ]
+ br label %for.j
+
+for.j:
+ %j = phi i64 [ 0, %for.i.header ], [ %j.next, %for.j ]
+ %subscript.0 = and i64 %i, %val
+ %subscript.1 = and i64 %j, %val
+ %idx = getelementptr inbounds [4 x i8], ptr %A, i64 %subscript.0, i64 %subscript.1
+ store i8 0, ptr %idx
+ %j.next = add nuw nsw i64 %j, 1
+ %exit.j = icmp eq i64 %j.next, 4
+ br i1 %exit.j, label %for.i.latch, label %for.j
+
+for.i.latch:
+ %i.next = add nuw nsw i64 %i, 1
+ %exit.i = icmp eq i64 %i.next, 4
+ br i1 %exit.i, label %exit, label %for.i.header
+
+exit:
+ ret void
+}
diff --git a/llvm/test/Transforms/LoopInterchange/confused-dependence.ll b/llvm/test/Transforms/LoopInterchange/confused-dependence.ll
index 49b7b0e4797b8..94080949f0af8 100644
--- a/llvm/test/Transforms/LoopInterchange/confused-dependence.ll
+++ b/llvm/test/Transforms/LoopInterchange/confused-dependence.ll
@@ -1,6 +1,6 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info \
-; RUN: -disable-output -debug 2>&1 | FileCheck %s
+; RUN: opt < %s -passes=loop-interchange -pass-remarks-output=%t \
+; RUN: -disable-output
+; RUN: FileCheck -input-file %t %s
;; In the following case, p0 and p1 may alias, so the direction vector must be [* *].
;;
@@ -10,9 +10,13 @@
;; p0[4 * i + j] = p1[4 * j + i];
;; }
-; CHECK: Dependency matrix before interchange:
-; CHECK-NEXT: * *
-; CHECK-NEXT: Processing InnerLoopId = 1 and OuterLoopId = 0
+; CHECK: --- !Missed
+; CHECK-NEXT: Pass: loop-interchange
+; CHECK-NEXT: Name: Dependence
+; CHECK-NEXT: Function: may_alias
+; CHECK-NEXT: Args:
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
+; CHECK-NEXT: ...
define void @may_alias(ptr %p0, ptr %p1) {
entry:
br label %for.i.header
diff --git a/llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll b/llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll
index c30f9a399fed8..5f4a8486d9ad7 100644
--- a/llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll
+++ b/llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll
@@ -21,13 +21,13 @@
; CHECK-NEXT: Name: Dependence
; CHECK-NEXT: Function: issue46867
; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
; CHECK: --- !Missed
; CHECK-NEXT: Pass: loop-interchange
; CHECK-NEXT: Name: Dependence
; CHECK-NEXT: Function: issue46867
; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
define void @issue46867(ptr noundef captures(none) %s, i32 noundef %c, ptr noundef readonly captures(none) %ff) {
entry:
%tobool7.not = icmp eq i32 %c, 0
@@ -121,7 +121,7 @@ land.end:
; CHECK-NEXT: Name: Dependence
; CHECK-NEXT: Function: issue47401
; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
define void @issue47401(ptr noundef writeonly captures(none) %e, ptr noundef readonly captures(none) %bb) {
entry:
br label %for.cond1.preheader
@@ -175,7 +175,7 @@ land.end:
; CHECK-NEXT: Name: Dependence
; CHECK-NEXT: Function: issue47295
; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
define void @issue47295(ptr noundef captures(none) %f, ptr noundef writeonly captures(none) %cc) {
entry:
br label %for.cond1.preheader
@@ -221,7 +221,7 @@ for.body4:
; CHECK-NEXT: Name: Dependence
; CHECK-NEXT: Function: issue54176
; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
define void @issue54176(i32 noundef %n, i32 noundef %m, ptr noundef captures(none) %aa, ptr noundef readonly captures(none) %bb, ptr noundef writeonly captures(none) %cc) {
entry:
diff --git a/llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll b/llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll
index 73a566a310157..14836ba73433d 100644
--- a/llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll
+++ b/llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll
@@ -71,7 +71,7 @@ for.end19:
; CHECK-NEXT: Name: Dependence
; CHECK-NEXT: Function: test01
; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
; CHECK-NEXT: ...
; DELIN: --- !Analysis
@@ -147,7 +147,7 @@ define void @test02(i32 %k, i32 %N) {
; CHECK-NEXT: Name: Dependence
; CHECK-NEXT: Function: test02
; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
; CHECK-NEXT: ...
; DELIN: --- !Analysis
@@ -290,7 +290,7 @@ for.end17:
; CHECK-NEXT: Name: Dependence
; CHECK-NEXT: Function: test04
; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
; CHECK-NEXT: ...
; DELIN: --- !Missed
diff --git a/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll b/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll
index 68089b43121c5..3af9e7304e3be 100644
--- a/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll
+++ b/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll
@@ -2,14 +2,13 @@
; RUN: opt < %s -passes=loop-interchange -S -debug 2>&1 | FileCheck %s
; CHECK: Dependency matrix before interchange:
-; CHECK-NEXT: * *
; CHECK-NEXT: = *
; CHECK-NEXT: < *
; CHECK-NEXT: Processing InnerLoopId
; This example is taken from github issue #54176
;
-define void @foo(i32 noundef %n, i32 noundef %m, ptr nocapture noundef %aa, ptr nocapture noundef readonly %bb, ptr nocapture noundef writeonly %cc) {
+define void @foo(i32 noundef %n, i32 noundef %m, ptr nocapture noundef noalias %aa, ptr nocapture noundef readonly noalias %bb, ptr nocapture noundef writeonly noalias %cc) {
entry:
%arrayidx7 = getelementptr inbounds i8, ptr %aa, i64 512
br label %for.cond1.preheader
More information about the llvm-commits
mailing list