[PATCH] D146638: [LFTR] Simplify integer case for genLoopLimit [nfc-ish]
Philip Reames via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 22 09:16:27 PDT 2023
reames created this revision.
reames added reviewers: nikic, efriedma, fhahn.
Herald added subscribers: StephenFan, bollu, hiraditya, mcrosier.
Herald added a project: All.
reames requested review of this revision.
Herald added a project: LLVM.
The integer case in genLoopLimit reduces down to a special case for narrowing the bitwidth of the limit, and then performing the same expansion we would for a pointer IV.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D146638
Files:
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -910,60 +910,27 @@
assert(isLoopCounter(IndVar, L, SE));
assert(ExitCount->getType()->isIntegerTy() && "exit count must be integer");
const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(SE->getSCEV(IndVar));
- const SCEV *IVInit = AR->getStart();
assert(AR->getStepRecurrence(*SE)->isOne() && "only handles unit stride");
- // IVInit may be a pointer while ExitCount is an integer when FindLoopCounter
- // finds a valid pointer IV.
- if (IndVar->getType()->isPointerTy()) {
- const SCEVAddRecExpr *ARBase = UsePostInc ? AR->getPostIncExpr(*SE) : AR;
- const SCEV *IVLimit = ARBase->evaluateAtIteration(ExitCount, *SE);
- assert(SE->isLoopInvariant(IVLimit, L) &&
- "Computed iteration count is not loop invariant!");
- return Rewriter.expandCodeFor(IVLimit, IndVar->getType(),
- ExitingBB->getTerminator());
- } else {
- // In any other case, convert both IVInit and ExitCount to integers before
- // comparing. This may result in SCEV expansion of pointers, but in practice
- // SCEV will fold the pointer arithmetic away as such:
- // BECount = (IVEnd - IVInit - 1) => IVLimit = IVInit (postinc).
- //
- // Valid Cases: (1) both integers is most common; (2) both may be pointers
- // for simple memset-style loops.
- //
- // IVInit integer and ExitCount pointer would only occur if a canonical IV
- // were generated on top of case #2, which is not expected.
-
- // For unit stride, IVCount = Start + ExitCount with 2's complement
- // overflow.
-
- // For integer IVs, truncate the IV before computing IVInit + BECount,
- // unless we know apriori that the limit must be a constant when evaluated
- // in the bitwidth of the IV. We prefer (potentially) keeping a truncate
- // of the IV in the loop over a (potentially) expensive expansion of the
- // widened exit count add(zext(add)) expression.
- if (SE->getTypeSizeInBits(IVInit->getType())
- > SE->getTypeSizeInBits(ExitCount->getType())) {
- if (isa<SCEVConstant>(IVInit) && isa<SCEVConstant>(ExitCount))
- ExitCount = SE->getZeroExtendExpr(ExitCount, IVInit->getType());
- else
- IVInit = SE->getTruncateExpr(IVInit, ExitCount->getType());
- }
-
- const SCEV *IVLimit = SE->getAddExpr(IVInit, ExitCount);
-
- if (UsePostInc)
- IVLimit = SE->getAddExpr(IVLimit, SE->getOne(IVLimit->getType()));
-
- // Expand the code for the iteration count.
- assert(SE->isLoopInvariant(IVLimit, L) &&
- "Computed iteration count is not loop invariant!");
- // Ensure that we generate the same type as IndVar, or a smaller integer
- // type. In the presence of null pointer values, we have an integer type
- // SCEV expression (IVInit) for a pointer type IV value (IndVar).
- return Rewriter.expandCodeFor(IVLimit, ExitCount->getType(),
- ExitingBB->getTerminator());
+ // For integer IVs, truncate the IV before computing the limit unless we
+ // know apriori that the limit must be a constant when evaluated in the
+ // bitwidth of the IV. We prefer (potentially) keeping a truncate of the
+ // IV in the loop over a (potentially) expensive expansion of the widened
+ // exit count add(zext(add)) expression.
+ if (IndVar->getType()->isIntegerTy() &&
+ SE->getTypeSizeInBits(AR->getType()) >
+ SE->getTypeSizeInBits(ExitCount->getType())) {
+ const SCEV *IVInit = AR->getStart();
+ if (!isa<SCEVConstant>(IVInit) || !isa<SCEVConstant>(ExitCount))
+ AR = cast<SCEVAddRecExpr>(SE->getTruncateExpr(AR, ExitCount->getType()));
}
+
+ const SCEVAddRecExpr *ARBase = UsePostInc ? AR->getPostIncExpr(*SE) : AR;
+ const SCEV *IVLimit = ARBase->evaluateAtIteration(ExitCount, *SE);
+ assert(SE->isLoopInvariant(IVLimit, L) &&
+ "Computed iteration count is not loop invariant!");
+ return Rewriter.expandCodeFor(IVLimit, ARBase->getType(),
+ ExitingBB->getTerminator());
}
/// This method rewrites the exit condition of the loop to be a canonical !=
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D146638.507387.patch
Type: text/x-patch
Size: 4320 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230322/67e0bb6b/attachment.bin>
More information about the llvm-commits
mailing list