[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