[llvm] [LoopInterchange] Fix depends() check parameters (PR #77719)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 10 19:19:31 PST 2024


https://github.com/ShivaChen created https://github.com/llvm/llvm-project/pull/77719

This commit enables loop-interchange with -enable-loopinterchange for the case in https://github.com/llvm/llvm-project/issues/71519.
With the loop-interchange, the case can be vectorized.

    for (int nl = 0; nl < 10000000/256; nl++)
      for (int i = 0; i < 256; ++i)
        for (int j = 1; j < 256; j++)
          aa[j][i] = aa[j - 1][i] + bb[j][i];

The commit address the issues that:
1. populateDependencyMatrix determine aa[j][i] has output dependency with itself.
2. The reversed parameter order of depends() caused the distance between aa[j][i] and aa[j - 1][i] be -1 instead of 1.

>From a5e45b10a198ec3e3bd0495a6ddf0700401cb0f1 Mon Sep 17 00:00:00 2001
From: Shiva Chen <shiva.chen at imgtec.com>
Date: Mon, 8 Jan 2024 07:30:24 +0000
Subject: [PATCH 1/3] Add interchange-s231.ll

---
 .../LoopInterchange/interchange-s231.ll       | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopInterchange/interchange-s231.ll

diff --git a/llvm/test/Transforms/LoopInterchange/interchange-s231.ll b/llvm/test/Transforms/LoopInterchange/interchange-s231.ll
new file mode 100644
index 00000000000000..6d096ac8f63bf4
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/interchange-s231.ll
@@ -0,0 +1,59 @@
+; REQUIRES: asserts
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
+; RUN:     -S -debug 2>&1 | FileCheck %s
+
+ at aa = global [256 x [256 x float]] zeroinitializer, align 64
+ at bb = global [256 x [256 x float]] zeroinitializer, align 64
+
+;;  for (int nl = 0; nl < 10000000/256; nl++)
+;;    for (int i = 0; i < 256; ++i)
+;;      for (int j = 1; j < 256; j++)
+;;        aa[j][i] = aa[j - 1][i] + bb[j][i];
+
+; CHECK: Found output dependency between Src and Dst
+; CHECK:  Src:  store float %add, ptr %arrayidx18
+; CHECK:  Dst:  store float %add, ptr %arrayidx18
+; CHECK: Processing InnerLoopId = 2 and OuterLoopId = 1
+; CHECK: Not interchanging loops. Cannot prove legality.
+
+define float @s231() {
+entry:
+  br label %for.cond1.preheader
+
+; Loop:
+for.cond1.preheader:                              ; preds = %entry, %for.cond.cleanup3
+  %nl.036 = phi i32 [ 0, %entry ], [ %inc23, %for.cond.cleanup3 ]
+  br label %for.cond5.preheader
+
+for.cond.cleanup3:                                ; preds = %for.cond.cleanup7
+  %inc23 = add nuw nsw i32 %nl.036, 1
+  %exitcond41 = icmp ne i32 %inc23, 39062
+  br i1 %exitcond41, label %for.cond1.preheader, label %for.cond.cleanup
+
+for.cond.cleanup7:                                ; preds = %for.body8
+  %indvars.iv.next39 = add nuw nsw i64 %indvars.iv38, 1
+  %exitcond40 = icmp ne i64 %indvars.iv.next39, 256
+  br i1 %exitcond40, label %for.cond5.preheader, label %for.cond.cleanup3
+
+for.body8:                                        ; preds = %for.cond5.preheader, %for.body8
+  %indvars.iv = phi i64 [ 1, %for.cond5.preheader ], [ %indvars.iv.next, %for.body8 ]
+  %0 = add nsw i64 %indvars.iv, -1
+  %arrayidx10 = getelementptr inbounds [256 x [256 x float]], ptr @aa, i64 0, i64 %0, i64 %indvars.iv38
+  %1 = load float, ptr %arrayidx10, align 4
+  %arrayidx14 = getelementptr inbounds [256 x [256 x float]], ptr @bb, i64 0, i64 %indvars.iv, i64 %indvars.iv38
+  %2 = load float, ptr %arrayidx14, align 4
+  %add = fadd fast float %2, %1
+  %arrayidx18 = getelementptr inbounds [256 x [256 x float]], ptr @aa, i64 0, i64 %indvars.iv, i64 %indvars.iv38
+  store float %add, ptr %arrayidx18, align 4
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  %exitcond = icmp ne i64 %indvars.iv.next, 256
+  br i1 %exitcond, label %for.body8, label %for.cond.cleanup7
+
+for.cond5.preheader:                              ; preds = %for.cond1.preheader, %for.cond.cleanup7
+  %indvars.iv38 = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next39, %for.cond.cleanup7 ]
+  br label %for.body8
+
+; Exit blocks
+for.cond.cleanup:                                 ; preds = %for.cond.cleanup3
+  ret float undef
+}

>From 1a11302a9403db1b518a1ae6cc364aa4a8953eaa Mon Sep 17 00:00:00 2001
From: Shiva Chen <shiva.chen at imgtec.com>
Date: Mon, 8 Jan 2024 07:46:15 +0000
Subject: [PATCH 2/3] [LoopInterchange] Skip dependence check to the same
 instruction

---
 llvm/lib/Transforms/Scalar/LoopInterchange.cpp           | 2 +-
 llvm/test/Transforms/LoopInterchange/interchange-s231.ll | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index 277f530ee25fc1..c578474732cf46 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -113,7 +113,7 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
   ValueVector::iterator I, IE, J, JE;
 
   for (I = MemInstr.begin(), IE = MemInstr.end(); I != IE; ++I) {
-    for (J = I, JE = MemInstr.end(); J != JE; ++J) {
+    for (J = I + 1, JE = MemInstr.end(); J != JE; ++J) {
       std::vector<char> Dep;
       Instruction *Src = cast<Instruction>(*I);
       Instruction *Dst = cast<Instruction>(*J);
diff --git a/llvm/test/Transforms/LoopInterchange/interchange-s231.ll b/llvm/test/Transforms/LoopInterchange/interchange-s231.ll
index 6d096ac8f63bf4..a69e5ace680b23 100644
--- a/llvm/test/Transforms/LoopInterchange/interchange-s231.ll
+++ b/llvm/test/Transforms/LoopInterchange/interchange-s231.ll
@@ -10,9 +10,9 @@
 ;;      for (int j = 1; j < 256; j++)
 ;;        aa[j][i] = aa[j - 1][i] + bb[j][i];
 
-; CHECK: Found output dependency between Src and Dst
-; CHECK:  Src:  store float %add, ptr %arrayidx18
-; CHECK:  Dst:  store float %add, ptr %arrayidx18
+; CHECK: Found anti dependency between Src and Dst
+; CHECK:  Src:  %1 = load float, ptr %arrayidx10, align 4
+; CHECK:  Dst:  store float %add, ptr %arrayidx18, align 4
 ; CHECK: Processing InnerLoopId = 2 and OuterLoopId = 1
 ; CHECK: Not interchanging loops. Cannot prove legality.
 

>From 8de55ee03e3d3197b6d242b57c3a56075d01b650 Mon Sep 17 00:00:00 2001
From: Shiva Chen <shiva.chen at imgtec.com>
Date: Mon, 8 Jan 2024 07:54:30 +0000
Subject: [PATCH 3/3] [LoopInterchange] Fix depends() check parameters

---
 llvm/lib/Transforms/Scalar/LoopInterchange.cpp           | 4 ++--
 llvm/test/Transforms/LoopInterchange/interchange-s231.ll | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index c578474732cf46..d4b78f4f04599c 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -115,8 +115,8 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
   for (I = MemInstr.begin(), IE = MemInstr.end(); I != IE; ++I) {
     for (J = I + 1, JE = MemInstr.end(); J != JE; ++J) {
       std::vector<char> Dep;
-      Instruction *Src = cast<Instruction>(*I);
-      Instruction *Dst = cast<Instruction>(*J);
+      Instruction *Src = cast<Instruction>(*J);
+      Instruction *Dst = cast<Instruction>(*I);
       // Ignore Input dependencies.
       if (isa<LoadInst>(Src) && isa<LoadInst>(Dst))
         continue;
diff --git a/llvm/test/Transforms/LoopInterchange/interchange-s231.ll b/llvm/test/Transforms/LoopInterchange/interchange-s231.ll
index a69e5ace680b23..5b51d2169fe510 100644
--- a/llvm/test/Transforms/LoopInterchange/interchange-s231.ll
+++ b/llvm/test/Transforms/LoopInterchange/interchange-s231.ll
@@ -10,11 +10,11 @@
 ;;      for (int j = 1; j < 256; j++)
 ;;        aa[j][i] = aa[j - 1][i] + bb[j][i];
 
-; CHECK: Found anti dependency between Src and Dst
-; CHECK:  Src:  %1 = load float, ptr %arrayidx10, align 4
-; CHECK:  Dst:  store float %add, ptr %arrayidx18, align 4
+; CHECK: Found flow dependency between Src and Dst
+; CHECK:  Src:  store float %add, ptr %arrayidx18, align 4
+; CHECK:  Dst:  %1 = load float, ptr %arrayidx10, align 4
 ; CHECK: Processing InnerLoopId = 2 and OuterLoopId = 1
-; CHECK: Not interchanging loops. Cannot prove legality.
+; CHECK: Loops interchanged.
 
 define float @s231() {
 entry:



More information about the llvm-commits mailing list