[llvm] r335481 - [DA] Delinearise AddRecs if we can prove they don't wrap

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 27 11:08:50 PDT 2018


Looking at the patch, I think this can be rephrased in a much more 
generic manner.  Is there any reason we can't add an optimization to 
indvarsimplify to infer the nsw for the add and record it in the IR?  If 
we did so, we could revert this patch, keep the benefit, and possibly 
benefit elsewhere.

Philip

On 06/25/2018 08:13 AM, David Green via llvm-commits wrote:
> Author: dmgreen
> Date: Mon Jun 25 08:13:26 2018
> New Revision: 335481
>
> URL: http://llvm.org/viewvc/llvm-project?rev=335481&view=rev
> Log:
> [DA] Delinearise AddRecs if we can prove they don't wrap
>
> We can prove that some delinearized subscripts do not wrap around to become
> negative by the fact that they are from inbound geps of load/store locations.
> This helps improve the delinearisation in cases where we can't prove that they
> are non-negative from SCEV alone.
>
> Differential Revision: https://reviews.llvm.org/D48481
>
>
> Modified:
>      llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h
>      llvm/trunk/lib/Analysis/DependenceAnalysis.cpp
>      llvm/trunk/test/Analysis/DependenceAnalysis/DADelin.ll
>
> Modified: llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h?rev=335481&r1=335480&r2=335481&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h (original)
> +++ llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h Mon Jun 25 08:13:26 2018
> @@ -563,6 +563,11 @@ template <typename T> class ArrayRef;
>       /// bounds.
>       bool isKnownLessThan(const SCEV *S, const SCEV *Size) const;
>   
> +    /// isKnownNonNegative - Compare to see if S is known not to be negative
> +    /// Uses the fact that S comes from Ptr, which may be an inbound GEP,
> +    /// Proving there is no wrapping going on.
> +    bool isKnownNonNegative(const SCEV *S, const Value *Ptr) const;
> +
>       /// collectUpperBound - All subscripts are the same type (on my machine,
>       /// an i64). The loop bound may be a smaller type. collectUpperBound
>       /// find the bound, if available, and zero extends it to the Type T.
>
> Modified: llvm/trunk/lib/Analysis/DependenceAnalysis.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DependenceAnalysis.cpp?rev=335481&r1=335480&r2=335481&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/DependenceAnalysis.cpp (original)
> +++ llvm/trunk/lib/Analysis/DependenceAnalysis.cpp Mon Jun 25 08:13:26 2018
> @@ -1027,6 +1027,25 @@ bool DependenceInfo::isKnownLessThan(con
>     return SE->isKnownNegative(LimitedBound);
>   }
>   
> +bool DependenceInfo::isKnownNonNegative(const SCEV *S, const Value *Ptr) const {
> +  bool Inbounds = false;
> +  if (auto *SrcGEP = dyn_cast<GetElementPtrInst>(Ptr))
> +    Inbounds = SrcGEP->isInBounds();
> +  if (Inbounds) {
> +    if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
> +      if (AddRec->isAffine()) {
> +        // We know S is for Ptr, the operand on a load/store, so doesn't wrap.
> +        // If both parts are NonNegative, the end result will be NonNegative
> +        if (SE->isKnownNonNegative(AddRec->getStart()) &&
> +            SE->isKnownNonNegative(AddRec->getOperand(1)))
> +          return true;
> +      }
> +    }
> +  }
> +
> +  return SE->isKnownNonNegative(S);
> +}
> +
>   // All subscripts are all the same type.
>   // Loop bound may be smaller (e.g., a char).
>   // Should zero extend loop bound, since it's always >= 0.
> @@ -3292,13 +3311,13 @@ bool DependenceInfo::tryDelinearize(Inst
>     // FIXME: It may be better to record these sizes and add them as constraints
>     // to the dependency checks.
>     for (int i = 1; i < size; ++i) {
> -    if (!SE->isKnownNonNegative(SrcSubscripts[i]))
> +    if (!isKnownNonNegative(SrcSubscripts[i], SrcPtr))
>         return false;
>   
>       if (!isKnownLessThan(SrcSubscripts[i], Sizes[i - 1]))
>         return false;
>   
> -    if (!SE->isKnownNonNegative(DstSubscripts[i]))
> +    if (!isKnownNonNegative(DstSubscripts[i], DstPtr))
>         return false;
>   
>       if (!isKnownLessThan(DstSubscripts[i], Sizes[i - 1]))
>
> Modified: llvm/trunk/test/Analysis/DependenceAnalysis/DADelin.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/DependenceAnalysis/DADelin.ll?rev=335481&r1=335480&r2=335481&view=diff
> ==============================================================================
> --- llvm/trunk/test/Analysis/DependenceAnalysis/DADelin.ll (original)
> +++ llvm/trunk/test/Analysis/DependenceAnalysis/DADelin.ll Mon Jun 25 08:13:26 2018
> @@ -553,4 +553,38 @@ for.inc10:
>   
>   for.end12:                                        ; preds = %for.inc10, %entry
>     ret double undef
> -}
> \ No newline at end of file
> +}
> +
> +
> +; CHECK-LABEL: nonnegative
> +define void @nonnegative(i32* nocapture %A, i32 %N) {
> +; CHECK: da analyze - none!
> +; CHECK: da analyze - consistent output [0 0|<]!
> +; CHECK: da analyze - none!
> +entry:
> +  %cmp44 = icmp eq i32 %N, 0
> +  br i1 %cmp44, label %exit, label %for.outer
> +
> +for.outer:
> +  %h.045 = phi i32 [ %add19, %for.latch ], [ 0, %entry ]
> +  %mul = mul i32 %h.045, %N
> +  br label %for.inner
> +
> +for.inner:
> +  %i.043 = phi i32 [ 0, %for.outer ], [ %add16, %for.inner ]
> +  %add = add i32 %i.043, %mul
> +  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %add
> +  store i32 1, i32* %arrayidx, align 4
> +  store i32 2, i32* %arrayidx, align 4
> +  %add16 = add nuw i32 %i.043, 1
> +  %exitcond46 = icmp eq i32 %add16, %N
> +  br i1 %exitcond46, label %for.latch, label %for.inner
> +
> +for.latch:
> +  %add19 = add nuw i32 %h.045, 1
> +  %exitcond47 = icmp eq i32 %add19, %N
> +  br i1 %exitcond47, label %exit, label %for.outer
> +
> +exit:
> +  ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list