diff options
author | Max Kazantsev <mkazantsev@azul.com> | 2020-12-04 11:59:07 +0700 |
---|---|---|
committer | Max Kazantsev <mkazantsev@azul.com> | 2020-12-04 12:34:43 +0700 |
commit | 12b6c5e68282be7beac597300cf90a9d6ae3e1dd (patch) | |
tree | abb548d31b3fe4fdef4b0f203f4bb9efbd421777 /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | |
parent | 3df0daceb2c684c8bd704595e70c08500bb051ed (diff) | |
download | llvm-12b6c5e68282be7beac597300cf90a9d6ae3e1dd.zip llvm-12b6c5e68282be7beac597300cf90a9d6ae3e1dd.tar.gz llvm-12b6c5e68282be7beac597300cf90a9d6ae3e1dd.tar.bz2 |
Return "[IndVars] ICmpInst should not prevent IV widening"
This reverts commit 4bd35cdc3ae1874c6d070c5d410b3f591de54ee6.
The patch was reverted during the investigation. The investigation
shown that the patch did not cause any trouble, but just exposed
the existing problem that is addressed by the previous patch
"[IndVars] Quick fix LHS/RHS bug". Returning without changes.
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 8842dfe..c02264a 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 @@ -1658,6 +1675,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; } |