Index: include/llvm/Transforms/IPO/PassManagerBuilder.h =================================================================== --- include/llvm/Transforms/IPO/PassManagerBuilder.h +++ include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -188,7 +188,8 @@ void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM); void addPGOInstrPasses(legacy::PassManagerBase &MPM); void addFunctionSimplificationPasses(legacy::PassManagerBase &MPM); - void addInstructionCombiningPass(legacy::PassManagerBase &MPM) const; + void addInstructionCombiningPass(legacy::PassManagerBase &MPM, + bool FoldPhiArgs = true) 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,12 +26,15 @@ class InstCombinePass : public PassInfoMixin { InstCombineWorklist Worklist; bool ExpensiveCombines; + bool FoldPhiArgs; public: static StringRef name() { return "InstCombinePass"; } - explicit InstCombinePass(bool ExpensiveCombines = true) - : ExpensiveCombines(ExpensiveCombines) {} + explicit InstCombinePass(bool ExpensiveCombines = true, + bool FoldPhiArgs = true) + : ExpensiveCombines(ExpensiveCombines), + FoldPhiArgs(FoldPhiArgs) {} PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; @@ -43,12 +46,15 @@ class InstructionCombiningPass : public FunctionPass { InstCombineWorklist Worklist; const bool ExpensiveCombines; + const bool FoldPhiArgs; public: static char ID; // Pass identification, replacement for typeid - InstructionCombiningPass(bool ExpensiveCombines = true) - : FunctionPass(ID), ExpensiveCombines(ExpensiveCombines) { + InstructionCombiningPass(bool ExpensiveCombines = true, + bool FoldPhiArgs = true) + : FunctionPass(ID), ExpensiveCombines(ExpensiveCombines), + FoldPhiArgs(FoldPhiArgs) { initializeInstructionCombiningPassPass(*PassRegistry::getPassRegistry()); } @@ -68,7 +74,8 @@ // into: // %Z = add int 2, %X // -FunctionPass *createInstructionCombiningPass(bool ExpensiveCombines = true); +FunctionPass *createInstructionCombiningPass(bool ExpensiveCombines = true, + bool FoldPhiArgs = true); } #endif Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ lib/Passes/PassBuilder.cpp @@ -641,7 +641,7 @@ // Create a small function pass pipeline to cleanup after all the global // optimizations. FunctionPassManager GlobalCleanupPM(DebugLogging); - GlobalCleanupPM.addPass(InstCombinePass()); + GlobalCleanupPM.addPass(InstCombinePass(true, false)); invokePeepholeEPCallbacks(GlobalCleanupPM, Level); GlobalCleanupPM.addPass(SimplifyCFGPass()); Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -247,9 +247,10 @@ } void PassManagerBuilder::addInstructionCombiningPass( - legacy::PassManagerBase &PM) const { + legacy::PassManagerBase &PM, bool FoldPhiArgs) const { bool ExpensiveCombines = OptLevel > 2; - PM.add(createInstructionCombiningPass(ExpensiveCombines)); + PM.add(createInstructionCombiningPass(ExpensiveCombines, + FoldPhiArgs)); } void PassManagerBuilder::populateFunctionPassManager( @@ -517,7 +518,7 @@ MPM.add(createDeadArgEliminationPass()); // Dead argument elimination - addInstructionCombiningPass(MPM); // Clean up after IPCP & DAE + addInstructionCombiningPass(MPM, false); // Clean up after IPCP & DAE addExtensionsToPM(EP_Peephole, MPM); MPM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE Index: lib/Transforms/InstCombine/InstCombineInternal.h =================================================================== --- lib/Transforms/InstCombine/InstCombineInternal.h +++ lib/Transforms/InstCombine/InstCombineInternal.h @@ -290,6 +290,9 @@ /// Enable combines that trigger rarely but are costly in compiletime. const bool ExpensiveCombines; + // Allow operand folding of Phi Nodes. + const bool FoldPhiArgs; + AliasAnalysis *AA; // Required analyses. @@ -308,13 +311,15 @@ 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 FoldPhiArgs, 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), - DL(DL), SQ(DL, &TLI, &DT, &AC), ORE(ORE), LI(LI) {} + ExpensiveCombines(ExpensiveCombines), + FoldPhiArgs(FoldPhiArgs), 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/InstCombinePHI.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombinePHI.cpp +++ lib/Transforms/InstCombine/InstCombinePHI.cpp @@ -650,6 +650,8 @@ /// require special-casing a cast from the 'i1' type. See the comment in /// FoldPHIArgOpIntoPHI() about pessimizing illegal integer types. Instruction *InstCombiner::FoldPHIArgZextsIntoPHI(PHINode &Phi) { + if (!FoldPhiArgs) + return nullptr; // We cannot create a new instruction after the PHI if the terminator is an // EHPad because there is no valid insertion point. if (TerminatorInst *TI = Phi.getParent()->getTerminator()) @@ -724,6 +726,8 @@ /// only used by the PHI, PHI together their inputs, and do the operation once, /// to the result of the PHI. Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { + if (!FoldPhiArgs) + return nullptr; // We cannot create a new instruction after the PHI if the terminator is an // EHPad because there is no valid insertion point. if (TerminatorInst *TI = PN.getParent()->getTerminator()) Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3314,7 +3314,7 @@ Function &F, InstCombineWorklist &Worklist, AliasAnalysis *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, DominatorTree &DT, OptimizationRemarkEmitter &ORE, bool ExpensiveCombines = true, - LoopInfo *LI = nullptr) { + bool FoldPhiArgs = true, LoopInfo *LI = nullptr) { auto &DL = F.getParent()->getDataLayout(); ExpensiveCombines |= EnableExpensiveCombines; @@ -3343,8 +3343,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, + FoldPhiArgs, AA, AC, TLI, DT, ORE, DL, LI); IC.MaxArraySizeForCombine = MaxArraySize; if (!IC.run()) @@ -3365,7 +3365,8 @@ auto *AA = &AM.getResult(F); if (!combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, ORE, - ExpensiveCombines, LI)) + ExpensiveCombines, FoldPhiArgs, + LI)) // No changes, all analyses are preserved. return PreservedAnalyses::all(); @@ -3407,7 +3408,8 @@ auto *LI = LIWP ? &LIWP->getLoopInfo() : nullptr; return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, ORE, - ExpensiveCombines, LI); + ExpensiveCombines, FoldPhiArgs, + LI); } char InstructionCombiningPass::ID = 0; @@ -3432,8 +3434,9 @@ initializeInstructionCombiningPassPass(*unwrap(R)); } -FunctionPass *llvm::createInstructionCombiningPass(bool ExpensiveCombines) { - return new InstructionCombiningPass(ExpensiveCombines); +FunctionPass *llvm::createInstructionCombiningPass(bool ExpensiveCombines, + bool FoldPhiArgs) { + return new InstructionCombiningPass(ExpensiveCombines, FoldPhiArgs); } void LLVMAddInstructionCombiningPass(LLVMPassManagerRef PM) {