Skip to content

Commit 6249bfe

Browse files
committed
[Polly][CodeGen] Remove use of ScalarEvolution.
ScalarEvolution::getSCEV cannot be used during codegen. ScalarEvolution assumes a stable IR and control flow which is under construction during Polly's CodeGen. In particular, it uses DominatorTree for compute the backedge taken count. However the DominatorTree is not updated during codegen. In this case, SCEV was used to determine the base pointer of an array access. Replace it by our own function. Polly generates only GEP and BitCasts for array acceses, i.e. it is sufficient to handle these to to find the base pointer. Fixes llvm.org/PR48422
1 parent 399bc48 commit 6249bfe

File tree

2 files changed

+71
-9
lines changed

2 files changed

+71
-9
lines changed

polly/lib/CodeGen/IRBuilder.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,28 @@ void ScopAnnotator::annotateSecondLevel(llvm::Instruction *Inst,
188188
Inst->setMetadata("noalias", SecondLevelOtherAliasScopeList);
189189
}
190190

191+
/// Find the base pointer of an array access.
192+
///
193+
/// This should be equivalent to ScalarEvolution::getPointerBase, which we
194+
/// cannot use here the IR is still under construction which ScalarEvolution
195+
/// assumes to not be modified.
196+
static Value *findBasePtr(Value *Val) {
197+
while (true) {
198+
if (auto *Gep = dyn_cast<GEPOperator>(Val)) {
199+
Val = Gep->getPointerOperand();
200+
continue;
201+
}
202+
if (auto *Cast = dyn_cast<BitCastOperator>(Val)) {
203+
Val = Cast->getOperand(0);
204+
continue;
205+
}
206+
207+
break;
208+
}
209+
210+
return Val;
211+
}
212+
191213
void ScopAnnotator::annotate(Instruction *Inst) {
192214
if (!Inst->mayReadOrWriteMemory())
193215
return;
@@ -209,15 +231,7 @@ void ScopAnnotator::annotate(Instruction *Inst) {
209231
if (!Ptr)
210232
return;
211233

212-
auto *PtrSCEV = SE->getSCEV(Ptr);
213-
auto *BaseSCEV = SE->getPointerBase(PtrSCEV);
214-
auto *SU = dyn_cast<SCEVUnknown>(BaseSCEV);
215-
216-
if (!SU)
217-
return;
218-
219-
auto *BasePtr = SU->getValue();
220-
234+
Value *BasePtr = findBasePtr(Ptr);
221235
if (!BasePtr)
222236
return;
223237

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s
2+
;
3+
; llvm.org/PR48422
4+
; Use of ScalarEvolution in Codegen not possible because DominatorTree is not updated.
5+
;
6+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
7+
8+
define dso_local void @func(i1 %b, i1 %p3, [14 x i32]* %d) local_unnamed_addr {
9+
entry:
10+
%conv = zext i1 %b to i16
11+
%add = select i1 %p3, i32 21, i32 20
12+
br label %for.body.us.us
13+
14+
for.body.us.us:
15+
%e.062.us.us = phi i16 [ %inc.us.us, %omp.inner.for.cond.simd.if.end.loopexit_crit_edge.us.us ], [ %conv, %entry ]
16+
%idxprom.us.us = sext i16 %e.062.us.us to i64
17+
br i1 %b, label %omp.inner.for.body.us.us.us.preheader, label %omp.inner.for.body.us63.us.preheader
18+
19+
omp.inner.for.body.us63.us.preheader:
20+
%arrayidx25.us.le71.us = getelementptr inbounds [14 x i32], [14 x i32]* %d, i64 %idxprom.us.us, i64 0
21+
%0 = load i32, i32* %arrayidx25.us.le71.us, align 4
22+
br label %omp.inner.for.cond.simd.if.end.loopexit_crit_edge.us.us
23+
24+
omp.inner.for.body.us.us.us.preheader:
25+
%arrayidx25.us.le.us.us = getelementptr inbounds [14 x i32], [14 x i32]* %d, i64 %idxprom.us.us, i64 0
26+
%1 = load i32, i32* %arrayidx25.us.le.us.us, align 4
27+
%conv27.us.le.us.us = select i1 undef, i16 0, i16 undef
28+
br label %omp.inner.for.cond.simd.if.end.loopexit_crit_edge.us.us
29+
30+
omp.inner.for.cond.simd.if.end.loopexit_crit_edge.us.us:
31+
%conv27.lcssa.us.us = phi i16 [ undef, %omp.inner.for.body.us63.us.preheader ], [ %conv27.us.le.us.us, %omp.inner.for.body.us.us.us.preheader ]
32+
%inc.us.us = add i16 %e.062.us.us, 1
33+
%conv2.us.us = sext i16 %inc.us.us to i32
34+
%cmp.us.us = icmp sgt i32 %add, %conv2.us.us
35+
br i1 %cmp.us.us, label %for.body.us.us, label %for.cond.cleanup.loopexit
36+
37+
for.cond.cleanup.loopexit:
38+
ret void
39+
}
40+
41+
42+
; CHECK-LABEL: @func(
43+
; CHECK: polly.stmt.omp.inner.for.body.us.us.us.preheader5:
44+
; CHECK: load i32, i32* %scevgep6, align 4, !alias.scope !0, !noalias !2
45+
46+
; CHECK: !0 = distinct !{!0, !1, !"polly.alias.scope.MemRef_d"}
47+
; CHECK: !1 = distinct !{!1, !"polly.alias.scope.domain"}
48+
; CHECK: !2 = !{}

0 commit comments

Comments
 (0)