diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-09-20 01:52:18 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-09-20 01:52:18 +0000 |
commit | 428db150d16f671d9e99726a5068c6613496e799 (patch) | |
tree | cd4c35c60f328d6acd1a26f022a5da2ee1be6b34 /llvm/lib/Transforms/Scalar | |
parent | f49712a8536f35929f956262ebad5a7d83150719 (diff) | |
download | bcm5719-llvm-428db150d16f671d9e99726a5068c6613496e799.tar.gz bcm5719-llvm-428db150d16f671d9e99726a5068c6613496e799.zip |
[IndVars] Fix a bug in r248045.
Because -indvars widens induction variables through arithmetic,
`NeverNegative` cannot be a property of the `WidenIV` (a `WidenIV`
manages information for all transitive uses of an IV being widened,
including uses of `-1 * IV`). Instead it must live on `NarrowIVDefUse`
which manages information for a specific def-use edge in the transitive
use list of an induction variable.
This change also adds a test case that demonstrates the problem with
r248045.
llvm-svn: 248107
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
-rw-r--r-- | llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index c58c9978b82..72d95794949 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -832,10 +832,19 @@ struct NarrowIVDefUse { Instruction *NarrowUse; Instruction *WideDef; - NarrowIVDefUse(): NarrowDef(nullptr), NarrowUse(nullptr), WideDef(nullptr) {} + // True if the narrow def is never negative. Tracking this information lets + // us use a sign extension instead of a zero extension or vice versa, when + // profitable and legal. + bool NeverNegative; + + NarrowIVDefUse() + : NarrowDef(nullptr), NarrowUse(nullptr), WideDef(nullptr), + NeverNegative(false) {} - NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD): - NarrowDef(ND), NarrowUse(NU), WideDef(WD) {} + NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD, + bool NeverNegative) + : NarrowDef(ND), NarrowUse(NU), WideDef(WD), + NeverNegative(NeverNegative) {} }; /// WidenIV - The goal of this transform is to remove sign and zero extends @@ -849,11 +858,6 @@ class WidenIV { Type *WideType; bool IsSigned; - // True if the narrow induction variable is never negative. Tracking this - // information lets us use a sign extension instead of a zero extension or - // vice versa, when profitable and legal. - bool NeverNegative; - // Context LoopInfo *LI; Loop *L; @@ -876,7 +880,6 @@ public: OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType), IsSigned(WI.IsSigned), - NeverNegative(false), LI(LInfo), L(LI->getLoopFor(OrigPhi->getParent())), SE(SEv), @@ -1103,7 +1106,7 @@ bool WidenIV::WidenLoopCompare(NarrowIVDefUse DU) { // (A) == icmp slt i32 sext(%narrow), sext(%val) // == icmp slt i32 zext(%narrow), sext(%val) - if (!(NeverNegative || IsSigned == Cmp->isSigned())) + if (!(DU.NeverNegative || IsSigned == Cmp->isSigned())) return false; Value *Op = Cmp->getOperand(Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0); @@ -1240,6 +1243,10 @@ Instruction *WidenIV::WidenIVUse(NarrowIVDefUse DU, SCEVExpander &Rewriter) { /// pushNarrowIVUsers - Add eligible users of NarrowDef to NarrowIVUsers. /// void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) { + const SCEV *NarrowSCEV = SE->getSCEV(NarrowDef); + bool NeverNegative = + SE->isKnownPredicate(ICmpInst::ICMP_SGE, NarrowSCEV, + SE->getConstant(NarrowSCEV->getType(), 0)); for (User *U : NarrowDef->users()) { Instruction *NarrowUser = cast<Instruction>(U); @@ -1247,7 +1254,8 @@ void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) { if (!Widened.insert(NarrowUser).second) continue; - NarrowIVUsers.push_back(NarrowIVDefUse(NarrowDef, NarrowUser, WideDef)); + NarrowIVUsers.push_back( + NarrowIVDefUse(NarrowDef, NarrowUser, WideDef, NeverNegative)); } } @@ -1267,9 +1275,6 @@ PHINode *WidenIV::CreateWideIV(SCEVExpander &Rewriter) { if (!AddRec) return nullptr; - NeverNegative = SE->isKnownPredicate(ICmpInst::ICMP_SGE, AddRec, - SE->getConstant(AddRec->getType(), 0)); - // Widen the induction variable expression. const SCEV *WideIVExpr = IsSigned ? SE->getSignExtendExpr(AddRec, WideType) : |