[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

GitOrigin-RevId: 6249bfeefeed7ee2634355d4d7523b46fb00fda6
diff --git a/lib/CodeGen/IRBuilder.cpp b/lib/CodeGen/IRBuilder.cpp
index c2bb5e4..001a907 100644
--- a/lib/CodeGen/IRBuilder.cpp
+++ b/lib/CodeGen/IRBuilder.cpp
@@ -188,6 +188,28 @@
   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 @@
   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/test/Isl/CodeGen/scev-backedgetaken.ll b/test/Isl/CodeGen/scev-backedgetaken.ll
new file mode 100644
index 0000000..397b5ae
--- /dev/null
+++ b/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 = !{}