[llvm] [SCEV] Try to re-use pointer LCSSA phis when expanding SCEVs. (PR #147824)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 25 03:45:49 PDT 2025
================
@@ -1224,18 +1226,37 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
}
Value *SCEVExpander::tryToReuseLCSSAPhi(const SCEVAddRecExpr *S) {
+ Type *STy = S->getType();
const Loop *L = S->getLoop();
BasicBlock *EB = L->getExitBlock();
if (!EB || !EB->getSinglePredecessor() ||
!SE.DT.dominates(EB, Builder.GetInsertBlock()))
return nullptr;
for (auto &PN : EB->phis()) {
- if (!SE.isSCEVable(PN.getType()) || PN.getType() != S->getType())
+ if (!SE.isSCEVable(PN.getType()))
continue;
- auto *ExitV = SE.getSCEV(&PN);
- if (S == ExitV)
- return &PN;
+ auto *ExitSCEV = SE.getSCEV(&PN);
+ Type *PhiTy = PN.getType();
+ if (STy->isIntegerTy() && PhiTy->isPointerTy())
+ ExitSCEV = SE.getPtrToIntExpr(ExitSCEV, STy);
+ else if (S->getType() != PN.getType())
+ continue;
+
+ // Check if we can re-use the existing PN, by adjusting it with an expanded
+ // offset, if the offset is simpler.
+ const SCEV *Diff = SE.getMinusSCEV(S, ExitSCEV);
+ const SCEV *Op = Diff;
+ match(Diff, m_scev_Mul(m_scev_AllOnes(), m_SCEV(Op)));
+ match(Op, m_scev_PtrToInt(m_SCEV(Op)));
+ if (!isa<SCEVConstant, SCEVUnknown>(Op))
+ continue;
+
+ Value *DiffV = expand(Diff);
+ Value *BaseV = &PN;
+ if (DiffV->getType()->isIntegerTy() && PhiTy->isPointerTy())
+ return Builder.CreatePtrAdd(BaseV, DiffV);
----------------
fhahn wrote:
This was broken by the patch, the cases in the tests should be pointer AddRecs, that are than convered via PtrToInt.
I added a new test case (`llvm/test/Transforms/LoopIdiom/reuse-lcssa-phi-scev-expansion.ll`) which has a pointer `phi`, with the integer AddRec. Handle by creating a PtrToInt here, if `S` is has integer type.
https://github.com/llvm/llvm-project/pull/147824
More information about the llvm-commits
mailing list