Skip to content

[LAA] Add tests with non-power-of-2 store-load forward distance #136710

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

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes='print<access-info>' -disable-output -mtriple=riscv64 -mattr=+v < %s 2>&1 | FileCheck %s
; RUN: opt -passes='print<access-info>' -disable-output -mtriple=x86_64 < %s 2>&1 | FileCheck %s

; REQUIRES: riscv-registered-target, x86-registered-target

; Dependence distance between read and write is greater than the trip
; count of the loop. Thus, values written are never read for any
; valid vectorization of the loop.
define void @test(ptr %p) {
; CHECK-LABEL: 'test'
; CHECK-NEXT: loop:
; CHECK-NEXT: Memory dependences are safe
; CHECK-NEXT: Dependences:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT: SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT: Expressions re-written:
;
entry:
br label %loop

loop:
%iv = phi i64 [0, %entry], [%iv.next, %loop]
%a1 = getelementptr i64, ptr %p, i64 %iv
%v = load i64, ptr %a1, align 8
%offset = add i64 %iv, 200
%a2 = getelementptr i64, ptr %p, i64 %offset
store i64 %v, ptr %a2, align 8
%iv.next = add i64 %iv, 1
%cmp = icmp ne i64 %iv, 199
br i1 %cmp, label %loop, label %exit

exit:
ret void
}

; Dependence distance is less than trip count, thus we must prove that
; chosen VF guaranteed to be less than dependence distance.
define void @test_may_clobber1(ptr %p) {
; CHECK-LABEL: 'test_may_clobber1'
; CHECK-NEXT: loop:
; CHECK-NEXT: Memory dependences are safe with a maximum safe vector width of 6400 bits, with a maximum safe store-load forward width of 256 bits
; CHECK-NEXT: Dependences:
; CHECK-NEXT: BackwardVectorizable:
; CHECK-NEXT: %v = load i64, ptr %a1, align 32 ->
; CHECK-NEXT: store i64 %v, ptr %a2, align 32
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT: SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT: Expressions re-written:
;
entry:
br label %loop

loop:
%iv = phi i64 [0, %entry], [%iv.next, %loop]
%a1 = getelementptr i64, ptr %p, i64 %iv
%v = load i64, ptr %a1, align 32
%offset = add i64 %iv, 100
%a2 = getelementptr i64, ptr %p, i64 %offset
store i64 %v, ptr %a2, align 32
%iv.next = add i64 %iv, 1
%cmp = icmp ne i64 %iv, 199
br i1 %cmp, label %loop, label %exit

exit:
ret void
}

define void @test_may_clobber2(ptr %p) {
; CHECK-LABEL: 'test_may_clobber2'
; CHECK-NEXT: loop:
; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
; CHECK-NEXT: Backward loop carried data dependence that prevents store-to-load forwarding.
; CHECK-NEXT: Dependences:
; CHECK-NEXT: BackwardVectorizableButPreventsForwarding:
; CHECK-NEXT: %v = load i64, ptr %a1, align 32 ->
; CHECK-NEXT: store i64 %v, ptr %a2, align 32
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT: SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT: Expressions re-written:
;
entry:
br label %loop

loop:
%iv = phi i64 [0, %entry], [%iv.next, %loop]
%a1 = getelementptr i64, ptr %p, i64 %iv
%v = load i64, ptr %a1, align 32
%offset = add i64 %iv, 9
%a2 = getelementptr i64, ptr %p, i64 %offset
store i64 %v, ptr %a2, align 32
%iv.next = add i64 %iv, 1
%cmp = icmp ne i64 %iv, 199
br i1 %cmp, label %loop, label %exit

exit:
ret void
}

define void @test_may_clobber3(ptr %p) {
; CHECK-LABEL: 'test_may_clobber3'
; CHECK-NEXT: loop:
; CHECK-NEXT: Memory dependences are safe with a maximum safe vector width of 640 bits, with a maximum safe store-load forward width of 128 bits
; CHECK-NEXT: Dependences:
; CHECK-NEXT: BackwardVectorizable:
; CHECK-NEXT: %v = load i64, ptr %a1, align 32 ->
; CHECK-NEXT: store i64 %v, ptr %a2, align 32
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT: SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT: Expressions re-written:
;
entry:
br label %loop

loop:
%iv = phi i64 [0, %entry], [%iv.next, %loop]
%a1 = getelementptr i64, ptr %p, i64 %iv
%v = load i64, ptr %a1, align 32
%offset = add i64 %iv, 10
%a2 = getelementptr i64, ptr %p, i64 %offset
store i64 %v, ptr %a2, align 32
%iv.next = add i64 %iv, 1
%cmp = icmp ne i64 %iv, 199
br i1 %cmp, label %loop, label %exit

exit:
ret void
}

; Trivially no overlap due to minimum distance (8192) exceeding value of VLEN and LMUL.
define void @trivial_due_max_vscale(ptr %p) {
; CHECK-LABEL: 'trivial_due_max_vscale'
; CHECK-NEXT: loop:
; CHECK-NEXT: Memory dependences are safe
; CHECK-NEXT: Dependences:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT: SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT: Expressions re-written:
;
entry:
br label %loop

loop:
%iv = phi i64 [0, %entry], [%iv.next, %loop]
%a1 = getelementptr i64, ptr %p, i64 %iv
%v = load i64, ptr %a1, align 32
%offset = add i64 %iv, 8192
%a2 = getelementptr i64, ptr %p, i64 %offset
store i64 %v, ptr %a2, align 32
%iv.next = add i64 %iv, 1
%cmp = icmp ne i64 %iv, 199
br i1 %cmp, label %loop, label %exit

exit:
ret void
}

; Dependence distance could be violated via LMUL>=2 or interleaving.
define void @no_high_lmul_or_interleave(ptr %p) {
; CHECK-LABEL: 'no_high_lmul_or_interleave'
; CHECK-NEXT: loop:
; CHECK-NEXT: Memory dependences are safe with a maximum safe vector width of 65536 bits
; CHECK-NEXT: Dependences:
; CHECK-NEXT: BackwardVectorizable:
; CHECK-NEXT: %v = load i64, ptr %a1, align 32 ->
; CHECK-NEXT: store i64 %v, ptr %a2, align 32
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT: SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT: Expressions re-written:
;
entry:
br label %loop

loop:
%iv = phi i64 [0, %entry], [%iv.next, %loop]
%a1 = getelementptr i64, ptr %p, i64 %iv
%v = load i64, ptr %a1, align 32
%offset = add i64 %iv, 1024
%a2 = getelementptr i64, ptr %p, i64 %offset
store i64 %v, ptr %a2, align 32
%iv.next = add i64 %iv, 1
%cmp = icmp ne i64 %iv, 3001
br i1 %cmp, label %loop, label %exit

exit:
ret void
}

define void @non_power_2_storeloadforward(ptr %A) {
; CHECK-LABEL: 'non_power_2_storeloadforward'
; CHECK-NEXT: loop:
; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
; CHECK-NEXT: Backward loop carried data dependence that prevents store-to-load forwarding.
; CHECK-NEXT: Dependences:
; CHECK-NEXT: Forward:
; CHECK-NEXT: %3 = load i32, ptr %arrayidx2, align 4 ->
; CHECK-NEXT: store i32 %add3, ptr %arrayidx5, align 4
; CHECK-EMPTY:
; CHECK-NEXT: BackwardVectorizableButPreventsForwarding:
; CHECK-NEXT: %1 = load i32, ptr %arrayidx, align 4 ->
; CHECK-NEXT: store i32 %add3, ptr %arrayidx5, align 4
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT: SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT: Expressions re-written:
;
entry:
br label %loop

loop:
%iv = phi i64 [ 16, %entry ], [ %iv.next, %loop ]
%0 = add nsw i64 %iv, -3
%gep.iv.sub.3 = getelementptr inbounds i32, ptr %A, i64 %0
%1 = load i32, ptr %gep.iv.sub.3, align 4
%2 = add nsw i64 %iv, 4
%gep.iv.4 = getelementptr inbounds i32, ptr %A, i64 %2
%3 = load i32, ptr %gep.iv.4, align 4
%add3 = add nsw i32 %3, %1
%gep.iv = getelementptr inbounds i32, ptr %A, i64 %iv
store i32 %add3, ptr %gep.iv, align 4
%iv.next = add i64 %iv, 1
%iv.trunc = trunc i64 %iv.next to i32
%exitcond = icmp ne i32 %iv.trunc, 128
br i1 %exitcond, label %loop, label %exit

exit:
ret void
}
Loading