[llvm] [polly] [delinearize] use SCEV exprs in getIndexExpressionsFromGEP (PR #162888)
Sebastian Pop via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 3 19:21:13 PST 2025
https://github.com/sebpop updated https://github.com/llvm/llvm-project/pull/162888
>From 12bdde54346700ce5bf2564d08bf56f09070ab85 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Fri, 10 Oct 2025 12:01:57 -0500
Subject: [PATCH 1/2] [delinearize] use SCEV exprs in
getIndexExpressionsFromGEP
---
llvm/include/llvm/Analysis/Delinearization.h | 12 ++++++------
llvm/lib/Analysis/Delinearization.cpp | 5 +++--
llvm/lib/Analysis/DependenceAnalysis.cpp | 2 +-
polly/lib/Analysis/ScopBuilder.cpp | 10 +++-------
4 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/llvm/include/llvm/Analysis/Delinearization.h b/llvm/include/llvm/Analysis/Delinearization.h
index b9fc0bcf47430..8fb30925b1ba7 100644
--- a/llvm/include/llvm/Analysis/Delinearization.h
+++ b/llvm/include/llvm/Analysis/Delinearization.h
@@ -154,15 +154,15 @@ bool validateDelinearizationResult(ScalarEvolution &SE,
///
/// This function optimistically assumes the GEP references into a fixed size
/// array. If this is actually true, this function returns a list of array
-/// subscript expressions in \p Subscripts and a list of integers describing
-/// the size of the individual array dimensions in \p Sizes. Both lists have
-/// either equal length or the size list is one element shorter in case there
-/// is no known size available for the outermost array dimension. Returns true
-/// if successful and false otherwise.
+/// subscript expressions in \p Subscripts and a list of SCEV expressions
+/// describing the size of the individual array dimensions in \p Sizes. Both
+/// lists have either equal length or the size list is one element shorter in
+/// case there is no known size available for the outermost array dimension.
+/// Returns true if successful and false otherwise.
bool getIndexExpressionsFromGEP(ScalarEvolution &SE,
const GetElementPtrInst *GEP,
SmallVectorImpl<const SCEV *> &Subscripts,
- SmallVectorImpl<int> &Sizes);
+ SmallVectorImpl<const SCEV *> &Sizes);
struct DelinearizationPrinterPass
: public PassInfoMixin<DelinearizationPrinterPass> {
diff --git a/llvm/lib/Analysis/Delinearization.cpp b/llvm/lib/Analysis/Delinearization.cpp
index 686622feec477..c2a429ffdfe9a 100644
--- a/llvm/lib/Analysis/Delinearization.cpp
+++ b/llvm/lib/Analysis/Delinearization.cpp
@@ -824,7 +824,7 @@ bool llvm::validateDelinearizationResult(ScalarEvolution &SE,
bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
const GetElementPtrInst *GEP,
SmallVectorImpl<const SCEV *> &Subscripts,
- SmallVectorImpl<int> &Sizes) {
+ SmallVectorImpl<const SCEV *> &Sizes) {
assert(Subscripts.empty() && Sizes.empty() &&
"Expected output lists to be empty on entry to this function.");
assert(GEP && "getIndexExpressionsFromGEP called with a null GEP");
@@ -855,7 +855,8 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
Subscripts.push_back(Expr);
if (!(DroppedFirstDim && i == 2))
- Sizes.push_back(ArrayTy->getNumElements());
+ Sizes.push_back(SE.getConstant(Expr->getType(),
+ ArrayTy->getNumElements()));
Ty = ArrayTy->getElementType();
}
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index fe07b7edb6713..b0cfaf6e5272b 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -3265,7 +3265,7 @@ bool DependenceInfo::tryDelinearizeFixedSize(
return false;
// Check that the two size arrays are non-empty and equal in length and
- // value.
+ // value. SCEV expressions are uniqued, so we can compare pointers.
if (SrcSizes.size() != DstSizes.size() ||
!std::equal(SrcSizes.begin(), SrcSizes.end(), DstSizes.begin())) {
SrcSubscripts.clear();
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 60a1e00916750..0f96c89232499 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -1464,7 +1464,7 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
return false;
SmallVector<const SCEV *, 4> Subscripts;
- SmallVector<int, 4> Sizes;
+ SmallVector<const SCEV *, 4> Sizes;
getIndexExpressionsFromGEP(SE, GEP, Subscripts, Sizes);
auto *BasePtr = GEP->getOperand(0);
@@ -1476,8 +1476,6 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
if (BasePtr != BasePointer->getValue())
return false;
- std::vector<const SCEV *> SizesSCEV;
-
const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads();
Loop *SurroundingLoop = Stmt->getSurroundingLoop();
@@ -1495,11 +1493,9 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
if (Sizes.empty())
return false;
+ std::vector<const SCEV *> SizesSCEV;
SizesSCEV.push_back(nullptr);
-
- for (auto V : Sizes)
- SizesSCEV.push_back(SE.getSCEV(
- ConstantInt::get(IntegerType::getInt64Ty(BasePtr->getContext()), V)));
+ SizesSCEV.insert(SizesSCEV.end(), Sizes.begin(), Sizes.end());
addArrayAccess(Stmt, Inst, AccType, BasePointer->getValue(), ElementType,
true, Subscripts, SizesSCEV, Val);
>From 5280bf2d3474accd68de4ba093467f74b8e5fbf2 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Wed, 3 Dec 2025 21:16:04 -0600
Subject: [PATCH 2/2] [delinearize] use DataLayout index type in
getIndexExpressionsFromGEP
Use SE.getEffectiveSCEVType(GEP->getPointerOperandType()) to get the
correct pointer index sized integer type for the SCEV constant sizes,
instead of using the type of the expression. This ensures the sizes
have the correct type for the target's address space.
---
llvm/lib/Analysis/Delinearization.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Analysis/Delinearization.cpp b/llvm/lib/Analysis/Delinearization.cpp
index c2a429ffdfe9a..31dab99c91f29 100644
--- a/llvm/lib/Analysis/Delinearization.cpp
+++ b/llvm/lib/Analysis/Delinearization.cpp
@@ -830,6 +830,7 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
assert(GEP && "getIndexExpressionsFromGEP called with a null GEP");
LLVM_DEBUG(dbgs() << "\nGEP to delinearize: " << *GEP << "\n");
Type *Ty = nullptr;
+ Type *IndexTy = SE.getEffectiveSCEVType(GEP->getPointerOperandType());
bool DroppedFirstDim = false;
for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
const SCEV *Expr = SE.getSCEV(GEP->getOperand(i));
@@ -855,8 +856,7 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
Subscripts.push_back(Expr);
if (!(DroppedFirstDim && i == 2))
- Sizes.push_back(SE.getConstant(Expr->getType(),
- ArrayTy->getNumElements()));
+ Sizes.push_back(SE.getConstant(IndexTy, ArrayTy->getNumElements()));
Ty = ArrayTy->getElementType();
}
More information about the llvm-commits
mailing list