Skip to content

Commit 3399008

Browse files
committed
[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.
1 parent 12bdde5 commit 3399008

File tree

2 files changed

+202
-2
lines changed

2 files changed

+202
-2
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
From 7f9239030a10aa26d7002cc05ec92d935c43c45a Mon Sep 17 00:00:00 2001
2+
From: Sebastian Pop <[email protected]>
3+
Date: Fri, 10 Oct 2025 12:01:57 -0500
4+
Subject: [PATCH] [delinearize] use SCEV exprs in getIndexExpressionsFromGEP
5+
6+
---
7+
llvm/include/llvm/Analysis/Delinearization.h | 14 +++++-----
8+
llvm/lib/Analysis/Delinearization.cpp | 7 ++---
9+
llvm/lib/Analysis/DependenceAnalysis.cpp | 27 +++++++++-----------
10+
llvm/lib/Analysis/LoopCacheAnalysis.cpp | 5 ++--
11+
polly/lib/Analysis/ScopBuilder.cpp | 10 +++-----
12+
5 files changed, 28 insertions(+), 35 deletions(-)
13+
14+
diff --git a/llvm/include/llvm/Analysis/Delinearization.h b/llvm/include/llvm/Analysis/Delinearization.h
15+
index 434cfb61699d..9c729b5cf18c 100644
16+
--- a/llvm/include/llvm/Analysis/Delinearization.h
17+
+++ b/llvm/include/llvm/Analysis/Delinearization.h
18+
@@ -145,15 +145,15 @@ bool delinearizeFixedSizeArray(ScalarEvolution &SE, const SCEV *Expr,
19+
///
20+
/// This function optimistically assumes the GEP references into a fixed size
21+
/// array. If this is actually true, this function returns a list of array
22+
-/// subscript expressions in \p Subscripts and a list of integers describing
23+
-/// the size of the individual array dimensions in \p Sizes. Both lists have
24+
-/// either equal length or the size list is one element shorter in case there
25+
-/// is no known size available for the outermost array dimension. Returns true
26+
-/// if successful and false otherwise.
27+
+/// subscript expressions in \p Subscripts and a list of SCEV expressions
28+
+/// describing the size of the individual array dimensions in \p Sizes. Both
29+
+/// lists have either equal length or the size list is one element shorter in
30+
+/// case there is no known size available for the outermost array dimension.
31+
+/// Returns true if successful and false otherwise.
32+
bool getIndexExpressionsFromGEP(ScalarEvolution &SE,
33+
const GetElementPtrInst *GEP,
34+
SmallVectorImpl<const SCEV *> &Subscripts,
35+
- SmallVectorImpl<int> &Sizes);
36+
+ SmallVectorImpl<const SCEV *> &Sizes);
37+
38+
/// Implementation of fixed size array delinearization. Try to delinearize
39+
/// access function for a fixed size multi-dimensional array, by deriving
40+
@@ -164,7 +164,7 @@ bool getIndexExpressionsFromGEP(ScalarEvolution &SE,
41+
bool tryDelinearizeFixedSizeImpl(ScalarEvolution *SE, Instruction *Inst,
42+
const SCEV *AccessFn,
43+
SmallVectorImpl<const SCEV *> &Subscripts,
44+
- SmallVectorImpl<int> &Sizes);
45+
+ SmallVectorImpl<const SCEV *> &Sizes);
46+
47+
struct DelinearizationPrinterPass
48+
: public PassInfoMixin<DelinearizationPrinterPass> {
49+
diff --git a/llvm/lib/Analysis/Delinearization.cpp b/llvm/lib/Analysis/Delinearization.cpp
50+
index 4064b25d9d4e..f438a9bd9ecd 100644
51+
--- a/llvm/lib/Analysis/Delinearization.cpp
52+
+++ b/llvm/lib/Analysis/Delinearization.cpp
53+
@@ -659,7 +659,7 @@ bool llvm::delinearizeFixedSizeArray(ScalarEvolution &SE, const SCEV *Expr,
54+
bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
55+
const GetElementPtrInst *GEP,
56+
SmallVectorImpl<const SCEV *> &Subscripts,
57+
- SmallVectorImpl<int> &Sizes) {
58+
+ SmallVectorImpl<const SCEV *> &Sizes) {
59+
assert(Subscripts.empty() && Sizes.empty() &&
60+
"Expected output lists to be empty on entry to this function.");
61+
assert(GEP && "getIndexExpressionsFromGEP called with a null GEP");
62+
@@ -690,7 +690,8 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
63+
64+
Subscripts.push_back(Expr);
65+
if (!(DroppedFirstDim && i == 2))
66+
- Sizes.push_back(ArrayTy->getNumElements());
67+
+ Sizes.push_back(SE.getConstant(Expr->getType(),
68+
+ ArrayTy->getNumElements()));
69+
70+
Ty = ArrayTy->getElementType();
71+
}
72+
@@ -706,7 +707,7 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
73+
74+
bool llvm::tryDelinearizeFixedSizeImpl(
75+
ScalarEvolution *SE, Instruction *Inst, const SCEV *AccessFn,
76+
- SmallVectorImpl<const SCEV *> &Subscripts, SmallVectorImpl<int> &Sizes) {
77+
+ SmallVectorImpl<const SCEV *> &Subscripts, SmallVectorImpl<const SCEV *> &Sizes) {
78+
Value *SrcPtr = getLoadStorePointerOperand(Inst);
79+
80+
// Check the simple case where the array dimensions are fixed size.
81+
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
82+
index 8d20b0e10305..7dd0bea75c84 100644
83+
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
84+
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
85+
@@ -3504,8 +3504,8 @@ bool DependenceInfo::tryDelinearizeFixedSize(
86+
"expected src and dst scev unknowns to be equal");
87+
});
88+
89+
- SmallVector<int, 4> SrcSizes;
90+
- SmallVector<int, 4> DstSizes;
91+
+ SmallVector<const SCEV *, 4> SrcSizes;
92+
+ SmallVector<const SCEV *, 4> DstSizes;
93+
if (!tryDelinearizeFixedSizeImpl(SE, Src, SrcAccessFn, SrcSubscripts,
94+
SrcSizes) ||
95+
!tryDelinearizeFixedSizeImpl(SE, Dst, DstAccessFn, DstSubscripts,
96+
@@ -3513,7 +3513,7 @@ bool DependenceInfo::tryDelinearizeFixedSize(
97+
return false;
98+
99+
// Check that the two size arrays are non-empty and equal in length and
100+
- // value.
101+
+ // value. SCEV expressions are uniqued, so we can compare pointers.
102+
if (SrcSizes.size() != DstSizes.size() ||
103+
!std::equal(SrcSizes.begin(), SrcSizes.end(), DstSizes.begin())) {
104+
SrcSubscripts.clear();
105+
@@ -3535,7 +3535,7 @@ bool DependenceInfo::tryDelinearizeFixedSize(
106+
// iff the subscripts are positive and are less than the range of the
107+
// dimension.
108+
if (!DisableDelinearizationChecks) {
109+
- auto AllIndicesInRange = [&](SmallVector<int, 4> &DimensionSizes,
110+
+ auto AllIndicesInRange = [&](SmallVector<const SCEV *, 4> &DimensionSizes,
111+
SmallVectorImpl<const SCEV *> &Subscripts,
112+
Value *Ptr) {
113+
size_t SSize = Subscripts.size();
114+
@@ -3548,17 +3548,14 @@ bool DependenceInfo::tryDelinearizeFixedSize(
115+
});
116+
return false;
117+
}
118+
- if (auto *SType = dyn_cast<IntegerType>(S->getType())) {
119+
- const SCEV *Range = SE->getConstant(
120+
- ConstantInt::get(SType, DimensionSizes[I - 1], false));
121+
- if (!isKnownLessThan(S, Range)) {
122+
- LLVM_DEBUG({
123+
- dbgs() << "Check failed: !isKnownLessThan(S, Range)\n";
124+
- dbgs() << " S: " << *S << "\n"
125+
- << " Range: " << *Range << "\n";
126+
- });
127+
- return false;
128+
- }
129+
+ const SCEV *Range = DimensionSizes[I - 1];
130+
+ if (!isKnownLessThan(S, Range)) {
131+
+ LLVM_DEBUG({
132+
+ dbgs() << "Check failed: !isKnownLessThan(S, Range)\n";
133+
+ dbgs() << " S: " << *S << "\n"
134+
+ << " Range: " << *Range << "\n";
135+
+ });
136+
+ return false;
137+
}
138+
}
139+
return true;
140+
diff --git a/llvm/lib/Analysis/LoopCacheAnalysis.cpp b/llvm/lib/Analysis/LoopCacheAnalysis.cpp
141+
index 050c32707596..74bcce8f51a4 100644
142+
--- a/llvm/lib/Analysis/LoopCacheAnalysis.cpp
143+
+++ b/llvm/lib/Analysis/LoopCacheAnalysis.cpp
144+
@@ -356,15 +356,14 @@ CacheCostTy IndexedReference::computeRefCost(const Loop &L,
145+
146+
bool IndexedReference::tryDelinearizeFixedSize(
147+
const SCEV *AccessFn, SmallVectorImpl<const SCEV *> &Subscripts) {
148+
- SmallVector<int, 4> ArraySizes;
149+
+ SmallVector<const SCEV *, 4> ArraySizes;
150+
if (!tryDelinearizeFixedSizeImpl(&SE, &StoreOrLoadInst, AccessFn, Subscripts,
151+
ArraySizes))
152+
return false;
153+
154+
// Populate Sizes with scev expressions to be used in calculations later.
155+
for (auto Idx : seq<unsigned>(1, Subscripts.size()))
156+
- Sizes.push_back(
157+
- SE.getConstant(Subscripts[Idx]->getType(), ArraySizes[Idx - 1]));
158+
+ Sizes.push_back(ArraySizes[Idx - 1]);
159+
160+
LLVM_DEBUG({
161+
dbgs() << "Delinearized subscripts of fixed-size array\n"
162+
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
163+
index 67a4c4345580..ec77b15ddd76 100644
164+
--- a/polly/lib/Analysis/ScopBuilder.cpp
165+
+++ b/polly/lib/Analysis/ScopBuilder.cpp
166+
@@ -1463,7 +1463,7 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
167+
return false;
168+
169+
SmallVector<const SCEV *, 4> Subscripts;
170+
- SmallVector<int, 4> Sizes;
171+
+ SmallVector<const SCEV *, 4> Sizes;
172+
getIndexExpressionsFromGEP(SE, GEP, Subscripts, Sizes);
173+
auto *BasePtr = GEP->getOperand(0);
174+
175+
@@ -1475,8 +1475,6 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
176+
if (BasePtr != BasePointer->getValue())
177+
return false;
178+
179+
- std::vector<const SCEV *> SizesSCEV;
180+
-
181+
const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads();
182+
183+
Loop *SurroundingLoop = Stmt->getSurroundingLoop();
184+
@@ -1494,11 +1492,9 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
185+
if (Sizes.empty())
186+
return false;
187+
188+
+ std::vector<const SCEV *> SizesSCEV;
189+
SizesSCEV.push_back(nullptr);
190+
-
191+
- for (auto V : Sizes)
192+
- SizesSCEV.push_back(SE.getSCEV(
193+
- ConstantInt::get(IntegerType::getInt64Ty(BasePtr->getContext()), V)));
194+
+ SizesSCEV.insert(SizesSCEV.end(), Sizes.begin(), Sizes.end());
195+
196+
addArrayAccess(Stmt, Inst, AccType, BasePointer->getValue(), ElementType,
197+
true, Subscripts, SizesSCEV, Val);
198+
--
199+
2.45.2
200+

llvm/lib/Analysis/Delinearization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
830830
assert(GEP && "getIndexExpressionsFromGEP called with a null GEP");
831831
LLVM_DEBUG(dbgs() << "\nGEP to delinearize: " << *GEP << "\n");
832832
Type *Ty = nullptr;
833+
Type *IndexTy = SE.getEffectiveSCEVType(GEP->getPointerOperandType());
833834
bool DroppedFirstDim = false;
834835
for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
835836
const SCEV *Expr = SE.getSCEV(GEP->getOperand(i));
@@ -855,8 +856,7 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
855856

856857
Subscripts.push_back(Expr);
857858
if (!(DroppedFirstDim && i == 2))
858-
Sizes.push_back(SE.getConstant(Expr->getType(),
859-
ArrayTy->getNumElements()));
859+
Sizes.push_back(SE.getConstant(IndexTy, ArrayTy->getNumElements()));
860860

861861
Ty = ArrayTy->getElementType();
862862
}

0 commit comments

Comments
 (0)