Index: llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp =================================================================== --- llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp +++ llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp @@ -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 @@ void AggressiveInstCombinerLegacyPass::getAnalysisUsage( AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired(); AU.addRequired(); AU.addPreserved(); AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); } bool AggressiveInstCombinerLegacyPass::runOnFunction(Function &F) { + auto &DT = getAnalysis().getDomTree(); auto &TLI = getAnalysis().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 @@ PreservedAnalyses AggressiveInstCombinePass::run(Function &F, FunctionAnalysisManager &AM) { + auto &DT = AM.getResult(F); auto &TLI = AM.getResult(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 @@ 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: llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombineInternal.h =================================================================== --- llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombineInternal.h +++ llvm/trunk/lib/Transforms/AggressiveInstCombine/AggressiveInstCombineInternal.h @@ -45,11 +45,13 @@ 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 Worklist; @@ -73,8 +75,9 @@ MapVector 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: llvm/trunk/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp =================================================================== --- llvm/trunk/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp +++ llvm/trunk/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp @@ -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 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(&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. Index: llvm/trunk/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll =================================================================== --- llvm/trunk/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll +++ llvm/trunk/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll @@ -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 +}