[LV/LoopAccesses] Backward dependences are not safe just because the
authorAdam Nemet <anemet@apple.com>
Thu, 26 Feb 2015 17:58:48 +0000 (17:58 +0000)
committerAdam Nemet <anemet@apple.com>
Thu, 26 Feb 2015 17:58:48 +0000 (17:58 +0000)
accesses are via different types

Noticed this while generalizing the code for loop distribution.

I confirmed with Arnold that this was indeed a bug and managed to create
a testcase.

llvm-svn: 230647

llvm/lib/Analysis/LoopAccessAnalysis.cpp
llvm/test/Analysis/LoopAccessAnalysis/backward-dep-different-types.ll [new file with mode: 0644]

index 1a0bf48..7bedd40 100644 (file)
@@ -794,11 +794,10 @@ bool MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
 
   assert(Val.isStrictlyPositive() && "Expect a positive value");
 
-  // Positive distance bigger than max vectorization factor.
   if (ATy != BTy) {
     DEBUG(dbgs() <<
           "LAA: ReadWrite-Write positive dependency with different types\n");
-    return false;
+    return true;
   }
 
   unsigned Distance = (unsigned) Val.getZExtValue();
@@ -820,6 +819,7 @@ bool MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
     return true;
   }
 
+  // Positive distance bigger than max vectorization factor.
   MaxSafeDepDistBytes = Distance < MaxSafeDepDistBytes ?
     Distance : MaxSafeDepDistBytes;
 
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/backward-dep-different-types.ll b/llvm/test/Analysis/LoopAccessAnalysis/backward-dep-different-types.ll
new file mode 100644 (file)
index 0000000..f503a5c
--- /dev/null
@@ -0,0 +1,50 @@
+; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+
+; In this loop just because we access A through different types (int, float)
+; we still have a dependence cycle:
+;
+;   for (i = 0; i < n; i++) {
+;    A_float = (float *) A;
+;    A_float[i + 1] = A[i] * B[i];
+;   }
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.10.0"
+
+; CHECK: Report: unsafe dependent memory operations in loop
+; CHECK-NOT: Memory dependences are safe
+
+@n = global i32 20, align 4
+@B = common global i32* null, align 8
+@A = common global i32* null, align 8
+
+define void @f() {
+entry:
+  %a = load i32** @A, align 8
+  %b = load i32** @B, align 8
+  br label %for.body
+
+for.body:                                         ; preds = %for.body, %entry
+  %storemerge3 = phi i64 [ 0, %entry ], [ %add, %for.body ]
+
+  %arrayidxA = getelementptr inbounds i32* %a, i64 %storemerge3
+  %loadA = load i32* %arrayidxA, align 2
+
+  %arrayidxB = getelementptr inbounds i32* %b, i64 %storemerge3
+  %loadB = load i32* %arrayidxB, align 2
+
+  %mul = mul i32 %loadB, %loadA
+
+  %add = add nuw nsw i64 %storemerge3, 1
+
+  %a_float = bitcast i32* %a to float*
+  %arrayidxA_plus_2 = getelementptr inbounds float* %a_float, i64 %add
+  %mul_float = sitofp i32 %mul to float
+  store float %mul_float, float* %arrayidxA_plus_2, align 2
+
+  %exitcond = icmp eq i64 %add, 20
+  br i1 %exitcond, label %for.end, label %for.body
+
+for.end:                                          ; preds = %for.body
+  ret void
+}