OSDN Git Service

[AggressiveInstCombine] Make TruncCombine class ignore unreachable basic blocks.
authorAmjad Aboud <amjad.aboud@intel.com>
Wed, 31 Jan 2018 10:41:31 +0000 (10:41 +0000)
committerAmjad Aboud <amjad.aboud@intel.com>
Wed, 31 Jan 2018 10:41:31 +0000 (10:41 +0000)
Because dead code may contain non-standard IR that causes infinite looping or crashes in underlying analysis.
See PR36134 for more details.

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

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

lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
lib/Transforms/AggressiveInstCombine/AggressiveInstCombineInternal.h
lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp
test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll [new file with mode: 0644]

index b7364d2..18432c0 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/Analysis/GlobalsModRef.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Dominators.h"
 #include "llvm/Pass.h"
 #include "llvm/Transforms/Scalar.h"
 using namespace llvm;
@@ -55,20 +56,23 @@ public:
 void AggressiveInstCombinerLegacyPass::getAnalysisUsage(
     AnalysisUsage &AU) const {
   AU.setPreservesCFG();
+  AU.addRequired<DominatorTreeWrapperPass>();
   AU.addRequired<TargetLibraryInfoWrapperPass>();
   AU.addPreserved<AAResultsWrapperPass>();
   AU.addPreserved<BasicAAWrapperPass>();
+  AU.addPreserved<DominatorTreeWrapperPass>();
   AU.addPreserved<GlobalsAAWrapperPass>();
 }
 
 bool AggressiveInstCombinerLegacyPass::runOnFunction(Function &F) {
+  auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
   auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
   auto &DL = F.getParent()->getDataLayout();
 
   bool MadeIRChange = false;
 
   // Handle TruncInst patterns
-  TruncInstCombine TIC(TLI, DL);
+  TruncInstCombine TIC(TLI, DL, DT);
   MadeIRChange |= TIC.run(F);
 
   // TODO: add more patterns to handle...
@@ -78,12 +82,13 @@ bool AggressiveInstCombinerLegacyPass::runOnFunction(Function &F) {
 
 PreservedAnalyses AggressiveInstCombinePass::run(Function &F,
                                                  FunctionAnalysisManager &AM) {
+  auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
   auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
   auto &DL = F.getParent()->getDataLayout();
   bool MadeIRChange = false;
 
   // Handle TruncInst patterns
-  TruncInstCombine TIC(TLI, DL);
+  TruncInstCombine TIC(TLI, DL, DT);
   MadeIRChange |= TIC.run(F);
   if (!MadeIRChange)
     // No changes, all analyses are preserved.
@@ -101,6 +106,7 @@ char AggressiveInstCombinerLegacyPass::ID = 0;
 INITIALIZE_PASS_BEGIN(AggressiveInstCombinerLegacyPass,
                       "aggressive-instcombine",
                       "Combine pattern based expressions", false, false)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
 INITIALIZE_PASS_END(AggressiveInstCombinerLegacyPass, "aggressive-instcombine",
                     "Combine pattern based expressions", false, false)
index 63255dd..d4655cf 100644 (file)
@@ -45,11 +45,13 @@ using namespace llvm;
 
 namespace llvm {
   class DataLayout;
+  class DominatorTree;
   class TargetLibraryInfo;
 
 class TruncInstCombine {
   TargetLibraryInfo &TLI;
   const DataLayout &DL;
+  const DominatorTree &DT;
 
   /// List of all TruncInst instructions to be processed.
   SmallVector<TruncInst *, 4> Worklist;
@@ -73,8 +75,9 @@ class TruncInstCombine {
   MapVector<Instruction *, Info> InstInfoMap;
 
 public:
-  TruncInstCombine(TargetLibraryInfo &TLI, const DataLayout &DL)
-      : TLI(TLI), DL(DL), CurrentTruncInst(nullptr) {}
+  TruncInstCombine(TargetLibraryInfo &TLI, const DataLayout &DL,
+                   const DominatorTree &DT)
+      : TLI(TLI), DL(DL), DT(DT), CurrentTruncInst(nullptr) {}
 
   /// Perform TruncInst pattern optimization on given function.
   bool run(Function &F);
index deb0979..0378ea7 100644 (file)
@@ -31,6 +31,7 @@
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Dominators.h"
 #include "llvm/IR/IRBuilder.h"
 using namespace llvm;
 
@@ -380,10 +381,14 @@ bool TruncInstCombine::run(Function &F) {
   bool MadeIRChange = false;
 
   // Collect all TruncInst in the function into the Worklist for evaluating.
-  for (auto &BB : F)
+  for (auto &BB : F) {
+    // Ignore unreachable basic block.
+    if (!DT.isReachableFromEntry(&BB))
+      continue;
     for (auto &I : BB)
       if (auto *CI = dyn_cast<TruncInst>(&I))
         Worklist.push_back(CI);
+  }
 
   // Process all TruncInst in the Worklist, for each instruction:
   //   1. Check if it dominates an eligible expression dag to be reduced.
diff --git a/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll b/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll
new file mode 100644 (file)
index 0000000..ea3b23d
--- /dev/null
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -aggressive-instcombine -S | FileCheck %s
+; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+
+; Aggressive Instcombine should be able ignore unreachable basic block.
+
+define void @func_20() {
+; CHECK-LABEL: @func_20(
+; CHECK-NEXT:  for.body94:
+; CHECK-NEXT:    unreachable
+; CHECK:       for.cond641:
+; CHECK-NEXT:    [[OR722:%.*]] = or i32 [[OR722]], undef
+; CHECK-NEXT:    [[OR723:%.*]] = or i32 [[OR722]], 1
+; CHECK-NEXT:    [[CONV724:%.*]] = trunc i32 [[OR723]] to i16
+; CHECK-NEXT:    br label [[FOR_COND641:%.*]]
+;
+for.body94:
+  unreachable
+
+for.cond641:
+  %or722 = or i32 %or722, undef
+  %or723 = or i32 %or722, 1
+  %conv724 = trunc i32 %or723 to i16
+  br label %for.cond641
+}
+
+define void @func_21() {
+; CHECK-LABEL: @func_21(
+; CHECK-NEXT:  for.body94:
+; CHECK-NEXT:    unreachable
+; CHECK:       for.cond641:
+; CHECK-NEXT:    [[OR722:%.*]] = or i32 [[A:%.*]], undef
+; CHECK-NEXT:    [[A]] = or i32 [[OR722]], undef
+; CHECK-NEXT:    [[OR723:%.*]] = or i32 [[OR722]], 1
+; CHECK-NEXT:    [[CONV724:%.*]] = trunc i32 [[OR723]] to i16
+; CHECK-NEXT:    br label [[FOR_COND641:%.*]]
+;
+for.body94:
+  unreachable
+
+for.cond641:
+  %or722 = or i32 %a, undef
+  %a = or i32 %or722, undef
+  %or723 = or i32 %or722, 1
+  %conv724 = trunc i32 %or723 to i16
+  br label %for.cond641
+}