diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2016-01-17 18:12:52 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2016-01-17 18:12:52 +0000 |
commit | de47590589f8418b942a0ca4576f6ed40ec61c36 (patch) | |
tree | f3700e4e6e0f7bbf3dbab6b95f6fc487a5c9e719 /llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | |
parent | 7a8a705c9d4542c5692667adb7de34d617a52378 (diff) | |
download | llvm-de47590589f8418b942a0ca4576f6ed40ec61c36.zip llvm-de47590589f8418b942a0ca4576f6ed40ec61c36.tar.gz llvm-de47590589f8418b942a0ca4576f6ed40ec61c36.tar.bz2 |
[IndVars] Fix PR25576
`LCSSASafePhiForRAUW` as computed was incorrect -- in cases like
these (this exact example does not actually trigger the bug):
define i32 @f(i32 %n, i1* %c) {
entry:
br label %outer.loop
outer.loop:
br label %inner.loop
inner.loop:
%iv = phi i32 [ 0, %outer.loop ], [ %iv.inc, %inner.loop ]
%iv.inc = add nuw nsw i32 %iv, 1
%tc = udiv i32 %n, 13
%be.cond = icmp ult i32 %iv, %tc
br i1 %be.cond, label %inner.loop, label %inner.exit
inner.exit:
%iv.lcssa = phi i32 [ %iv, %inner.loop ]
%outer.be.cond = load volatile i1, i1* %c
br i1 %outer.be.cond, label %outer.loop, label %leave
leave:
%iv.lcssa.lcssa = phi i32 [ %iv.lcssa, %inner.exit ]
ret i32 %iv.lcssa.lcssa
}
`LCSSASafePhiForRAUW` is true for `%iv.lcssa` when re-rewriting the exit
value of `%iv` for `%inner.loop` to `%tc` (this can happen due to
`SCEVExpander::findExistingExpansion`), but the RAUW breaks LCSSA.
To fix this, instead of computing `SafePhi` with special logic, decide
the safety of RAUW directly via `replacementPreservesLCSSAForm`.
llvm-svn: 258016
Diffstat (limited to 'llvm/lib/Transforms/Scalar/IndVarSimplify.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 29 |
1 files changed, 6 insertions, 23 deletions
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index 4f02708..0a41e71 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -504,10 +504,9 @@ struct RewritePhi { unsigned Ith; // Ith incoming value. Value *Val; // Exit value after expansion. bool HighCost; // High Cost when expansion. - bool SafePhi; // LCSSASafePhiForRAUW. - RewritePhi(PHINode *P, unsigned I, Value *V, bool H, bool S) - : PN(P), Ith(I), Val(V), HighCost(H), SafePhi(S) {} + RewritePhi(PHINode *P, unsigned I, Value *V, bool H) + : PN(P), Ith(I), Val(V), HighCost(H) {} }; } @@ -560,21 +559,6 @@ void IndVarSimplify::rewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) { unsigned NumPreds = PN->getNumIncomingValues(); - // We would like to be able to RAUW single-incoming value PHI nodes. We - // have to be certain this is safe even when this is an LCSSA PHI node. - // While the computed exit value is no longer varying in *this* loop, the - // exit block may be an exit block for an outer containing loop as well, - // the exit value may be varying in the outer loop, and thus it may still - // require an LCSSA PHI node. The safe case is when this is - // single-predecessor PHI node (LCSSA) and the exit block containing it is - // part of the enclosing loop, or this is the outer most loop of the nest. - // In either case the exit value could (at most) be varying in the same - // loop body as the phi node itself. Thus if it is in turn used outside of - // an enclosing loop it will only be via a separate LCSSA node. - bool LCSSASafePhiForRAUW = - NumPreds == 1 && - (!L->getParentLoop() || L->getParentLoop() == LI->getLoopFor(ExitBB)); - // Iterate over all of the PHI nodes. BasicBlock::iterator BBI = ExitBB->begin(); while ((PN = dyn_cast<PHINode>(BBI++))) { @@ -669,8 +653,7 @@ void IndVarSimplify::rewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) { } // Collect all the candidate PHINodes to be rewritten. - RewritePhiSet.emplace_back(PN, i, ExitVal, HighCost, - LCSSASafePhiForRAUW); + RewritePhiSet.emplace_back(PN, i, ExitVal, HighCost); } } } @@ -699,9 +682,9 @@ void IndVarSimplify::rewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) { if (isInstructionTriviallyDead(Inst, TLI)) DeadInsts.push_back(Inst); - // If we determined that this PHI is safe to replace even if an LCSSA - // PHI, do so. - if (Phi.SafePhi) { + // Replace PN with ExitVal if that is legal and does not break LCSSA. + if (PN->getNumIncomingValues() == 1 && + LI->replacementPreservesLCSSAForm(PN, ExitVal)) { PN->replaceAllUsesWith(ExitVal); PN->eraseFromParent(); } |