[Polly][CodeGen] Remove use of ScalarEvolution.
authorMichael Kruse <llvm-project@meinersbur.de>
Mon, 7 Dec 2020 20:39:32 +0000 (14:39 -0600)
committerMichael Kruse <llvm-project@meinersbur.de>
Mon, 7 Dec 2020 21:21:51 +0000 (15:21 -0600)
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

polly/lib/CodeGen/IRBuilder.cpp
polly/test/Isl/CodeGen/scev-backedgetaken.ll [new file with mode: 0644]

index c2bb5e4..001a907 100644 (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;
 
diff --git a/polly/test/Isl/CodeGen/scev-backedgetaken.ll b/polly/test/Isl/CodeGen/scev-backedgetaken.ll
new file mode 100644 (file)
index 0000000..397b5ae
--- /dev/null
@@ -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 = !{}