[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
This commit is contained in:
Michael Kruse 2020-12-07 14:39:32 -06:00
parent 399bc48ecc
commit 6249bfeefe
2 changed files with 71 additions and 9 deletions

View File

@ -188,6 +188,28 @@ void ScopAnnotator::annotateSecondLevel(llvm::Instruction *Inst,
Inst->setMetadata("noalias", SecondLevelOtherAliasScopeList);
}
/// Find the base pointer of an array access.
///
/// This should be equivalent to ScalarEvolution::getPointerBase, which we
/// cannot use here the IR is still under construction which ScalarEvolution
/// assumes to not be modified.
static Value *findBasePtr(Value *Val) {
while (true) {
if (auto *Gep = dyn_cast<GEPOperator>(Val)) {
Val = Gep->getPointerOperand();
continue;
}
if (auto *Cast = dyn_cast<BitCastOperator>(Val)) {
Val = Cast->getOperand(0);
continue;
}
break;
}
return Val;
}
void ScopAnnotator::annotate(Instruction *Inst) {
if (!Inst->mayReadOrWriteMemory())
return;
@ -209,15 +231,7 @@ void ScopAnnotator::annotate(Instruction *Inst) {
if (!Ptr)
return;
auto *PtrSCEV = SE->getSCEV(Ptr);
auto *BaseSCEV = SE->getPointerBase(PtrSCEV);
auto *SU = dyn_cast<SCEVUnknown>(BaseSCEV);
if (!SU)
return;
auto *BasePtr = SU->getValue();
Value *BasePtr = findBasePtr(Ptr);
if (!BasePtr)
return;

View File

@ -0,0 +1,48 @@
; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s
;
; llvm.org/PR48422
; Use of ScalarEvolution in Codegen not possible because DominatorTree is not updated.
;
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
define dso_local void @func(i1 %b, i1 %p3, [14 x i32]* %d) local_unnamed_addr {
entry:
%conv = zext i1 %b to i16
%add = select i1 %p3, i32 21, i32 20
br label %for.body.us.us
for.body.us.us:
%e.062.us.us = phi i16 [ %inc.us.us, %omp.inner.for.cond.simd.if.end.loopexit_crit_edge.us.us ], [ %conv, %entry ]
%idxprom.us.us = sext i16 %e.062.us.us to i64
br i1 %b, label %omp.inner.for.body.us.us.us.preheader, label %omp.inner.for.body.us63.us.preheader
omp.inner.for.body.us63.us.preheader:
%arrayidx25.us.le71.us = getelementptr inbounds [14 x i32], [14 x i32]* %d, i64 %idxprom.us.us, i64 0
%0 = load i32, i32* %arrayidx25.us.le71.us, align 4
br label %omp.inner.for.cond.simd.if.end.loopexit_crit_edge.us.us
omp.inner.for.body.us.us.us.preheader:
%arrayidx25.us.le.us.us = getelementptr inbounds [14 x i32], [14 x i32]* %d, i64 %idxprom.us.us, i64 0
%1 = load i32, i32* %arrayidx25.us.le.us.us, align 4
%conv27.us.le.us.us = select i1 undef, i16 0, i16 undef
br label %omp.inner.for.cond.simd.if.end.loopexit_crit_edge.us.us
omp.inner.for.cond.simd.if.end.loopexit_crit_edge.us.us:
%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 ]
%inc.us.us = add i16 %e.062.us.us, 1
%conv2.us.us = sext i16 %inc.us.us to i32
%cmp.us.us = icmp sgt i32 %add, %conv2.us.us
br i1 %cmp.us.us, label %for.body.us.us, label %for.cond.cleanup.loopexit
for.cond.cleanup.loopexit:
ret void
}
; CHECK-LABEL: @func(
; CHECK: polly.stmt.omp.inner.for.body.us.us.us.preheader5:
; CHECK: load i32, i32* %scevgep6, align 4, !alias.scope !0, !noalias !2
; CHECK: !0 = distinct !{!0, !1, !"polly.alias.scope.MemRef_d"}
; CHECK: !1 = distinct !{!1, !"polly.alias.scope.domain"}
; CHECK: !2 = !{}