From: Nikita Popov Date: Sat, 29 Jun 2019 15:12:59 +0000 (+0000) Subject: [LFTR] Rephrase getLoopTest into "based-on" check; NFCI X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3f463ae38e7896dbb07b668aec6c84506dda3b92;p=llvm [LFTR] Rephrase getLoopTest into "based-on" check; NFCI What we want to know here is whether we're already using this value for the loop condition, so make the query about that. We can extend this to a more general "based-on" relationship, rather than a direct icmp use later. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364715 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 0f70384e904..4d301605a78 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -2027,11 +2027,17 @@ static PHINode *getLoopPhiForCounter(Value *IncV, Loop *L) { return nullptr; } -/// Return the ICmpInst controlling the given loop exit. There is no guarantee -/// that the exiting block is also the latch. -static ICmpInst *getLoopTest(BasicBlock *ExitingBB) { +/// Whether the current loop exit test is based on this value. Currently this +/// is limited to a direct use in the loop condition. +static bool isLoopExitTestBasedOn(Value *V, BasicBlock *ExitingBB) { BranchInst *BI = cast(ExitingBB->getTerminator()); - return dyn_cast(BI->getCondition()); + ICmpInst *ICmp = dyn_cast(BI->getCondition()); + // TODO: Allow non-icmp loop test. + if (!ICmp) + return false; + + // TODO: Allow indirect use. + return ICmp->getOperand(0) == V || ICmp->getOperand(1) == V; } /// linearFunctionTestReplace policy. Return true unless we can show that the @@ -2048,7 +2054,7 @@ static bool needsLFTR(Loop *L, BasicBlock *ExitingBB) { return false; // Do LFTR to simplify the exit condition to an ICMP. - ICmpInst *Cond = getLoopTest(ExitingBB); + ICmpInst *Cond = dyn_cast(BI->getCondition()); if (!Cond) return true; @@ -2250,10 +2256,10 @@ static PHINode *FindLoopCounter(Loop *L, BasicBlock *ExitingBB, // We explicitly allow unknown phis as long as they are already used by // the loop exit test. This is legal since performing LFTR could not // increase the number of undef users. - if (ICmpInst *Cond = getLoopTest(ExitingBB)) - if (Phi != getLoopPhiForCounter(Cond->getOperand(0), L) && - Phi != getLoopPhiForCounter(Cond->getOperand(1), L)) - continue; + Value *IncPhi = Phi->getIncomingValueForBlock(LatchBlock); + if (!isLoopExitTestBasedOn(Phi, ExitingBB) && + !isLoopExitTestBasedOn(IncPhi, ExitingBB)) + continue; } // Avoid introducing undefined behavior due to poison which didn't exist in @@ -2401,20 +2407,14 @@ linearFunctionTestReplace(Loop *L, BasicBlock *ExitingBB, // compare against the post-incremented value, otherwise we must compare // against the preincremented value. if (ExitingBB == L->getLoopLatch()) { - bool SafeToPostInc = IndVar->getType()->isIntegerTy(); - if (!SafeToPostInc) { - // For pointer IVs, we chose to not strip inbounds which requires us not - // to add a potentially UB introducing use. We need to either a) show - // the loop test we're modifying is already in post-inc form, or b) show - // that adding a use must not introduce UB. - if (ICmpInst *LoopTest = getLoopTest(ExitingBB)) - SafeToPostInc = LoopTest->getOperand(0) == IncVar || - LoopTest->getOperand(1) == IncVar; - if (!SafeToPostInc) - SafeToPostInc = - mustExecuteUBIfPoisonOnPathTo(IncVar, ExitingBB->getTerminator(), DT); - } - + // For pointer IVs, we chose to not strip inbounds which requires us not + // to add a potentially UB introducing use. We need to either a) show + // the loop test we're modifying is already in post-inc form, or b) show + // that adding a use must not introduce UB. + bool SafeToPostInc = + IndVar->getType()->isIntegerTy() || + isLoopExitTestBasedOn(IncVar, ExitingBB) || + mustExecuteUBIfPoisonOnPathTo(IncVar, ExitingBB->getTerminator(), DT); if (SafeToPostInc) { UsePostInc = true; CmpIndVar = IncVar;