Index: include/llvm/Transforms/InstCombine/InstCombine.h =================================================================== --- include/llvm/Transforms/InstCombine/InstCombine.h +++ include/llvm/Transforms/InstCombine/InstCombine.h @@ -26,12 +26,15 @@ class InstCombinePass : public PassInfoMixin { InstCombineWorklist Worklist; bool ExpensiveCombines; + bool CodeSinking; public: static StringRef name() { return "InstCombinePass"; } - explicit InstCombinePass(bool ExpensiveCombines = true) - : ExpensiveCombines(ExpensiveCombines) {} + explicit InstCombinePass(bool ExpensiveCombines = true, + bool CodeSinking = true) + : ExpensiveCombines(ExpensiveCombines), + CodeSinking(CodeSinking) {} PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; @@ -43,12 +46,15 @@ class InstructionCombiningPass : public FunctionPass { InstCombineWorklist Worklist; const bool ExpensiveCombines; + const bool CodeSinking; public: static char ID; // Pass identification, replacement for typeid - InstructionCombiningPass(bool ExpensiveCombines = true) - : FunctionPass(ID), ExpensiveCombines(ExpensiveCombines) { + InstructionCombiningPass(bool ExpensiveCombines = true, + bool CodeSinking = true) + : FunctionPass(ID), ExpensiveCombines(ExpensiveCombines), + CodeSinking(CodeSinking) { initializeInstructionCombiningPassPass(*PassRegistry::getPassRegistry()); } @@ -68,7 +74,8 @@ // into: // %Z = add int 2, %X // -FunctionPass *createInstructionCombiningPass(bool ExpensiveCombines = true); +FunctionPass *createInstructionCombiningPass(bool ExpensiveCombines = true, + bool CodeSinking = true); } #endif Index: lib/Transforms/InstCombine/InstCombineInternal.h =================================================================== --- lib/Transforms/InstCombine/InstCombineInternal.h +++ lib/Transforms/InstCombine/InstCombineInternal.h @@ -297,6 +297,8 @@ /// Enable combines that trigger rarely but are costly in compiletime. const bool ExpensiveCombines; + const bool CodeSinking; + AliasAnalysis *AA; // Required analyses. @@ -315,12 +317,13 @@ public: InstCombiner(InstCombineWorklist &Worklist, BuilderTy &Builder, - bool MinimizeSize, bool ExpensiveCombines, AliasAnalysis *AA, - AssumptionCache &AC, TargetLibraryInfo &TLI, DominatorTree &DT, - OptimizationRemarkEmitter &ORE, const DataLayout &DL, - LoopInfo *LI) + bool MinimizeSize, bool ExpensiveCombines, bool CodeSinking, + AliasAnalysis *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, + DominatorTree &DT, OptimizationRemarkEmitter &ORE, + const DataLayout &DL, LoopInfo *LI) : Worklist(Worklist), Builder(Builder), MinimizeSize(MinimizeSize), - ExpensiveCombines(ExpensiveCombines), AA(AA), AC(AC), TLI(TLI), DT(DT), + ExpensiveCombines(ExpensiveCombines), CodeSinking(CodeSinking), + AA(AA), AC(AC), TLI(TLI), DT(DT), DL(DL), SQ(DL, &TLI, &DT, &AC), ORE(ORE), LI(LI) {} /// Run the combiner over the entire worklist until it is empty. Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -119,6 +119,10 @@ DEBUG_COUNTER(VisitCounter, "instcombine-visit", "Controls which instructions are visited"); +static cl::opt +EnableCodeSinking("instcombine-code-sinking", cl::desc("Enable code sinking"), + cl::init(true)); + static cl::opt EnableExpensiveCombines("expensive-combines", cl::desc("Enable expensive instruction combines")); @@ -3102,7 +3106,7 @@ } // See if we can trivially sink this instruction to a successor basic block. - if (I->hasOneUse()) { + if (CodeSinking && I->hasOneUse()) { BasicBlock *BB = I->getParent(); Instruction *UserInst = cast(*I->user_begin()); BasicBlock *UserParent; @@ -3350,9 +3354,10 @@ Function &F, InstCombineWorklist &Worklist, AliasAnalysis *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, DominatorTree &DT, OptimizationRemarkEmitter &ORE, bool ExpensiveCombines = true, - LoopInfo *LI = nullptr) { + bool CodeSinking = true, LoopInfo *LI = nullptr) { auto &DL = F.getParent()->getDataLayout(); ExpensiveCombines |= EnableExpensiveCombines; + CodeSinking &= EnableCodeSinking; /// Builder - This is an IRBuilder that automatically inserts new /// instructions into the worklist when they are created. @@ -3379,8 +3384,8 @@ MadeIRChange |= prepareICWorklistFromFunction(F, DL, &TLI, Worklist); - InstCombiner IC(Worklist, Builder, F.optForMinSize(), ExpensiveCombines, AA, - AC, TLI, DT, ORE, DL, LI); + InstCombiner IC(Worklist, Builder, F.optForMinSize(), ExpensiveCombines, + CodeSinking, AA, AC, TLI, DT, ORE, DL, LI); IC.MaxArraySizeForCombine = MaxArraySize; if (!IC.run()) @@ -3401,7 +3406,7 @@ auto *AA = &AM.getResult(F); if (!combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, ORE, - ExpensiveCombines, LI)) + ExpensiveCombines, CodeSinking, LI)) // No changes, all analyses are preserved. return PreservedAnalyses::all(); @@ -3443,7 +3448,7 @@ auto *LI = LIWP ? &LIWP->getLoopInfo() : nullptr; return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, ORE, - ExpensiveCombines, LI); + ExpensiveCombines, CodeSinking, LI); } char InstructionCombiningPass::ID = 0; @@ -3468,8 +3473,9 @@ initializeInstructionCombiningPassPass(*unwrap(R)); } -FunctionPass *llvm::createInstructionCombiningPass(bool ExpensiveCombines) { - return new InstructionCombiningPass(ExpensiveCombines); +FunctionPass *llvm::createInstructionCombiningPass(bool ExpensiveCombines, + bool CodeSinking) { + return new InstructionCombiningPass(ExpensiveCombines, CodeSinking); } void LLVMAddInstructionCombiningPass(LLVMPassManagerRef PM) { Index: test/Transforms/InstCombine/no_sink_instruction.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/no_sink_instruction.ll @@ -0,0 +1,19 @@ +; RUN: opt -instcombine -instcombine-code-sinking=0 -S < %s | FileCheck %s + +define i32 @test(i1 %C, i32 %A, i32 %B) { +; CHECK-LABEL: @test( +; CHECK: sdiv i32 +; CHECK-NEXT: add i32 +entry: + %tmp.2 = sdiv i32 %A, %B ; [#uses=1] + %tmp.9 = add i32 %B, %A ; [#uses=1] + br i1 %C, label %then, label %endif + +then: ; preds = %entry +; CHECK: ret i32 + ret i32 %tmp.9 + +endif: ; preds = %entry +; CHECK: ret i32 + ret i32 %tmp.2 +}