Skip to content
Open
Show file tree
Hide file tree
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
20 changes: 11 additions & 9 deletions llvm/lib/Analysis/LoopAccessAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1949,17 +1949,20 @@ static bool isSafeDependenceDistance(const DataLayout &DL, ScalarEvolution &SE,

/// Check the dependence for two accesses with the same stride \p Stride.
/// \p Distance is the positive distance in bytes, and \p TypeByteSize is type
/// size in bytes.
/// size of the source and sink in bytes.
///
/// \returns true if they are independent.
static bool areStridedAccessesIndependent(uint64_t Distance, uint64_t Stride,
uint64_t TypeByteSize) {
static bool
areStridedAccessesIndependent(uint64_t Distance, uint64_t Stride,
std::pair<uint64_t, uint64_t> TypeByteSize) {
assert(Stride > 1 && "The stride must be greater than 1");
assert(TypeByteSize > 0 && "The type size in byte must be non-zero");
assert(TypeByteSize.first > 0 && TypeByteSize.second > 0 &&
"The type size in byte must be non-zero");
assert(Distance > 0 && "The distance must be non-zero");

// Skip if the distance is not multiple of type byte size.
if (Distance % TypeByteSize)
// Skip if the distance is not multiple of type byte size of either the source
// or the sink.
if (Distance % TypeByteSize.first || Distance % TypeByteSize.second)
return false;

// No dependence if the distance is not multiple of the stride.
Expand Down Expand Up @@ -2191,9 +2194,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
if (APDist) {
// If the distance between accesses and their strides are known constants,
// check whether the accesses interlace each other.
if (ConstDist > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
areStridedAccessesIndependent(ConstDist, *CommonStride,
TypeByteSize.first)) {
if (ConstDist > 0 && CommonStride && CommonStride > 1 &&
areStridedAccessesIndependent(ConstDist, *CommonStride, TypeByteSize)) {
LLVM_DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
return Dependence::NoDep;
}
Expand Down
11 changes: 1 addition & 10 deletions llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll
Original file line number Diff line number Diff line change
Expand Up @@ -273,20 +273,11 @@ exit:
; ^ ~~~~~~~~~~~~~~~~ ^ iv.next = iv + 8
;
; Measurements are in bytes.
;
; TODO: Relax the HasSameSize check; the strided accesses are
; independent, as determined by both the source size and the sink size.
; This test should report no dependencies.
define void @different_type_sizes_strided_accesses_independent(ptr %dst) {
; CHECK-LABEL: 'different_type_sizes_strided_accesses_independent'
; 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: Unknown data dependence.
; CHECK-NEXT: Memory dependences are safe
; CHECK-NEXT: Dependences:
; CHECK-NEXT: Unknown:
; CHECK-NEXT: store i16 0, ptr %gep.iv, align 2 ->
; CHECK-NEXT: store i32 1, ptr %gep.4.iv, align 4
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
Expand Down
4 changes: 0 additions & 4 deletions llvm/test/Analysis/LoopAccessAnalysis/forward-loop-carried.ll
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,6 @@ define void @forward_different_access_sizes(ptr readnone %end, ptr %start) {
; CHECK-NEXT: store i32 0, ptr %gep.2, align 4 ->
; CHECK-NEXT: %l = load i24, ptr %gep.1, align 1
; CHECK-EMPTY:
; CHECK-NEXT: Forward:
; CHECK-NEXT: store i32 0, ptr %gep.2, align 4 ->
; CHECK-NEXT: store i24 %l, ptr %ptr.iv, align 1
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ define void @pr58722_load_interleave_group(ptr %src, ptr %dst) {
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP1]]
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP2]]
; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP3]]
; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <8 x i32>, ptr [[TMP4]], align 4
; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <8 x i32>, ptr [[TMP4]], align 4, !alias.scope [[META0:![0-9]+]]
; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <8 x i32> [[WIDE_VEC]], <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i64 1
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i64 1
; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i64 1
; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i64 1
; CHECK-NEXT: [[TMP13:%.*]] = load i24, ptr [[TMP9]], align 4, !alias.scope [[META0:![0-9]+]]
; CHECK-NEXT: [[TMP13:%.*]] = load i24, ptr [[TMP9]], align 4, !alias.scope [[META0]]
; CHECK-NEXT: [[TMP14:%.*]] = load i24, ptr [[TMP10]], align 4, !alias.scope [[META0]]
; CHECK-NEXT: [[TMP15:%.*]] = load i24, ptr [[TMP11]], align 4, !alias.scope [[META0]]
; CHECK-NEXT: [[TMP16:%.*]] = load i24, ptr [[TMP12]], align 4, !alias.scope [[META0]]
Expand Down Expand Up @@ -95,17 +95,41 @@ exit:
define void @pr58722_store_interleave_group(ptr %src, ptr %dst) {
; CHECK-LABEL: @pr58722_store_interleave_group(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[ENTRY:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i32 [[IV]]
; CHECK-NEXT: store i32 [[IV]], ptr [[GEP_IV]], align 4
; CHECK: vector.body:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i32 [[IV]], 2
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[OFFSET_IDX]], 2
; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i32 [[OFFSET_IDX]]
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i32 [[TMP0]]
; CHECK-NEXT: store i32 [[OFFSET_IDX]], ptr [[GEP_IV]], align 4
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TMP2]], align 4
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i64, ptr [[GEP_IV]], i64 1
; CHECK-NEXT: [[TRUNC_IV:%.*]] = trunc i32 [[IV]] to i24
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i64 1
; CHECK-NEXT: [[TRUNC_IV:%.*]] = trunc i32 [[OFFSET_IDX]] to i24
; CHECK-NEXT: [[TMP6:%.*]] = trunc i32 [[TMP0]] to i24
; CHECK-NEXT: store i24 [[TRUNC_IV]], ptr [[GEP]], align 4
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 2
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[IV]], 10000
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK-NEXT: store i24 [[TMP6]], ptr [[TMP4]], align 4
; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 2
; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[IV_NEXT]], 5000
; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[LOOP]], !llvm.loop [[LOOP9:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: br label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 10000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY1:%.*]] ]
; CHECK-NEXT: br label [[LOOP1:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV1:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT1:%.*]], [[LOOP1]] ]
; CHECK-NEXT: [[GEP_IV1:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i32 [[IV1]]
; CHECK-NEXT: store i32 [[IV1]], ptr [[GEP_IV1]], align 4
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i64, ptr [[GEP_IV1]], i64 1
; CHECK-NEXT: [[TRUNC_IV1:%.*]] = trunc i32 [[IV1]] to i24
; CHECK-NEXT: store i24 [[TRUNC_IV1]], ptr [[GEP1]], align 4
; CHECK-NEXT: [[IV_NEXT1]] = add i32 [[IV1]], 2
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[IV1]], 10000
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP1]], !llvm.loop [[LOOP10:![0-9]+]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand Down