[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