[llvm] r234361 - [LoopAccesses] Allow analysis to complete in the presence of uniform stores

Adam Nemet anemet at apple.com
Tue Apr 7 21:12:53 PDT 2015


> On Apr 7, 2015, at 8:56 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:
> 
> This seems to have caused PR23157, which breaks the build of Chromium on ToT.
> Please either revert or fix. Thanks!

Reverting.  Sorry about the breakage.  Ashutosh, let me know if you need help tracking this down.

Adam

> 
> 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