diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp index d6ad855cad9a7..512ae415d1c3b 100644 --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -2122,7 +2122,8 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize( // dependence. TypeSize AStoreSz = DL.getTypeStoreSize(ATy); TypeSize BStoreSz = DL.getTypeStoreSize(BTy); - if (AStoreSz != BStoreSz && !SE.isKnownNonZero(Dist)) { + if (AStoreSz != BStoreSz && SE.isKnownNonPositive(Dist) && + SE.isKnownNonNegative(Dist)) { LLVM_DEBUG(dbgs() << "LAA: possibly zero dependence distance with " "different type sizes\n"); return Dependence::Unknown; diff --git a/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll b/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll index 023a8c056968f..c367b31f6d445 100644 --- a/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll @@ -187,6 +187,45 @@ exit: ret void } +; In the following test, dependence distance is possibly zero, +; but this is not equivalent to the condition known-non-positive +; and known-non-negative. + +define void @possibly_zero_dist_diff_typesz(ptr %p) { +; CHECK-LABEL: 'possibly_zero_dist_diff_typesz' +; CHECK-NEXT: loop: +; CHECK-NEXT: Memory dependences are safe +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Forward: +; CHECK-NEXT: %ld.p = load i32, ptr %gep.p.iv.i32, align 1 -> +; CHECK-NEXT: store i16 %trunc, ptr %gep.p.iv.i16, align 1 +; 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 i16 [ 0, %entry ], [ %iv.next, %loop ] + %gep.p.iv.i32 = getelementptr inbounds nuw i32, ptr %p, i16 %iv + %ld.p = load i32, ptr %gep.p.iv.i32, align 1 + %trunc = trunc i32 %ld.p to i16 + %gep.p.iv.i16 = getelementptr inbounds nuw i16, ptr %p, i16 %iv + store i16 %trunc, ptr %gep.p.iv.i16, align 1 + %iv.next = add nuw nsw i16 %iv, 1 + %exit.cond = icmp eq i16 %iv.next, 32 + br i1 %exit.cond, label %exit, label %loop + +exit: + ret void +} + ; In the following test, the sink is loop-invariant. define void @type_size_equivalence_sink_loopinv(ptr nocapture %vec, i64 %n) {