[llvm] r318050 - [SCEV] Handling for ICmp occuring in the evolution chain.

Evgenii Stepanov via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 13 10:27:01 PST 2017


/code/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:4093:21:
error: variable 'IsPosBECond' is used uninitialized whenever 'if'
condition is false [-Werror,-Wsometimes-uninitialized]
    if (BasicBlock *Latch = L->getLoopLatch()) {
                    ^~~~~
/code/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:4103:53:
note: uninitialized use occurs here
    SCEVBackedgeConditionFolder Rewriter(L, BECond, IsPosBECond, SE);

On Mon, Nov 13, 2017 at 8:43 AM, Jatin Bhateja via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: jbhateja
> Date: Mon Nov 13 08:43:24 2017
> New Revision: 318050
>
> URL: http://llvm.org/viewvc/llvm-project?rev=318050&view=rev
> Log:
> [SCEV] Handling for ICmp occuring in the evolution chain.
>
> Summary:
>  If a compare instruction is same or inverse of the compare in the
>  branch of the loop latch, then return a constant evolution node.
>  This shall facilitate computations of loop exit counts in cases
>  where compare appears in the evolution chain of induction variables.
>
>  Will fix PR 34538
>
> Reviewers: sanjoy, hfinkel, junryoungju
>
> Reviewed By: sanjoy, junryoungju
>
> Subscribers: javed.absar, llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D38494
>
> Added:
>     llvm/trunk/test/Analysis/ScalarEvolution/pr34538.ll
> Modified:
>     llvm/trunk/lib/Analysis/ScalarEvolution.cpp
>     llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
>
> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=318050&r1=318049&r2=318050&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Nov 13 08:43:24 2017
> @@ -4080,6 +4080,85 @@ private:
>    bool Valid = true;
>  };
>
> +/// This class evaluates the compare condition by matching it against the
> +/// condition of loop latch. If there is a match we assume a true value
> +/// for the condition while building SCEV nodes.
> +class SCEVBackedgeConditionFolder
> +    : public SCEVRewriteVisitor<SCEVBackedgeConditionFolder> {
> +public:
> +  static const SCEV *rewrite(const SCEV *S, const Loop *L,
> +                             ScalarEvolution &SE) {
> +    bool IsPosBECond;
> +    Value *BECond = nullptr;
> +    if (BasicBlock *Latch = L->getLoopLatch()) {
> +      BranchInst *BI = dyn_cast<BranchInst>(Latch->getTerminator());
> +      if (BI && BI->isConditional() &&
> +          BI->getSuccessor(0) != BI->getSuccessor(1)) {
> +        BECond = BI->getCondition();
> +        IsPosBECond = BI->getSuccessor(0) == L->getHeader();
> +      } else {
> +        return S;
> +      }
> +    }
> +    SCEVBackedgeConditionFolder Rewriter(L, BECond, IsPosBECond, SE);
> +    return Rewriter.visit(S);
> +  }
> +
> +  const SCEV *visitUnknown(const SCEVUnknown *Expr) {
> +    const SCEV *Result = Expr;
> +    bool InvariantF = SE.isLoopInvariant(Expr, L);
> +
> +    if (!InvariantF) {
> +      Instruction *I = cast<Instruction>(Expr->getValue());
> +      switch (I->getOpcode()) {
> +      case Instruction::Select: {
> +        SelectInst *SI = cast<SelectInst>(I);
> +        Optional<const SCEV *> Res =
> +            compareWithBackedgeCondition(SI->getCondition());
> +        if (Res.hasValue()) {
> +          bool IsOne = cast<SCEVConstant>(Res.getValue())->getValue()->isOne();
> +          Result = SE.getSCEV(IsOne ? SI->getTrueValue() : SI->getFalseValue());
> +        }
> +        break;
> +      }
> +      default: {
> +        Optional<const SCEV *> Res = compareWithBackedgeCondition(I);
> +        if (Res.hasValue())
> +          Result = Res.getValue();
> +        break;
> +      }
> +      }
> +    }
> +    return Result;
> +  }
> +
> +private:
> +  explicit SCEVBackedgeConditionFolder(const Loop *L, Value *BECond,
> +                                       bool IsPosBECond, ScalarEvolution &SE)
> +      : SCEVRewriteVisitor(SE), L(L), BackedgeCond(BECond),
> +        IsPositiveBECond(IsPosBECond) {}
> +
> +  Optional<const SCEV *> compareWithBackedgeCondition(Value *IC);
> +
> +  const Loop *L;
> +  /// Loop back condition.
> +  Value *BackedgeCond = nullptr;
> +  /// Set to true if loop back is on positive branch condition.
> +  bool IsPositiveBECond;
> +};
> +
> +Optional<const SCEV *>
> +SCEVBackedgeConditionFolder::compareWithBackedgeCondition(Value *IC) {
> +
> +  // If value matches the backedge condition for loop latch,
> +  // then return a constant evolution node based on loopback
> +  // branch taken.
> +  if (BackedgeCond == IC)
> +    return IsPositiveBECond ? SE.getOne(Type::getInt1Ty(SE.getContext()))
> +                            : SE.getZero(Type::getInt1Ty(SE.getContext()));
> +  return None;
> +}
> +
>  class SCEVShiftRewriter : public SCEVRewriteVisitor<SCEVShiftRewriter> {
>  public:
>    SCEVShiftRewriter(const Loop *L, ScalarEvolution &SE)
> @@ -4753,7 +4832,8 @@ const SCEV *ScalarEvolution::createAddRe
>        SmallVector<const SCEV *, 8> Ops;
>        for (unsigned i = 0, e = Add->getNumOperands(); i != e; ++i)
>          if (i != FoundIndex)
> -          Ops.push_back(Add->getOperand(i));
> +          Ops.push_back(SCEVBackedgeConditionFolder::rewrite(Add->getOperand(i),
> +                                                             L, *this));
>        const SCEV *Accum = getAddExpr(Ops);
>
>        // This is not a valid addrec if the step amount is varying each
> @@ -4779,33 +4859,33 @@ const SCEV *ScalarEvolution::createAddRe
>            // indices form a positive value.
>            if (GEP->isInBounds() && GEP->getOperand(0) == PN) {
>              Flags = setFlags(Flags, SCEV::FlagNW);
> -
> +
>              const SCEV *Ptr = getSCEV(GEP->getPointerOperand());
>              if (isKnownPositive(getMinusSCEV(getSCEV(GEP), Ptr)))
>                Flags = setFlags(Flags, SCEV::FlagNUW);
>            }
> -
> +
>            // We cannot transfer nuw and nsw flags from subtraction
>            // operations -- sub nuw X, Y is not the same as add nuw X, -Y
>            // for instance.
>          }
> -
> +
>          const SCEV *StartVal = getSCEV(StartValueV);
>          const SCEV *PHISCEV = getAddRecExpr(StartVal, Accum, L, Flags);
> -
> +
>          // Okay, for the entire analysis of this edge we assumed the PHI
>          // to be symbolic.  We now need to go back and purge all of the
>          // entries for the scalars that use the symbolic expression.
>          forgetSymbolicName(PN, SymbolicName);
>          ValueExprMap[SCEVCallbackVH(PN, this)] = PHISCEV;
> -
> +
>          // We can add Flags to the post-inc expression only if we
>          // know that it is *undefined behavior* for BEValueV to
>          // overflow.
>          if (auto *BEInst = dyn_cast<Instruction>(BEValueV))
>            if (isLoopInvariant(Accum, L) && isAddRecNeverPoison(BEInst, L))
>              (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags);
> -
> +
>          return PHISCEV;
>        }
>      }
>
> Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=318050&r1=318049&r2=318050&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Nov 13 08:43:24 2017
> @@ -2970,7 +2970,7 @@ void LSRInstance::CollectChains() {
>        // consider leaf IV Users. This effectively rediscovers a portion of
>        // IVUsers analysis but in program order this time.
>        if (SE.isSCEVable(I.getType()) && !isa<SCEVUnknown>(SE.getSCEV(&I)))
> -        continue;
> +          continue;
>
>        // Remove this instruction from any NearUsers set it may be in.
>        for (unsigned ChainIdx = 0, NChains = IVChainVec.size();
>
> Added: llvm/trunk/test/Analysis/ScalarEvolution/pr34538.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/pr34538.ll?rev=318050&view=auto
> ==============================================================================
> --- llvm/trunk/test/Analysis/ScalarEvolution/pr34538.ll (added)
> +++ llvm/trunk/test/Analysis/ScalarEvolution/pr34538.ll Mon Nov 13 08:43:24 2017
> @@ -0,0 +1,39 @@
> +; RUN: opt -scalar-evolution -loop-deletion -simplifycfg -analyze < %s | FileCheck %s --check-prefix=CHECK-ANALYSIS-1
> +; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s --check-prefix=CHECK-ANALYSIS-2
> +
> +define i32 @pr34538() local_unnamed_addr #0 {
> +; CHECK-ANALYSIS-1: Loop %do.body: backedge-taken count is 10000
> +; CHECK-ANALYSIS-1: Loop %do.body: max backedge-taken count is 10000
> +; CHECK-ANALYSIS-1: Loop %do.body: Predicated backedge-taken count is 10000
> +entry:
> +  br label %do.body
> +
> +do.body:                                          ; preds = %do.body, %entry
> +  %start.0 = phi i32 [ 0, %entry ], [ %inc.start.0, %do.body ]
> +  %cmp = icmp slt i32 %start.0, 10000
> +  %inc = zext i1 %cmp to i32
> +  %inc.start.0 = add nsw i32 %start.0, %inc
> +  br i1 %cmp, label %do.body, label %do.end
> +
> +do.end:                                           ; preds = %do.body
> +  ret i32 0
> +}
> +
> +
> +define i32 @foo() {
> +entry:
> +  br label %do.body
> +
> +do.body:                                          ; preds = %do.body, %entry
> +  %start.0 = phi i32 [ 0, %entry ], [ %inc.start.0, %do.body ]
> +  %cmp = icmp slt i32 %start.0, 10000
> +  %select_ext = select i1 %cmp, i32 2 , i32 1
> +  %inc.start.0 = add nsw i32 %start.0, %select_ext
> +  br i1 %cmp, label %do.body, label %do.end
> +
> +do.end:                                           ; preds = %do.body
> +  ret i32 0
> +; CHECK-ANALYSIS-2: Loop %do.body: backedge-taken count is 5000
> +; CHECK-ANALYSIS-2: Loop %do.body: max backedge-taken count is 5000
> +; CHECK-ANALYSIS-2: Loop %do.body: Predicated backedge-taken count is 5000
> +}
>
>
> _______________________________________________
> 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