diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -170,19 +170,18 @@ AU.addRequiredTransitive(); } - // Used to test the dependence analyzer. -// Looks through the function, noting loads and stores. +// Looks through the function, noting instructions that may access memory. // Calls depends() on every possible pair and prints out the result. // Ignores all other instructions. static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA) { auto *F = DA->getFunction(); for (inst_iterator SrcI = inst_begin(F), SrcE = inst_end(F); SrcI != SrcE; ++SrcI) { - if (isa(*SrcI) || isa(*SrcI)) { + if (SrcI->mayReadOrWriteMemory()) { for (inst_iterator DstI = SrcI, DstE = inst_end(F); DstI != DstE; ++DstI) { - if (isa(*DstI) || isa(*DstI)) { + if (DstI->mayReadOrWriteMemory()) { OS << "da analyze - "; if (auto D = DA->depends(&*SrcI, &*DstI, true)) { D->dump(OS); @@ -196,6 +195,7 @@ } else OS << "none!\n"; + OS << " Src:" << *SrcI << " --> Dst:" << *DstI << "\n"; } } } @@ -3413,8 +3413,7 @@ if (Src == Dst) PossiblyLoopIndependent = false; - if ((!Src->mayReadFromMemory() && !Src->mayWriteToMemory()) || - (!Dst->mayReadFromMemory() && !Dst->mayWriteToMemory())) + if (!(Src->mayReadOrWriteMemory() && Dst->mayReadOrWriteMemory())) // if both instructions don't reference memory, there's no dependence return nullptr; @@ -3786,8 +3785,6 @@ return std::make_unique(std::move(Result)); } - - //===----------------------------------------------------------------------===// // getSplitIteration - // Rather than spend rarely-used space recording the splitting iteration diff --git a/llvm/test/Analysis/DependenceAnalysis/Dump.ll b/llvm/test/Analysis/DependenceAnalysis/Dump.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/DependenceAnalysis/Dump.ll @@ -0,0 +1,50 @@ +; RUN: opt < %s -disable-output "-passes=print" -aa-pipeline=basic-aa 2>&1 \ +; RUN: | FileCheck %s + +;; Test to make sure the dump shows the src and dst +;; instructions (including call instructions). +;; +;; void bar(float * restrict A); +;; void foo(float * restrict A, int n) { +;; for (int i = 0; i < n; i++) { +;; A[i] = i; +;; bar(A); +;; } +;; } + +; CHECK-LABEL: foo + +; CHECK:da analyze - none! +; CHECK-NEXT: Src: store float %conv, float* %arrayidx, align 4 --> Dst: store float %conv, float* %arrayidx, align 4 +; CHECK-NEXT:da analyze - confused! +; CHECK-NEXT: Src: store float %conv, float* %arrayidx, align 4 --> Dst: call void @bar(float* %A) +; CHECK-NEXT:da analyze - confused! +; CHECK-NEXT: Src: call void @bar(float* %A) --> Dst: call void @bar(float* %A) + +define void @foo(float* noalias %A, i32 signext %n) { +entry: + %cmp1 = icmp slt i32 0, %n + br i1 %cmp1, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ] + %conv = sitofp i32 %i.02 to float + %idxprom = zext i32 %i.02 to i64 + %arrayidx = getelementptr inbounds float, float* %A, i64 %idxprom + store float %conv, float* %arrayidx, align 4 + call void @bar(float* %A) #3 + %inc = add nuw nsw i32 %i.02, 1 + %cmp = icmp slt i32 %inc, %n + br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge + +for.cond.for.end_crit_edge: ; preds = %for.body + br label %for.end + +for.end: ; preds = %for.cond.for.end_crit_edge, %entry + ret void +} + +declare void @bar(float*)