-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LAA] Add a test case to show incorrect dependency classification (NFC). #70473
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-analysis Author: Alexandros Lamprineas (labrinea) ChangesCurrently the loop access analysis classifies this loop as unsafe to vectorize because the memory dependencies are 'ForwardButPreventsForwarding'. However, the access pattern is 'write-after-read' with no subsequent read accessing the written memory locations. I can't see how store-to-load forwarding is applicable here. void vectorizable_Read_Write(int *A) { Full diff: https://github.com/llvm/llvm-project/pull/70473.diff 1 Files Affected:
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/forward-negative-step.ll b/llvm/test/Analysis/LoopAccessAnalysis/forward-negative-step.ll
new file mode 100644
index 000000000000000..89c1737fb730513
--- /dev/null
+++ b/llvm/test/Analysis/LoopAccessAnalysis/forward-negative-step.ll
@@ -0,0 +1,40 @@
+; RUN: opt -passes='print<access-info>' -disable-output < %s 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+
+; FIXME: This should be vectorizable
+
+; void vectorizable_Read_Write(int *A) {
+; for (unsigned i = 1022; i >= 0; i--)
+; A[i+1] = A[i] + 1;
+; }
+
+; CHECK: function 'vectorizable_Read_Write':
+; CHECK-NEXT: for.body:
+; CHECK-NEXT: Report: unsafe dependent memory operations in loop
+; CHECK-NEXT: Forward loop carried data dependence that prevents store-to-load forwarding.
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: ForwardButPreventsForwarding:
+; CHECK-NEXT: %0 = load i32, ptr %arrayidx, align 4 ->
+; CHECK-NEXT: store i32 %add, ptr %gep, align 4
+
+define void @vectorizable_Read_Write(ptr nocapture %A) {
+entry:
+ %invariant.gep = getelementptr i32, ptr %A, i64 1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 1022, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
+ %add = add nsw i32 %0, 1
+ %gep = getelementptr i32, ptr %invariant.gep, i64 %indvars.iv
+ store i32 %add, ptr %gep, align 4
+ %indvars.iv.next = add nsw i64 %indvars.iv, -1
+ %cmp.not = icmp eq i64 %indvars.iv, 0
+ br i1 %cmp.not, label %for.cond.cleanup, label %for.body
+}
+
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Currently the loop access analysis classifies this loop as unsafe to vectorize because the memory dependencies are 'ForwardButPreventsForwarding'. However, the access pattern is 'write-after-read' with no subsequent read accessing the written memory locations. I can't see how store-to-load forwarding is applicable here. void vectorizable_Read_Write(int *A) { for (unsigned i = 1022; i >= 0; i--) A[i+1] = A[i] + 1; }
As shown in llvm#70473, the following loop was not considered safe to vectorize. When determining the memory access dependencies in a loop which has negative iteration step, we invert the source and sink of the dependence. Perhaps we should just invert the operands to getMinusSCEV(). This way the dependency is not regarded to be true, since the users of the `IsWrite` variables, which correspond to each of the memory accesses, rely on program order and therefore should not be swapped. void vectorizable_Read_Write(int *A) { for (unsigned i = 1022; i >= 0; i--) A[i+1] = A[i] + 1; }
As shown in #70473, the following loop was not considered safe to vectorize. When determining the memory access dependencies in a loop which has negative iteration step, we invert the source and sink of the dependence. Perhaps we should just invert the operands to getMinusSCEV(). This way the dependency is not regarded to be true, since the users of the `IsWrite` variables, which correspond to each of the memory accesses, rely on program order and therefore should not be swapped. void vectorizable_Read_Write(int *A) { for (unsigned i = 1022; i >= 0; i--) A[i+1] = A[i] + 1; }
Currently the loop access analysis classifies this loop as unsafe to vectorize because the memory dependencies are 'ForwardButPreventsForwarding'. However, the access pattern is 'write-after-read' with no subsequent read accessing the written memory locations. I can't see how store-to-load forwarding is applicable here.
void vectorizable_Read_Write(int *A) {
for (unsigned i = 1022; i >= 0; i--)
A[i+1] = A[i] + 1;
}