summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2018-07-27 09:43:39 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2018-07-27 09:43:39 +0000
commit4d980515d2accf33ca684524fbbeb31f098be6c4 (patch)
treed6069b8f3ffb9f2f1f7e81ab5a13fed60d97526b /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
parenta4ba5f9951498bee2df9892ba78defdc8e5f0422 (diff)
downloadbcm5719-llvm-4d980515d2accf33ca684524fbbeb31f098be6c4.tar.gz
bcm5719-llvm-4d980515d2accf33ca684524fbbeb31f098be6c4.zip
[SimplifyIndVar] Canonicalize comparisons to unsigned while eliminating truncs
This is a follow-up for the patch rL335020. When we replace compares against trunc with compares against wide IV, we can also replace signed predicates with unsigned where it is legal. Reviewed By: reames Differential Revision: https://reviews.llvm.org/D48763 llvm-svn: 338115
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyIndVar.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 7b07c9a3c4a..e381fbc34ab 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -555,6 +555,24 @@ bool SimplifyIndvar::eliminateTrunc(TruncInst *TI) {
return false;
}
+ auto CanUseZExt = [&](ICmpInst *ICI) {
+ // Unsigned comparison can be widened as unsigned.
+ if (ICI->isUnsigned())
+ return true;
+ // Is it profitable to do zext?
+ if (!DoesZExtCollapse)
+ return false;
+ // For equality, we can safely zext both parts.
+ if (ICI->isEquality())
+ return true;
+ // Otherwise we can only use zext when comparing two non-negative or two
+ // negative values. But in practice, we will never pass DoesZExtCollapse
+ // check for a negative value, because zext(trunc(x)) is non-negative. So
+ // it only make sense to check for non-negativity here.
+ const SCEV *SCEVOP1 = SE->getSCEV(ICI->getOperand(0));
+ const SCEV *SCEVOP2 = SE->getSCEV(ICI->getOperand(1));
+ return SE->isKnownNonNegative(SCEVOP1) && SE->isKnownNonNegative(SCEVOP2);
+ };
// Replace all comparisons against trunc with comparisons against IV.
for (auto *ICI : ICmpUsers) {
auto *Op1 = ICI->getOperand(1);
@@ -565,17 +583,20 @@ bool SimplifyIndvar::eliminateTrunc(TruncInst *TI) {
// then prefer zext as a more canonical form.
// TODO: If we see a signed comparison which can be turned into unsigned,
// we can do it here for canonicalization purposes.
- if (ICI->isUnsigned() || (ICI->isEquality() && DoesZExtCollapse)) {
+ ICmpInst::Predicate Pred = ICI->getPredicate();
+ if (CanUseZExt(ICI)) {
assert(DoesZExtCollapse && "Unprofitable zext?");
Ext = new ZExtInst(Op1, IVTy, "zext", ICI);
+ Pred = ICmpInst::getUnsignedPredicate(Pred);
} else {
assert(DoesSExtCollapse && "Unprofitable sext?");
Ext = new SExtInst(Op1, IVTy, "sext", ICI);
+ assert(Pred == ICmpInst::getSignedPredicate(Pred) && "Must be signed!");
}
bool Changed;
L->makeLoopInvariant(Ext, Changed);
(void)Changed;
- ICmpInst *NewICI = new ICmpInst(ICI, ICI->getPredicate(), IV, Ext);
+ ICmpInst *NewICI = new ICmpInst(ICI, Pred, IV, Ext);
ICI->replaceAllUsesWith(NewICI);
DeadInsts.emplace_back(ICI);
}
OpenPOWER on IntegriCloud