https://github.com/kasuga-fj created https://github.com/llvm/llvm-project/pull/148241
None >From 3596b1726514dda5942d99d4779852e01367c764 Mon Sep 17 00:00:00 2001 From: Ryotaro Kasuga <kasuga.ryot...@fujitsu.com> Date: Fri, 11 Jul 2025 13:10:44 +0000 Subject: [PATCH] [DA] Add check for base pointer invariance --- llvm/lib/Analysis/DependenceAnalysis.cpp | 16 ++++++++++++++++ .../DependenceAnalysis/FlipFlopBaseAddress.ll | 18 +++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp index 428342f51ad2e..07bf560772c8c 100644 --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -3383,6 +3383,10 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst, SrcSubscripts, DstSubscripts)) return false; + assert(isLoopInvariant(SrcBase, SrcLoop) && + isLoopInvariant(DstBase, DstLoop) && + "Expected SrcBase and DstBase to be loop invariant"); + int Size = SrcSubscripts.size(); LLVM_DEBUG({ dbgs() << "\nSrcSubscripts: "; @@ -3666,6 +3670,18 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst, SCEVUnionPredicate(Assume, *SE)); } + // Even if the base pointers are the same, they may not be loop-invariant. It + // could lead to incorrect results, as we're analyzing loop-carried + // dependencies. + Loop *SrcLoop = LI->getLoopFor(Src->getParent()); + Loop *DstLoop = LI->getLoopFor(Dst->getParent()); + if (!isLoopInvariant(SrcBase, SrcLoop) || + !isLoopInvariant(DstBase, DstLoop)) { + LLVM_DEBUG(dbgs() << "The base pointer is not loop invariant.\n"); + return std::make_unique<Dependence>(Src, Dst, + SCEVUnionPredicate(Assume, *SE)); + } + uint64_t EltSize = SrcLoc.Size.toRaw(); const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase); const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase); diff --git a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll index 843c18a6e0d1e..a357018563be1 100644 --- a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll +++ b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll @@ -8,11 +8,11 @@ define float @bug41488_test1(float %f) { ; CHECK-LABEL: 'bug41488_test1' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT: da analyze - input [*]! +; CHECK-NEXT: da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float %f, ptr %q, align 4 ; CHECK-NEXT: da analyze - confused! ; CHECK-NEXT: Src: store float %f, ptr %q, align 4 --> Dst: store float %f, ptr %q, align 4 -; CHECK-NEXT: da analyze - output [*]! +; CHECK-NEXT: da analyze - confused! ; entry: %g = alloca float, align 4 @@ -34,11 +34,11 @@ for.cond.cleanup: define void @bug41488_test2(i32 %n) { ; CHECK-LABEL: 'bug41488_test2' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT: da analyze - input [*]! +; CHECK-NEXT: da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float 0.000000e+00, ptr %q, align 4 ; CHECK-NEXT: da analyze - confused! ; CHECK-NEXT: Src: store float 0.000000e+00, ptr %q, align 4 --> Dst: store float 0.000000e+00, ptr %q, align 4 -; CHECK-NEXT: da analyze - output [*]! +; CHECK-NEXT: da analyze - confused! ; entry: %g = alloca float, align 4 @@ -68,7 +68,7 @@ define void @bug53942_foo(i32 noundef %n, ptr noalias nocapture noundef writeonl ; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 ; CHECK-NEXT: da analyze - confused! ; CHECK-NEXT: Src: store double %.pre, ptr %arrayidx2, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 -; CHECK-NEXT: da analyze - output [*]! +; CHECK-NEXT: da analyze - confused! ; entry: %cmp8 = icmp sgt i32 %n, 1 @@ -99,11 +99,11 @@ for.body: ; preds = %for.body.preheader, define void @bug53942_bar(i32 noundef %n, ptr noalias noundef %A, ptr noalias noundef %B) { ; CHECK-LABEL: 'bug53942_bar' ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: %0 = load double, ptr %arrayidx, align 8 -; CHECK-NEXT: da analyze - input [*]! +; CHECK-NEXT: da analyze - confused! ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 ; CHECK-NEXT: da analyze - confused! ; CHECK-NEXT: Src: store double %0, ptr %arrayidx8, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 -; CHECK-NEXT: da analyze - output [*]! +; CHECK-NEXT: da analyze - confused! ; entry: br label %for.cond @@ -173,7 +173,7 @@ for.end: ; preds = %for.cond.cleanup define void @non_invariant_baseptr_with_identical_obj(ptr %A) { ; CHECK-LABEL: 'non_invariant_baseptr_with_identical_obj' ; CHECK-NEXT: Src: store i32 1, ptr %idx, align 4 --> Dst: store i32 1, ptr %idx, align 4 -; CHECK-NEXT: da analyze - none! +; CHECK-NEXT: da analyze - confused! ; entry: br label %loop.i.header @@ -222,7 +222,7 @@ exit: define void @non_invariant_baseptr_with_identical_underlying_obj2(ptr %A) { ; CHECK-LABEL: 'non_invariant_baseptr_with_identical_underlying_obj2' ; CHECK-NEXT: Src: store i32 1, ptr %idx, align 4 --> Dst: store i32 1, ptr %idx, align 4 -; CHECK-NEXT: da analyze - none! +; CHECK-NEXT: da analyze - confused! ; entry: br label %loop.i.header _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits