aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2025-07-25 15:29:40 +0100
committerGitHub <noreply@github.com>2025-07-25 15:29:40 +0100
commite21ee41be450f849f5247aafa07d7f4c3941bb9d (patch)
tree40471ca110ce19d73cb2b0e1288cbed94f3a881e /llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
parente4963834e44b2d41d1d6bce0c7c585a4c0b7bf86 (diff)
downloadllvm-e21ee41be450f849f5247aafa07d7f4c3941bb9d.zip
llvm-e21ee41be450f849f5247aafa07d7f4c3941bb9d.tar.gz
llvm-e21ee41be450f849f5247aafa07d7f4c3941bb9d.tar.bz2
[SCEV] Try to re-use pointer LCSSA phis when expanding SCEVs. (#147824)
Generalize the code added in https://github.com/llvm/llvm-project/pull/147214 to also support re-using pointer LCSSA phis when expanding SCEVs with AddRecs. A common source of integer AddRecs with pointer bases are runtime checks emitted by LV based on the distance between 2 pointer AddRecs. This improves codegen in some cases when vectorizing and prevents regressions with https://github.com/llvm/llvm-project/pull/142309, which turns some phis into single-entry ones, which SCEV will look through now (and expand the whole AddRec), whereas before it would have to treat the LCSSA phi as SCEVUnknown. Compile-time impact neutral: https://llvm-compile-time-tracker.com/compare.php?from=fd5fc76c91538871771be2c3be2ca3a5f2dcac31&to=ca5fc2b3d8e6efc09f1624a17fdbfbe909f14eb4&stat=instructions:u PR: https://github.com/llvm/llvm-project/pull/147824
Diffstat (limited to 'llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp36
1 files changed, 32 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index ed08c0b..ddb062b 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolutionPatternMatch.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/DataLayout.h"
@@ -42,6 +43,7 @@ cl::opt<unsigned> llvm::SCEVCheapExpansionBudget(
"controls the budget that is considered cheap (default = 4)"));
using namespace PatternMatch;
+using namespace SCEVPatternMatch;
PoisonFlags::PoisonFlags(const Instruction *I) {
NUW = false;
@@ -1224,6 +1226,7 @@ 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() ||
@@ -1231,11 +1234,36 @@ Value *SCEVExpander::tryToReuseLCSSAPhi(const SCEVAddRecExpr *S) {
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);
+ if (!isa<SCEVAddRecExpr>(ExitSCEV))
+ continue;
+ 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;
+
+ assert(Diff->getType()->isIntegerTy() &&
+ "difference must be of integer type");
+ Value *DiffV = expand(Diff);
+ Value *BaseV = &PN;
+ if (PhiTy->isPointerTy()) {
+ if (STy->isPointerTy())
+ return Builder.CreatePtrAdd(BaseV, DiffV);
+ BaseV = Builder.CreatePtrToInt(BaseV, DiffV->getType());
+ }
+ return Builder.CreateAdd(BaseV, DiffV);
}
return nullptr;