From: Michael Kruse Date: Mon, 7 Dec 2020 20:39:32 +0000 (-0600) Subject: [Polly][CodeGen] Remove use of ScalarEvolution. X-Git-Tag: llvmorg-13-init~4132 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6249bfeefeed7ee2634355d4d7523b46fb00fda6;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/polly/lib/CodeGen/IRBuilder.cpp b/polly/lib/CodeGen/IRBuilder.cpp index c2bb5e4..001a907 100644 --- a/polly/lib/CodeGen/IRBuilder.cpp +++ b/polly/lib/CodeGen/IRBuilder.cpp @@ -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(Val)) { + Val = Gep->getPointerOperand(); + continue; + } + if (auto *Cast = dyn_cast(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(BaseSCEV); - - if (!SU) - return; - - auto *BasePtr = SU->getValue(); - + Value *BasePtr = findBasePtr(Ptr); if (!BasePtr) return; diff --git a/polly/test/Isl/CodeGen/scev-backedgetaken.ll b/polly/test/Isl/CodeGen/scev-backedgetaken.ll new file mode 100644 index 0000000..397b5ae --- /dev/null +++ b/polly/test/Isl/CodeGen/scev-backedgetaken.ll @@ -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 = !{}