]> granicus.if.org Git - llvm/commitdiff
[GVN] When merging blocks update LoopInfo if it's available
authorAdam Nemet <anemet@apple.com>
Thu, 1 Dec 2016 03:56:43 +0000 (03:56 +0000)
committerAdam Nemet <anemet@apple.com>
Thu, 1 Dec 2016 03:56:43 +0000 (03:56 +0000)
If LoopInfo is available during GVN, BasicAA will use it.  However
MergeBlockIntoPredecessor does not update LI as it merges blocks.

This didn't use to cause problems because LI was freed before
GVN/BasicAA.  Now with OptimizationRemarkEmitter, the lifetime of LI is
extended so LI needs to be kept up-to-date during GVN.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288307 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Scalar/GVN.h
lib/Transforms/Scalar/GVN.cpp
test/Transforms/GVN/stale-loop-info.ll [new file with mode: 0644]

index a86a9a8c448a5907899acc2cace9cb2dd3f1f9af..5492ba2c1d4b1adf3496622789f6b088d4e689dd 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/IntrinsicInst.h"
@@ -134,7 +135,7 @@ private:
 
   bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
                const TargetLibraryInfo &RunTLI, AAResults &RunAA,
-               MemoryDependenceResults *RunMD);
+               MemoryDependenceResults *RunMD, LoopInfo *LI);
 
   /// Push a new Value to the LeaderTable onto the list for its value number.
   void addToLeaderTable(uint32_t N, Value *V, const BasicBlock *BB) {
index d5234c0f7e3271134b4ff14ee125cbb67c64068d..79afff2fe3b91dcb154b89b99e2f47121119ac64 100644 (file)
@@ -586,7 +586,8 @@ PreservedAnalyses GVN::run(Function &F, FunctionAnalysisManager &AM) {
   auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
   auto &AA = AM.getResult<AAManager>(F);
   auto &MemDep = AM.getResult<MemoryDependenceAnalysis>(F);
-  bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep);
+  auto *LI = AM.getCachedResult<LoopAnalysis>(F);
+  bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep, LI);
   if (!Changed)
     return PreservedAnalyses::all();
   PreservedAnalyses PA;
@@ -2179,7 +2180,7 @@ bool GVN::processInstruction(Instruction *I) {
 /// runOnFunction - This is the main transformation entry point for a function.
 bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
                   const TargetLibraryInfo &RunTLI, AAResults &RunAA,
-                  MemoryDependenceResults *RunMD) {
+                  MemoryDependenceResults *RunMD, LoopInfo *LI) {
   AC = &RunAC;
   DT = &RunDT;
   VN.setDomTree(DT);
@@ -2196,9 +2197,9 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
   for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ) {
     BasicBlock *BB = &*FI++;
 
-    bool removedBlock =
-        MergeBlockIntoPredecessor(BB, DT, /* LoopInfo */ nullptr, MD);
-    if (removedBlock) ++NumGVNBlocks;
+    bool removedBlock = MergeBlockIntoPredecessor(BB, DT, LI, MD);
+    if (removedBlock)
+      ++NumGVNBlocks;
 
     Changed |= removedBlock;
   }
@@ -2693,13 +2694,16 @@ public:
     if (skipFunction(F))
       return false;
 
+    auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
+
     return Impl.runImpl(
         F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
         getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
         getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(),
         getAnalysis<AAResultsWrapperPass>().getAAResults(),
         NoLoads ? nullptr
-                : &getAnalysis<MemoryDependenceWrapperPass>().getMemDep());
+                : &getAnalysis<MemoryDependenceWrapperPass>().getMemDep(),
+        LIWP ? &LIWP->getLoopInfo() : nullptr);
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
diff --git a/test/Transforms/GVN/stale-loop-info.ll b/test/Transforms/GVN/stale-loop-info.ll
new file mode 100644 (file)
index 0000000..dd082c7
--- /dev/null
@@ -0,0 +1,50 @@
+; RUN: opt -loops -gvn -S < %s | FileCheck %s
+
+; This used to fail with ASAN enabled and if for some reason LoopInfo remained
+; available during GVN.  In this case BasicAA will use LI but
+; MergeBlockIntoPredecessor in GVN failed to update LI.
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+%struct.wibble.1028 = type { i32, i32, %struct.barney.881 }
+%struct.barney.881 = type { %struct.zot.882 }
+%struct.zot.882 = type { [64 x i8] }
+
+; Function Attrs: argmemonly
+declare void @snork.1(i8*) local_unnamed_addr #0
+
+define hidden zeroext i1 @eggs(%struct.wibble.1028* %arg, i1 %arg2) unnamed_addr align 2 {
+bb:
+  br i1 %arg2, label %bb14, label %bb3
+
+bb3:                                              ; preds = %bb
+  %tmp = getelementptr inbounds %struct.wibble.1028, %struct.wibble.1028* %arg, i64 0, i32 2, i32 0, i32 0, i64 0
+  %tmp5 = bitcast i8* %tmp to %struct.wibble.1028**
+  br label %bb6
+
+bb6:                                              ; preds = %bb12, %bb3
+  br label %bb7
+
+bb7:                                              ; preds = %bb6
+  br i1 undef, label %bb11, label %bb8
+
+bb8:                                              ; preds = %bb7
+  %tmp9 = load %struct.wibble.1028*, %struct.wibble.1028** %tmp5, align 8
+; CHECK: %tmp9 = load %struct.wibble.1028*, %struct.wibble.1028** %tmp5, align 8
+  %tmp10 = bitcast %struct.wibble.1028* %tmp9 to i8*
+  br label %bb12
+
+bb11:                                             ; preds = %bb7
+  br label %bb12
+
+bb12:                                             ; preds = %bb11, %bb8
+  %tmp13 = phi i8* [ %tmp, %bb11 ], [ %tmp10, %bb8 ]
+  call void @snork.1(i8* %tmp13) #1
+  br label %bb6
+
+bb14:                                             ; preds = %bb
+  ret i1 false
+}
+
+attributes #0 = { argmemonly }
+attributes #1 = { nounwind }