Alexandros Lamprineas 3ad6d1cbe5
[LAA] Fix incorrect dependency classification. (#70819)
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;
}
2023-12-05 15:27:30 +00:00

66 lines
2.1 KiB
LLVM

; REQUIRES: asserts
; RUN: opt -passes='print<access-info>' -debug-only=loop-accesses -disable-output < %s 2>&1 | FileCheck %s
; void negative_step(int *A) {
; for (int i = 1022; i >= 0; i--)
; A[i+1] = A[i] + 1;
; }
; CHECK: LAA: Found a loop in negative_step: loop
; CHECK: LAA: Checking memory dependencies
; CHECK-NEXT: LAA: Src Scev: {(4092 + %A),+,-4}<nw><%loop>Sink Scev: {(4088 + %A)<nuw>,+,-4}<nw><%loop>(Induction step: -1)
; CHECK-NEXT: LAA: Distance for store i32 %add, ptr %gep.A.plus.1, align 4 to %l = load i32, ptr %gep.A, align 4: -4
; CHECK-NEXT: LAA: Dependence is negative
define void @negative_step(ptr nocapture %A) {
entry:
%A.plus.1 = getelementptr i32, ptr %A, i64 1
br label %loop
loop:
%iv = phi i64 [ 1022, %entry ], [ %iv.next, %loop ]
%gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
%l = load i32, ptr %gep.A, align 4
%add = add nsw i32 %l, 1
%gep.A.plus.1 = getelementptr i32, ptr %A.plus.1, i64 %iv
store i32 %add, ptr %gep.A.plus.1, align 4
%iv.next = add nsw i64 %iv, -1
%cmp.not = icmp eq i64 %iv, 0
br i1 %cmp.not, label %exit, label %loop
exit:
ret void
}
; void positive_step(int *A) {
; for (int i = 1; i < 1024; i++)
; A[i-1] = A[i] + 1;
; }
; CHECK: LAA: Found a loop in positive_step: loop
; CHECK: LAA: Checking memory dependencies
; CHECK-NEXT: LAA: Src Scev: {(4 + %A)<nuw>,+,4}<nuw><%loop>Sink Scev: {%A,+,4}<nw><%loop>(Induction step: 1)
; CHECK-NEXT: LAA: Distance for %l = load i32, ptr %gep.A, align 4 to store i32 %add, ptr %gep.A.minus.1, align 4: -4
; CHECK-NEXT: LAA: Dependence is negative
define void @positive_step(ptr nocapture %A) {
entry:
%A.minus.1 = getelementptr i32, ptr %A, i64 -1
br label %loop
loop:
%iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
%gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
%l = load i32, ptr %gep.A, align 4
%add = add nsw i32 %l, 1
%gep.A.minus.1 = getelementptr i32, ptr %A.minus.1, i64 %iv
store i32 %add, ptr %gep.A.minus.1, align 4
%iv.next = add nsw i64 %iv, 1
%cmp.not = icmp eq i64 %iv, 1024
br i1 %cmp.not, label %exit, label %loop
exit:
ret void
}