diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index 2b2d56f335446..774414cc40525 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -209,6 +209,14 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level, Direction = '*'; Dep.push_back(Direction); } + + // If the Dependence object doesn't have any information, fill the + // dependency vector with '*'. + if (D->isConfused()) { + assert(Dep.empty() && "Expected empty dependency vector"); + Dep.assign(Level, '*'); + } + while (Dep.size() != Level) { Dep.push_back('I'); } diff --git a/llvm/test/Transforms/LoopInterchange/confused-dependence.ll b/llvm/test/Transforms/LoopInterchange/confused-dependence.ll new file mode 100644 index 0000000000000..49b7b0e4797b8 --- /dev/null +++ b/llvm/test/Transforms/LoopInterchange/confused-dependence.ll @@ -0,0 +1,41 @@ +; REQUIRES: asserts +; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info \ +; RUN: -disable-output -debug 2>&1 | FileCheck %s + +;; In the following case, p0 and p1 may alias, so the direction vector must be [* *]. +;; +;; void may_alias(float *p0, float *p1) { +;; for (int i = 0; i < 4; i++) +;; for (int j = 0; j < 4; j++) +;; p0[4 * i + j] = p1[4 * j + i]; +;; } + +; CHECK: Dependency matrix before interchange: +; CHECK-NEXT: * * +; CHECK-NEXT: Processing InnerLoopId = 1 and OuterLoopId = 0 +define void @may_alias(ptr %p0, ptr %p1) { +entry: + br label %for.i.header + +for.i.header: + %i = phi i32 [ 0, %entry ], [ %i.inc, %for.i.latch ] + br label %for.j + +for.j: + %j = phi i32 [ 0, %for.i.header ], [ %j.inc, %for.j ] + %idx.0 = getelementptr inbounds [4 x [4 x float]], ptr %p0, i32 0, i32 %j, i32 %i + %idx.1 = getelementptr inbounds [4 x [4 x float]], ptr %p1, i32 0, i32 %i, i32 %j + %0 = load float, ptr %idx.0, align 4 + store float %0, ptr %idx.1, align 4 + %j.inc = add nuw nsw i32 %j, 1 + %cmp.j = icmp slt i32 %j.inc, 4 + br i1 %cmp.j, label %for.j, label %for.i.latch + +for.i.latch: + %i.inc = add nuw nsw i32 %i, 1 + %cmp.i = icmp slt i32 %i.inc, 4 + br i1 %cmp.i, label %for.i.header, label %exit + +exit: + ret void +} diff --git a/llvm/test/Transforms/LoopInterchange/pr43326-ideal-access-pattern.ll b/llvm/test/Transforms/LoopInterchange/pr43326-ideal-access-pattern.ll index 520e1ee3506da..732b9b2766302 100644 --- a/llvm/test/Transforms/LoopInterchange/pr43326-ideal-access-pattern.ll +++ b/llvm/test/Transforms/LoopInterchange/pr43326-ideal-access-pattern.ll @@ -4,7 +4,7 @@ ; Triply nested loop, should be able to do interchange three times ; to get the ideal access pattern. -; void f(int e[10][10][10], int f[10][10][10]) { +; void f(int e[restrict 10][10][10], int f[restrict 10][10][10]) { ; for (int a = 0; a < 10; a++) { ; for (int b = 0; b < 10; b++) { ; for (int c = 0; c < 10; c++) { @@ -35,7 +35,7 @@ ; REMARKS-NEXT: Name: Interchanged ; REMARKS-NEXT: Function: pr43326-triply-nested -define void @pr43326-triply-nested(ptr %e, ptr %f) { +define void @pr43326-triply-nested(ptr noalias %e, ptr noalias %f) { entry: br label %for.outermost.header diff --git a/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll b/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll index e5c18830784ac..68089b43121c5 100644 --- a/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll +++ b/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -passes=loop-interchange -S -debug 2>&1 | FileCheck %s ; CHECK: Dependency matrix before interchange: -; CHECK-NEXT: I I +; CHECK-NEXT: * * ; CHECK-NEXT: = * ; CHECK-NEXT: < * ; CHECK-NEXT: Processing InnerLoopId