[llvm] r288307 - [GVN] When merging blocks update LoopInfo if it's available

Adam Nemet via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 30 19:56:43 PST 2016


Author: anemet
Date: Wed Nov 30 21:56:43 2016
New Revision: 288307

URL: http://llvm.org/viewvc/llvm-project?rev=288307&view=rev
Log:
[GVN] When merging blocks update LoopInfo if it's available

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

Added:
    llvm/trunk/test/Transforms/GVN/stale-loop-info.ll
Modified:
    llvm/trunk/include/llvm/Transforms/Scalar/GVN.h
    llvm/trunk/lib/Transforms/Scalar/GVN.cpp

Modified: llvm/trunk/include/llvm/Transforms/Scalar/GVN.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/GVN.h?rev=288307&r1=288306&r2=288307&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar/GVN.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar/GVN.h Wed Nov 30 21:56:43 2016
@@ -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) {

Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=288307&r1=288306&r2=288307&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Nov 30 21:56:43 2016
@@ -586,7 +586,8 @@ PreservedAnalyses GVN::run(Function &F,
   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
 /// 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, Assumptio
   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 {

Added: llvm/trunk/test/Transforms/GVN/stale-loop-info.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/stale-loop-info.ll?rev=288307&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GVN/stale-loop-info.ll (added)
+++ llvm/trunk/test/Transforms/GVN/stale-loop-info.ll Wed Nov 30 21:56:43 2016
@@ -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 }




More information about the llvm-commits mailing list