From eeb73a9e6ebd0a88874d0508406b8e24307f6d83 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Thu, 25 Sep 2025 12:47:30 +0100 Subject: [PATCH 1/2] [LAA] Pre-commit test for possibly-zero-dist-diff-typesz --- .../LoopAccessAnalysis/depend_diff_types.ll | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll b/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll index 023a8c056968f..840fe915e0570 100644 --- a/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll @@ -187,6 +187,52 @@ 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 with run-time checks +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Check 0: +; CHECK-NEXT: Comparing group GRP0: +; CHECK-NEXT: %gep.p.iv.i16 = getelementptr inbounds nuw i16, ptr %p, i16 %iv +; CHECK-NEXT: Against group GRP1: +; CHECK-NEXT: %gep.p.iv.i32 = getelementptr inbounds nuw i32, ptr %p, i16 %iv +; CHECK-NEXT: Grouped accesses: +; CHECK-NEXT: Group GRP0: +; CHECK-NEXT: (Low: %p High: (64 + %p)) +; CHECK-NEXT: Member: {%p,+,2}<%loop> +; CHECK-NEXT: Group GRP1: +; CHECK-NEXT: (Low: %p High: (128 + %p)) +; CHECK-NEXT: Member: {%p,+,4}<%loop> +; 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) { From 55811d76c7fb7c5a78de547852d305b8c1fd3939 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Thu, 25 Sep 2025 12:50:14 +0100 Subject: [PATCH 2/2] [LAA] Fix non-NFC parts of 1aded51 1aded51 ([LAA] Prepare to handle diff type sizes (NFC)) was supposed to be a non-functional patch, but introduced functional changes as known-non-negative and known-non-positive is not equivalent to !known-non-zero. Fix this. --- llvm/lib/Analysis/LoopAccessAnalysis.cpp | 3 ++- .../LoopAccessAnalysis/depend_diff_types.ll | 17 +++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) 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 840fe915e0570..c367b31f6d445 100644 --- a/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll @@ -194,21 +194,14 @@ exit: 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 with run-time checks +; 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: Check 0: -; CHECK-NEXT: Comparing group GRP0: -; CHECK-NEXT: %gep.p.iv.i16 = getelementptr inbounds nuw i16, ptr %p, i16 %iv -; CHECK-NEXT: Against group GRP1: -; CHECK-NEXT: %gep.p.iv.i32 = getelementptr inbounds nuw i32, ptr %p, i16 %iv ; CHECK-NEXT: Grouped accesses: -; CHECK-NEXT: Group GRP0: -; CHECK-NEXT: (Low: %p High: (64 + %p)) -; CHECK-NEXT: Member: {%p,+,2}<%loop> -; CHECK-NEXT: Group GRP1: -; CHECK-NEXT: (Low: %p High: (128 + %p)) -; CHECK-NEXT: Member: {%p,+,4}<%loop> ; CHECK-EMPTY: ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. ; CHECK-NEXT: SCEV assumptions: