Index: include/llvm/Transforms/IPO/PassManagerBuilder.h =================================================================== --- include/llvm/Transforms/IPO/PassManagerBuilder.h +++ include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -159,6 +159,7 @@ void addLTOOptimizationPasses(legacy::PassManagerBase &PM); void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM); void addPGOInstrPasses(legacy::PassManagerBase &MPM); + void addInstructionCombiningPass(legacy::PassManagerBase &MPM) const; public: /// populateFunctionPassManager - This fills in the function pass manager, Index: include/llvm/Transforms/InstCombine/InstCombine.h =================================================================== --- include/llvm/Transforms/InstCombine/InstCombine.h +++ include/llvm/Transforms/InstCombine/InstCombine.h @@ -26,15 +26,20 @@ class InstCombinePass { InstCombineWorklist Worklist; + bool ExpensiveCombines; public: static StringRef name() { return "InstCombinePass"; } // Explicitly define constructors for MSVC. - InstCombinePass() {} - InstCombinePass(InstCombinePass &&Arg) : Worklist(std::move(Arg.Worklist)) {} + InstCombinePass(bool ExpensiveCombines = true) + : ExpensiveCombines(ExpensiveCombines) {} + InstCombinePass(InstCombinePass &&Arg) + : Worklist(std::move(Arg.Worklist)), + ExpensiveCombines(Arg.ExpensiveCombines) {} InstCombinePass &operator=(InstCombinePass &&RHS) { Worklist = std::move(RHS.Worklist); + ExpensiveCombines = RHS.ExpensiveCombines; return *this; } Index: include/llvm/Transforms/Scalar.h =================================================================== --- include/llvm/Transforms/Scalar.h +++ include/llvm/Transforms/Scalar.h @@ -132,7 +132,7 @@ // into: // %Z = add int 2, %X // -FunctionPass *createInstructionCombiningPass(); +FunctionPass *createInstructionCombiningPass(bool ExpensiveCombines = true); //===----------------------------------------------------------------------===// // Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -178,6 +178,12 @@ PM.add(createScopedNoAliasAAWrapperPass()); } +void PassManagerBuilder::addInstructionCombiningPass( + legacy::PassManagerBase &MPM) const { + bool ExpensiveCombines = OptLevel > 2; + MPM.add(createInstructionCombiningPass(ExpensiveCombines)); +} + void PassManagerBuilder::populateFunctionPassManager( legacy::FunctionPassManager &FPM) { addExtensionsToPM(EP_EarlyAsPossible, FPM); @@ -259,7 +265,8 @@ MPM.add(createDeadArgEliminationPass()); // Dead argument elimination - MPM.add(createInstructionCombiningPass());// Clean up after IPCP & DAE + // Clean up after IPCP & DAE + addInstructionCombiningPass(MPM); addExtensionsToPM(EP_Peephole, MPM); MPM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE } @@ -294,7 +301,8 @@ MPM.add(createJumpThreadingPass()); // Thread jumps. MPM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals MPM.add(createCFGSimplificationPass()); // Merge & remove BBs - MPM.add(createInstructionCombiningPass()); // Combine silly seq's + // Combine silly seq's + addInstructionCombiningPass(MPM); addExtensionsToPM(EP_Peephole, MPM); MPM.add(createTailCallEliminationPass()); // Eliminate tail calls @@ -305,7 +313,7 @@ MPM.add(createLICMPass()); // Hoist loop invariants MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3)); MPM.add(createCFGSimplificationPass()); - MPM.add(createInstructionCombiningPass()); + addInstructionCombiningPass(MPM); MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars MPM.add(createLoopIdiomPass()); // Recognize idioms like memset. MPM.add(createLoopDeletionPass()); // Delete dead loops @@ -332,7 +340,7 @@ // Run instcombine after redundancy elimination to exploit opportunities // opened up by them. - MPM.add(createInstructionCombiningPass()); + addInstructionCombiningPass(MPM); addExtensionsToPM(EP_Peephole, MPM); MPM.add(createJumpThreadingPass()); // Thread jumps MPM.add(createCorrelatedValuePropagationPass()); @@ -349,7 +357,7 @@ if (BBVectorize) { MPM.add(createBBVectorizePass()); - MPM.add(createInstructionCombiningPass()); + addInstructionCombiningPass(MPM); addExtensionsToPM(EP_Peephole, MPM); if (OptLevel > 1 && UseGVNAfterVectorization) MPM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies @@ -367,7 +375,8 @@ MPM.add(createAggressiveDCEPass()); // Delete dead instructions MPM.add(createCFGSimplificationPass()); // Merge & remove BBs - MPM.add(createInstructionCombiningPass()); // Clean up after everything. + // Clean up after everything. + addInstructionCombiningPass(MPM); addExtensionsToPM(EP_Peephole, MPM); // FIXME: This is a HACK! The inliner pass above implicitly creates a CGSCC @@ -436,7 +445,7 @@ // on -O1 and no #pragma is found). Would be good to have these two passes // as function calls, so that we can only pass them when the vectorizer // changed the code. - MPM.add(createInstructionCombiningPass()); + addInstructionCombiningPass(MPM); if (OptLevel > 1 && ExtraVectorizerPasses) { // At higher optimization levels, try to clean up any runtime overlap and // alignment checks inserted by the vectorizer. We want to track correllated @@ -446,11 +455,11 @@ // dead (or speculatable) control flows or more combining opportunities. MPM.add(createEarlyCSEPass()); MPM.add(createCorrelatedValuePropagationPass()); - MPM.add(createInstructionCombiningPass()); + addInstructionCombiningPass(MPM); MPM.add(createLICMPass()); MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3)); MPM.add(createCFGSimplificationPass()); - MPM.add(createInstructionCombiningPass()); + addInstructionCombiningPass(MPM); } if (RunSLPAfterLoopVectorization) { @@ -463,7 +472,7 @@ if (BBVectorize) { MPM.add(createBBVectorizePass()); - MPM.add(createInstructionCombiningPass()); + addInstructionCombiningPass(MPM); addExtensionsToPM(EP_Peephole, MPM); if (OptLevel > 1 && UseGVNAfterVectorization) MPM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies @@ -478,13 +487,13 @@ addExtensionsToPM(EP_Peephole, MPM); MPM.add(createCFGSimplificationPass()); - MPM.add(createInstructionCombiningPass()); + addInstructionCombiningPass(MPM); if (!DisableUnrollLoops) { MPM.add(createLoopUnrollPass()); // Unroll small loops // LoopUnroll may generate some redundency to cleanup. - MPM.add(createInstructionCombiningPass()); + addInstructionCombiningPass(MPM); // Runtime unrolling will introduce runtime check in loop prologue. If the // unrolled loop is a inner loop, then the prologue will be inside the Index: lib/Transforms/InstCombine/InstCombineInternal.h =================================================================== --- lib/Transforms/InstCombine/InstCombineInternal.h +++ lib/Transforms/InstCombine/InstCombineInternal.h @@ -177,6 +177,8 @@ private: // Mode in which we are running the combiner. const bool MinimizeSize; + /// Enable combines that trigger rarely but are costly in compiletime. + const bool ExpensiveCombines; AliasAnalysis *AA; @@ -195,11 +197,12 @@ public: InstCombiner(InstCombineWorklist &Worklist, BuilderTy *Builder, - bool MinimizeSize, AliasAnalysis *AA, + bool MinimizeSize, bool ExpensiveCombines, AliasAnalysis *AA, AssumptionCache *AC, TargetLibraryInfo *TLI, DominatorTree *DT, const DataLayout &DL, LoopInfo *LI) : Worklist(Worklist), Builder(Builder), MinimizeSize(MinimizeSize), - AA(AA), AC(AC), TLI(TLI), DT(DT), DL(DL), LI(LI), MadeIRChange(false) {} + ExpensiveCombines(ExpensiveCombines), AA(AA), AC(AC), TLI(TLI), DT(DT), + DL(DL), LI(LI), MadeIRChange(false) {} /// \brief 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 @@ -76,6 +76,10 @@ STATISTIC(NumFactor , "Number of factorizations"); STATISTIC(NumReassoc , "Number of reassociations"); +static cl::opt +EnableExpensiveCombines("expensive-combines", + cl::desc("Enable expensive instruction combines")); + Value *InstCombiner::EmitGEPOffset(User *GEP) { return llvm::EmitGEPOffset(Builder, DL, GEP); } @@ -2751,9 +2755,9 @@ } } - // In general, it is possible for computeKnownBits to determine all bits in a - // value even when the operands are not all constants. - if (!I->use_empty() && I->getType()->isIntegerTy()) { + // In general, it is possible for computeKnownBits to determine all bits in + // a value even when the operands are not all constants. + if (ExpensiveCombines && !I->use_empty() && I->getType()->isIntegerTy()) { unsigned BitWidth = I->getType()->getScalarSizeInBits(); APInt KnownZero(BitWidth, 0); APInt KnownOne(BitWidth, 0); @@ -3024,8 +3028,10 @@ combineInstructionsOverFunction(Function &F, InstCombineWorklist &Worklist, AliasAnalysis *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, DominatorTree &DT, + bool ExpensiveCombines = true, LoopInfo *LI = nullptr) { auto &DL = F.getParent()->getDataLayout(); + ExpensiveCombines |= EnableExpensiveCombines; /// Builder - This is an IRBuilder that automatically inserts new /// instructions into the worklist when they are created. @@ -3045,8 +3051,8 @@ bool Changed = prepareICWorklistFromFunction(F, DL, &TLI, Worklist); - InstCombiner IC(Worklist, &Builder, F.optForMinSize(), AA, &AC, &TLI, &DT, - DL, LI); + InstCombiner IC(Worklist, &Builder, F.optForMinSize(), ExpensiveCombines, + AA, &AC, &TLI, &DT, DL, LI); Changed |= IC.run(); if (!Changed) @@ -3065,7 +3071,8 @@ auto *LI = AM->getCachedResult(F); // FIXME: The AliasAnalysis is not yet supported in the new pass manager - if (!combineInstructionsOverFunction(F, Worklist, nullptr, AC, TLI, DT, LI)) + if (!combineInstructionsOverFunction(F, Worklist, nullptr, AC, TLI, DT, + ExpensiveCombines, LI)) // No changes, all analyses are preserved. return PreservedAnalyses::all(); @@ -3083,11 +3090,13 @@ /// will try to combine all instructions in the function. class InstructionCombiningPass : public FunctionPass { InstCombineWorklist Worklist; + const bool ExpensiveCombines; public: static char ID; // Pass identification, replacement for typeid - InstructionCombiningPass() : FunctionPass(ID) { + InstructionCombiningPass(bool ExpensiveCombines = true) + : FunctionPass(ID), ExpensiveCombines(ExpensiveCombines) { initializeInstructionCombiningPassPass(*PassRegistry::getPassRegistry()); } @@ -3120,7 +3129,8 @@ auto *LIWP = getAnalysisIfAvailable(); auto *LI = LIWP ? &LIWP->getLoopInfo() : nullptr; - return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, LI); + return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, + ExpensiveCombines, LI); } char InstructionCombiningPass::ID = 0; @@ -3143,6 +3153,6 @@ initializeInstructionCombiningPassPass(*unwrap(R)); } -FunctionPass *llvm::createInstructionCombiningPass() { - return new InstructionCombiningPass(); +FunctionPass *llvm::createInstructionCombiningPass(bool ExpensiveCombines) { + return new InstructionCombiningPass(ExpensiveCombines); } Index: test/Analysis/ValueTracking/known-bits-from-range-md.ll =================================================================== --- test/Analysis/ValueTracking/known-bits-from-range-md.ll +++ test/Analysis/ValueTracking/known-bits-from-range-md.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -instsimplify < %s | FileCheck %s +; RUN: opt -S -instsimplify -instcombine < %s | FileCheck %s define i1 @test0(i8* %ptr) { ; CHECK-LABEL: @test0( @@ -23,10 +23,10 @@ define i1 @test2(i8* %ptr) { ; CHECK-LABEL: @test2( entry: -; CHECK: load -; CHECK: and -; CHECK: icmp eq -; CHECK: ret +; CHECK: %val = load i8 +; CHECK: %and = and i8 %val +; CHECK: %is.eq = icmp ne i8 %and, 0 +; CHECK: ret i1 %is.eq %val = load i8, i8* %ptr, !range !{i8 64, i8 129} %and = and i8 %val, 64 %is.eq = icmp eq i8 %and, 64 Index: test/Transforms/InstCombine/all-bits-shift.ll =================================================================== --- test/Transforms/InstCombine/all-bits-shift.ll +++ test/Transforms/InstCombine/all-bits-shift.ll @@ -1,5 +1,4 @@ -; RUN: opt -S -instcombine < %s | FileCheck %s -; RUN: opt -S -instsimplify < %s | FileCheck %s +; RUN: opt -S -instcombine -expensive-combines < %s | FileCheck %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu"