[llvm] r234361 - [LoopAccesses] Allow analysis to complete in the presence of uniform stores
Peter Collingbourne
peter at pcc.me.uk
Tue Apr 7 20:56:29 PDT 2015
This seems to have caused PR23157, which breaks the build of Chromium on ToT.
Please either revert or fix. Thanks!
Peter
On Tue, Apr 07, 2015 at 09:46:17PM -0000, Adam Nemet wrote:
> Author: anemet
> Date: Tue Apr 7 16:46:16 2015
> New Revision: 234361
>
> URL: http://llvm.org/viewvc/llvm-project?rev=234361&view=rev
> Log:
> [LoopAccesses] Allow analysis to complete in the presence of uniform stores
>
> Both run-time pointer checking and the dependence analysis are capable
> of dealing with uniform addresses. I.e. it's really just an orthogonal
> property of the loop that the analysis computes.
>
> Run-time pointer checking will only try to reason about SCEVAddRec
> pointers or else gives up. If the uniform pointer turns out the be a
> SCEVAddRec in an outer loop, the run-time checks generated will be
> correct (start and end bounds would be equal).
>
> In case of the dependence analysis, we work again with SCEVs. When
> compared against a loop-dependent address of the same underlying object,
> the difference of the two SCEVs won't be constant. This will result in
> returning an Unknown dependence for the pair.
>
> When compared against another uniform access, the difference would be
> constant and we should return the right type of dependence
> (forward/backward/etc).
>
> The changes also adds support to query this property of the loop and
> modify the vectorizer to use this.
>
> Patch by Ashutosh Nema!
>
> Added:
> llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll
> llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll
> Modified:
> llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h
> llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp
> llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
>
> Modified: llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h?rev=234361&r1=234360&r2=234361&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h (original)
> +++ llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h Tue Apr 7 16:46:16 2015
> @@ -432,6 +432,13 @@ public:
> /// Only used in DEBUG build but we don't want NDEBUG-dependent ABI.
> unsigned NumSymbolicStrides;
>
> + /// \brief Checks existence of store to invariant address inside loop.
> + /// If the loop has any store to invariant address, then it returns true,
> + /// else returns false.
> + bool hasStoreToLoopInvariantAddress() const {
> + return StoreToLoopInvariantAddress;
> + }
> +
> private:
> /// \brief Analyze the loop. Substitute symbolic strides using Strides.
> void analyzeLoop(const ValueToValueMap &Strides);
> @@ -469,6 +476,10 @@ private:
> /// \brief Cache the result of analyzeLoop.
> bool CanVecMem;
>
> + /// \brief Indicator for storing to uniform addresses.
> + /// If a loop has write to a loop invariant address then it should be true.
> + bool StoreToLoopInvariantAddress;
> +
> /// \brief The diagnostics report generated for the analysis. E.g. why we
> /// couldn't analyze the loop.
> Optional<LoopAccessReport> Report;
>
> Modified: llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp?rev=234361&r1=234360&r2=234361&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp (original)
> +++ llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp Tue Apr 7 16:46:16 2015
> @@ -1044,16 +1044,8 @@ void LoopAccessInfo::analyzeLoop(const V
> for (I = Stores.begin(), IE = Stores.end(); I != IE; ++I) {
> StoreInst *ST = cast<StoreInst>(*I);
> Value* Ptr = ST->getPointerOperand();
> -
> - if (isUniform(Ptr)) {
> - emitAnalysis(
> - LoopAccessReport(ST)
> - << "write to a loop invariant address could not be vectorized");
> - DEBUG(dbgs() << "LAA: We don't allow storing to uniform addresses\n");
> - CanVecMem = false;
> - return;
> - }
> -
> + // Check for store to loop invariant address.
> + StoreToLoopInvariantAddress = isUniform(Ptr);
> // If we did *not* see this pointer before, insert it to the read-write
> // list. At this phase it is only a 'write' list.
> if (Seen.insert(Ptr).second) {
> @@ -1314,7 +1306,8 @@ LoopAccessInfo::LoopAccessInfo(Loop *L,
> const ValueToValueMap &Strides)
> : DepChecker(SE, L), NumComparisons(0), TheLoop(L), SE(SE), DL(DL),
> TLI(TLI), AA(AA), DT(DT), NumLoads(0), NumStores(0),
> - MaxSafeDepDistBytes(-1U), CanVecMem(false) {
> + MaxSafeDepDistBytes(-1U), CanVecMem(false),
> + StoreToLoopInvariantAddress(false) {
> if (canAnalyzeLoop())
> analyzeLoop(Strides);
> }
> @@ -1327,6 +1320,10 @@ void LoopAccessInfo::print(raw_ostream &
> OS.indent(Depth) << "Memory dependences are safe with run-time checks\n";
> }
>
> + OS.indent(Depth) << "Store to invariant address was "
> + << (StoreToLoopInvariantAddress ? "" : "not ")
> + << "found in loop.\n";
> +
> if (Report)
> OS.indent(Depth) << "Report: " << Report->str() << "\n";
>
>
> Modified: llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp?rev=234361&r1=234360&r2=234361&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp (original)
> +++ llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp Tue Apr 7 16:46:16 2015
> @@ -4009,6 +4009,14 @@ bool LoopVectorizationLegality::canVecto
> if (!LAI->canVectorizeMemory())
> return false;
>
> + if (LAI->hasStoreToLoopInvariantAddress()) {
> + emitAnalysis(
> + VectorizationReport()
> + << "write to a loop invariant address could not be vectorized");
> + DEBUG(dbgs() << "LV: We don't allow storing to uniform addresses\n");
> + return false;
> + }
> +
> if (LAI->getNumRuntimePointerChecks() >
> VectorizerParams::RuntimeMemoryCheckThreshold) {
> emitAnalysis(VectorizationReport()
>
> Added: llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll?rev=234361&view=auto
> ==============================================================================
> --- llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll (added)
> +++ llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll Tue Apr 7 16:46:16 2015
> @@ -0,0 +1,53 @@
> +; RUN: opt < %s -loop-accesses -analyze | FileCheck %s
> +
> +; Test to confirm LAA will find store to invariant address.
> +; Inner loop has a store to invariant address.
> +;
> +; for(; i < itr; i++) {
> +; for(; j < itr; j++) {
> +; var1[i] = var2[j] + var1[i];
> +; }
> +; }
> +
> +; CHECK: Store to invariant address was found in loop.
> +; CHECK-NOT: Store to invariant address was not found in loop.
> +
> +define i32 @foo(i32* nocapture %var1, i32* nocapture readonly %var2, i32 %itr) #0 {
> +entry:
> + %cmp20 = icmp eq i32 %itr, 0
> + br i1 %cmp20, label %for.end10, label %for.cond1.preheader
> +
> +for.cond1.preheader: ; preds = %entry, %for.inc8
> + %indvars.iv23 = phi i64 [ %indvars.iv.next24, %for.inc8 ], [ 0, %entry ]
> + %j.022 = phi i32 [ %j.1.lcssa, %for.inc8 ], [ 0, %entry ]
> + %cmp218 = icmp ult i32 %j.022, %itr
> + br i1 %cmp218, label %for.body3.lr.ph, label %for.inc8
> +
> +for.body3.lr.ph: ; preds = %for.cond1.preheader
> + %arrayidx5 = getelementptr inbounds i32, i32* %var1, i64 %indvars.iv23
> + %0 = zext i32 %j.022 to i64
> + br label %for.body3
> +
> +for.body3: ; preds = %for.body3, %for.body3.lr.ph
> + %indvars.iv = phi i64 [ %0, %for.body3.lr.ph ], [ %indvars.iv.next, %for.body3 ]
> + %arrayidx = getelementptr inbounds i32, i32* %var2, i64 %indvars.iv
> + %1 = load i32, i32* %arrayidx, align 4
> + %2 = load i32, i32* %arrayidx5, align 4
> + %add = add nsw i32 %2, %1
> + store i32 %add, i32* %arrayidx5, align 4
> + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
> + %lftr.wideiv = trunc i64 %indvars.iv.next to i32
> + %exitcond = icmp eq i32 %lftr.wideiv, %itr
> + br i1 %exitcond, label %for.inc8, label %for.body3
> +
> +for.inc8: ; preds = %for.body3, %for.cond1.preheader
> + %j.1.lcssa = phi i32 [ %j.022, %for.cond1.preheader ], [ %itr, %for.body3 ]
> + %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
> + %lftr.wideiv25 = trunc i64 %indvars.iv.next24 to i32
> + %exitcond26 = icmp eq i32 %lftr.wideiv25, %itr
> + br i1 %exitcond26, label %for.end10, label %for.cond1.preheader
> +
> +for.end10: ; preds = %for.inc8, %entry
> + ret i32 undef
> +}
> +
>
> Added: llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll?rev=234361&view=auto
> ==============================================================================
> --- llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll (added)
> +++ llvm/trunk/test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll Tue Apr 7 16:46:16 2015
> @@ -0,0 +1,54 @@
> +; RUN: opt < %s -loop-accesses -analyze | FileCheck %s
> +
> +; Test to confirm LAA will not find store to invariant address.
> +; Inner loop has no store to invariant address.
> +;
> +; for(; i < itr; i++) {
> +; for(; j < itr; j++) {
> +; var2[j] = var2[j] + var1[i];
> +; }
> +; }
> +
> +; CHECK: Store to invariant address was not found in loop.
> +; CHECK-NOT: Store to invariant address was found in loop.
> +
> +
> +define i32 @foo(i32* nocapture readonly %var1, i32* nocapture %var2, i32 %itr) #0 {
> +entry:
> + %cmp20 = icmp eq i32 %itr, 0
> + br i1 %cmp20, label %for.end10, label %for.cond1.preheader
> +
> +for.cond1.preheader: ; preds = %entry, %for.inc8
> + %indvars.iv23 = phi i64 [ %indvars.iv.next24, %for.inc8 ], [ 0, %entry ]
> + %j.022 = phi i32 [ %j.1.lcssa, %for.inc8 ], [ 0, %entry ]
> + %cmp218 = icmp ult i32 %j.022, %itr
> + br i1 %cmp218, label %for.body3.lr.ph, label %for.inc8
> +
> +for.body3.lr.ph: ; preds = %for.cond1.preheader
> + %arrayidx5 = getelementptr inbounds i32, i32* %var1, i64 %indvars.iv23
> + %0 = zext i32 %j.022 to i64
> + br label %for.body3
> +
> +for.body3: ; preds = %for.body3, %for.body3.lr.ph
> + %indvars.iv = phi i64 [ %0, %for.body3.lr.ph ], [ %indvars.iv.next, %for.body3 ]
> + %arrayidx = getelementptr inbounds i32, i32* %var2, i64 %indvars.iv
> + %1 = load i32, i32* %arrayidx, align 4
> + %2 = load i32, i32* %arrayidx5, align 4
> + %add = add nsw i32 %2, %1
> + store i32 %add, i32* %arrayidx, align 4
> + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
> + %lftr.wideiv = trunc i64 %indvars.iv.next to i32
> + %exitcond = icmp eq i32 %lftr.wideiv, %itr
> + br i1 %exitcond, label %for.inc8, label %for.body3
> +
> +for.inc8: ; preds = %for.body3, %for.cond1.preheader
> + %j.1.lcssa = phi i32 [ %j.022, %for.cond1.preheader ], [ %itr, %for.body3 ]
> + %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
> + %lftr.wideiv25 = trunc i64 %indvars.iv.next24 to i32
> + %exitcond26 = icmp eq i32 %lftr.wideiv25, %itr
> + br i1 %exitcond26, label %for.end10, label %for.cond1.preheader
> +
> +for.end10: ; preds = %for.inc8, %entry
> + ret i32 undef
> +}
> +
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
--
Peter
More information about the llvm-commits
mailing list