[LICM] Preserve DT and LoopInfo specifically

Summary:
In LICM, CFG could be changed in splitPredecessorsOfLoopExit(), which update
only DT and LoopInfo. Therefore, we should preserve only DT and LoopInfo specifically,
instead of all analyses that depend on the CFG (setPreservesCFG()).

This change should fix PR37323.

Reviewers: uabelho, davide, dberlin, Ka-Ka

Reviewed By: dberlin

Subscribers: mzolotukhin, bjope, mcrosier, llvm-commits

Differential Revision: https://reviews.llvm.org/D46775

llvm-svn: 333198
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 8c07477..98599de 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -170,7 +170,8 @@
   /// loop preheaders be inserted into the CFG...
   ///
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.setPreservesCFG();
+    AU.addPreserved<DominatorTreeWrapperPass>();
+    AU.addPreserved<LoopInfoWrapperPass>();
     AU.addRequired<TargetLibraryInfoWrapperPass>();
     if (EnableMSSALoopDependency)
       AU.addRequired<MemorySSAWrapperPass>();
@@ -220,7 +221,10 @@
     return PreservedAnalyses::all();
 
   auto PA = getLoopPassPreservedAnalyses();
-  PA.preserveSet<CFGAnalyses>();
+
+  PA.preserve<DominatorTreeAnalysis>();
+  PA.preserve<LoopAnalysis>();
+
   return PA;
 }
 
diff --git a/llvm/test/Transforms/LICM/pr37323.ll b/llvm/test/Transforms/LICM/pr37323.ll
new file mode 100644
index 0000000..2753491
--- /dev/null
+++ b/llvm/test/Transforms/LICM/pr37323.ll
@@ -0,0 +1,31 @@
+;RUN: opt -verify-dom-info -loop-simplify -postdomtree -licm -adce -verify-loop-info -S -o - %s | FileCheck %s
+;RUN: opt -verify-dom-info -passes='loop-simplify,require<postdomtree>,require<opt-remark-emit>,loop(licm),function(adce)' -S -o - %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+@c = external global i16, align 1
+
+;Make sure this test do not crash while accessing PostDomTree which is not
+;preserved in LICM.
+;
+;CHECK-LABEL: fn1()
+;CHECK-LABEL: for.cond.loopexit.split.loop.exit
+;CHECK-LABEL: for.cond.loopexit.split.loop.exit1
+define void @fn1() {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %if.end, %for.cond1, %entry
+  %0 = phi i16 [ undef, %entry ], [ ptrtoint (i16* @c to i16), %if.end ], [ %.mux, %for.cond1 ]
+  br i1 undef, label %for.cond1, label %for.end8
+
+for.cond1:                                        ; preds = %if.end, %for.cond
+  %.mux = select i1 undef, i16 undef, i16 ptrtoint (i16* @c to i16)
+  br i1 undef, label %for.cond, label %if.end
+
+if.end:                                           ; preds = %for.cond1
+  br i1 undef, label %for.cond, label %for.cond1
+
+for.end8:                                         ; preds = %for.cond
+  ret void
+}