diff options
author | Max Kazantsev <mkazantsev@azul.com> | 2020-11-30 10:51:31 +0700 |
---|---|---|
committer | Max Kazantsev <mkazantsev@azul.com> | 2020-11-30 10:51:31 +0700 |
commit | 0c9c6ddf17bb01ae350a899b3395bb078aa0c62e (patch) | |
tree | 35692d1753af3672d987cf0d3d9c0ca2842e10f1 /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | |
parent | 1db60c1307ac2e24796047c39d09bf400c22e531 (diff) | |
download | llvm-0c9c6ddf17bb01ae350a899b3395bb078aa0c62e.zip llvm-0c9c6ddf17bb01ae350a899b3395bb078aa0c62e.tar.gz llvm-0c9c6ddf17bb01ae350a899b3395bb078aa0c62e.tar.bz2 |
[IndVars] ICmpInst should not prevent IV widening
If we decided to widen IV with zext, then unsigned comparisons
should not prevent widening (same for sext/sign comparisons).
The result of comparison in wider type does not change in this case.
Differential Revision: https://reviews.llvm.org/D92207
Reviewed By: nikic
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp index d37fe74..e281c66 100644 --- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -1541,10 +1541,14 @@ bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) { bool CanZeroExtend = ExtKind == ZeroExtended && OBO->hasNoUnsignedWrap(); auto AnotherOpExtKind = ExtKind; - // Check that all uses are either s/zext, or narrow def (in case of we are - // widening the IV increment), or single-input LCSSA Phis. + // Check that all uses are either: + // - narrow def (in case of we are widening the IV increment); + // - single-input LCSSA Phis; + // - comparison of the chosen type; + // - extend of the chosen type (raison d'etre). SmallVector<Instruction *, 4> ExtUsers; SmallVector<PHINode *, 4> LCSSAPhiUsers; + SmallVector<ICmpInst *, 4> ICmpUsers; for (Use &U : NarrowUse->uses()) { Instruction *User = cast<Instruction>(U.getUser()); if (User == NarrowDef) @@ -1558,6 +1562,19 @@ bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) { LCSSAPhiUsers.push_back(LCSSAPhi); continue; } + if (auto *ICmp = dyn_cast<ICmpInst>(User)) { + auto Pred = ICmp->getPredicate(); + // We have 3 types of predicates: signed, unsigned and equality + // predicates. For equality, it's legal to widen icmp for either sign and + // zero extend. For sign extend, we can also do so for signed predicates, + // likeweise for zero extend we can widen icmp for unsigned predicates. + if (ExtKind == ZeroExtended && ICmpInst::isSigned(Pred)) + return false; + if (ExtKind == SignExtended && ICmpInst::isUnsigned(Pred)) + return false; + ICmpUsers.push_back(ICmp); + continue; + } if (ExtKind == SignExtended) User = dyn_cast<SExtInst>(User); else @@ -1655,6 +1672,26 @@ bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) { User->replaceAllUsesWith(TruncPN); DeadInsts.emplace_back(User); } + + for (ICmpInst *User : ICmpUsers) { + Builder.SetInsertPoint(User); + auto ExtendedOp = [&](Value * V)->Value * { + if (V == NarrowUse) + return WideBO; + if (ExtKind == ZeroExtended) + return Builder.CreateZExt(V, WideBO->getType()); + else + return Builder.CreateSExt(V, WideBO->getType()); + }; + auto Pred = User->getPredicate(); + auto *LHS = ExtendedOp(User->getOperand(0)); + auto *RHS = ExtendedOp(User->getOperand(1)); + auto *WideCmp = + Builder.CreateICmp(Pred, LHS, RHS, User->getName() + ".wide"); + User->replaceAllUsesWith(WideCmp); + DeadInsts.emplace_back(User); + } + return true; } |