diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2021-08-30 12:00:26 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2021-08-30 12:06:58 +0300 |
commit | 7b0d59da9af4bf4eb8342cac579e42a818ac1ae7 (patch) | |
tree | 65772119c937f1a92963bb0ed6f74d93b2731519 /llvm/lib/Transforms/Utils/LoopUtils.cpp | |
parent | ada219b13a2debc94cb252feb0dd987ef9290126 (diff) | |
download | llvm-7b0d59da9af4bf4eb8342cac579e42a818ac1ae7.zip llvm-7b0d59da9af4bf4eb8342cac579e42a818ac1ae7.tar.gz llvm-7b0d59da9af4bf4eb8342cac579e42a818ac1ae7.tar.bz2 |
[IndVars] Drop check for the validity of rewrite
`isValidRewrite()` checks that the both the original SCEV,
and the rewrite SCEV have the same base pointer.
I //believe//, after all the recent SCEV improvements,
this invariant is already enforced by SCEV itself.
I originally tried changing it into an assert in D108043,
but that showed that it triggers on e.g. https://reviews.llvm.org/D108043#2946621,
where SCEV manages to forward the store to load,
test added.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D108655
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUtils.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUtils.cpp | 65 |
1 files changed, 0 insertions, 65 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index b82b95a..25d22f1 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -1110,58 +1110,6 @@ bool llvm::cannotBeMaxInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE, // As a side effect, reduces the amount of IV processing within the loop. //===----------------------------------------------------------------------===// -// Return true if the SCEV expansion generated by the rewriter can replace the -// original value. SCEV guarantees that it produces the same value, but the way -// it is produced may be illegal IR. Ideally, this function will only be -// called for verification. -static bool isValidRewrite(ScalarEvolution *SE, Value *FromVal, Value *ToVal) { - // If an SCEV expression subsumed multiple pointers, its expansion could - // reassociate the GEP changing the base pointer. This is illegal because the - // final address produced by a GEP chain must be inbounds relative to its - // underlying object. Otherwise basic alias analysis, among other things, - // could fail in a dangerous way. Ultimately, SCEV will be improved to avoid - // producing an expression involving multiple pointers. Until then, we must - // bail out here. - // - // Retrieve the pointer operand of the GEP. Don't use getUnderlyingObject - // because it understands lcssa phis while SCEV does not. - Value *FromPtr = FromVal; - Value *ToPtr = ToVal; - if (auto *GEP = dyn_cast<GEPOperator>(FromVal)) - FromPtr = GEP->getPointerOperand(); - - if (auto *GEP = dyn_cast<GEPOperator>(ToVal)) - ToPtr = GEP->getPointerOperand(); - - if (FromPtr != FromVal || ToPtr != ToVal) { - // Quickly check the common case - if (FromPtr == ToPtr) - return true; - - // SCEV may have rewritten an expression that produces the GEP's pointer - // operand. That's ok as long as the pointer operand has the same base - // pointer. Unlike getUnderlyingObject(), getPointerBase() will find the - // base of a recurrence. This handles the case in which SCEV expansion - // converts a pointer type recurrence into a nonrecurrent pointer base - // indexed by an integer recurrence. - - // If the GEP base pointer is a vector of pointers, abort. - if (!FromPtr->getType()->isPointerTy() || !ToPtr->getType()->isPointerTy()) - return false; - - const SCEV *FromBase = SE->getPointerBase(SE->getSCEV(FromPtr)); - const SCEV *ToBase = SE->getPointerBase(SE->getSCEV(ToPtr)); - if (FromBase == ToBase) - return true; - - LLVM_DEBUG(dbgs() << "rewriteLoopExitValues: GEP rewrite bail out " - << *FromBase << " != " << *ToBase << "\n"); - - return false; - } - return true; -} - static bool hasHardUserWithinLoop(const Loop *L, const Instruction *I) { SmallPtrSet<const Instruction *, 8> Visited; SmallVector<const Instruction *, 8> WorkList; @@ -1195,7 +1143,6 @@ struct RewritePhi { bool HighCost; // Is this expansion a high-cost? Value *Expansion = nullptr; - bool ValidRewrite = false; RewritePhi(PHINode *P, unsigned I, const SCEV *Val, Instruction *ExpansionPt, bool H) @@ -1233,8 +1180,6 @@ static bool canLoopBeDeleted(Loop *L, SmallVector<RewritePhi, 8> &RewritePhiSet) // phase later. Skip it in the loop invariant check below. bool found = false; for (const RewritePhi &Phi : RewritePhiSet) { - if (!Phi.ValidRewrite) - continue; unsigned i = Phi.Ith; if (Phi.PN == P && (Phi.PN)->getIncomingValue(i) == Incoming) { found = true; @@ -1378,13 +1323,6 @@ int llvm::rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI, << *(Phi.Expansion) << '\n' << " LoopVal = " << *(Phi.ExpansionPoint) << "\n"); - // FIXME: isValidRewrite() is a hack. it should be an assert, eventually. - Phi.ValidRewrite = isValidRewrite(SE, Phi.ExpansionPoint, Phi.Expansion); - if (!Phi.ValidRewrite) { - DeadInsts.push_back(Phi.Expansion); - continue; - } - #ifndef NDEBUG // If we reuse an instruction from a loop which is neither L nor one of // its containing loops, we end up breaking LCSSA form for this loop by @@ -1407,9 +1345,6 @@ int llvm::rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI, // Transformation. for (const RewritePhi &Phi : RewritePhiSet) { - if (!Phi.ValidRewrite) - continue; - PHINode *PN = Phi.PN; Value *ExitVal = Phi.Expansion; |