summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2015-09-20 01:52:18 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2015-09-20 01:52:18 +0000
commit428db150d16f671d9e99726a5068c6613496e799 (patch)
treecd4c35c60f328d6acd1a26f022a5da2ee1be6b34 /llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
parentf49712a8536f35929f956262ebad5a7d83150719 (diff)
downloadbcm5719-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/IndVarSimplify.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/IndVarSimplify.cpp33
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) :
OpenPOWER on IntegriCloud