Index: llvm/trunk/include/llvm-c/Transforms/Scalar.h =================================================================== --- llvm/trunk/include/llvm-c/Transforms/Scalar.h +++ llvm/trunk/include/llvm-c/Transforms/Scalar.h @@ -44,9 +44,6 @@ /** See llvm::createCFGSimplificationPass function. */ void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM); -/** See llvm::createLateCFGSimplificationPass function. */ -void LLVMAddLateCFGSimplificationPass(LLVMPassManagerRef PM); - /** See llvm::createDeadStoreEliminationPass function. */ void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM); Index: llvm/trunk/include/llvm/InitializePasses.h =================================================================== --- llvm/trunk/include/llvm/InitializePasses.h +++ llvm/trunk/include/llvm/InitializePasses.h @@ -174,7 +174,6 @@ void initializeJumpThreadingPass(PassRegistry&); void initializeLCSSAVerificationPassPass(PassRegistry&); void initializeLCSSAWrapperPassPass(PassRegistry&); -void initializeLateCFGSimplifyPassPass(PassRegistry&); void initializeLazyBlockFrequencyInfoPassPass(PassRegistry&); void initializeLazyBranchProbabilityInfoPassPass(PassRegistry&); void initializeLazyMachineBlockFrequencyInfoPassPass(PassRegistry&); Index: llvm/trunk/include/llvm/LinkAllPasses.h =================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h +++ llvm/trunk/include/llvm/LinkAllPasses.h @@ -75,7 +75,6 @@ (void) llvm::createCallGraphDOTPrinterPass(); (void) llvm::createCallGraphViewerPass(); (void) llvm::createCFGSimplificationPass(); - (void) llvm::createLateCFGSimplificationPass(); (void) llvm::createCFLAndersAAWrapperPass(); (void) llvm::createCFLSteensAAWrapperPass(); (void) llvm::createStructurizeCFGPass(); Index: llvm/trunk/include/llvm/Transforms/Scalar.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar.h +++ llvm/trunk/include/llvm/Transforms/Scalar.h @@ -255,18 +255,12 @@ //===----------------------------------------------------------------------===// // // CFGSimplification - Merge basic blocks, eliminate unreachable blocks, -// simplify terminator instructions, etc... +// simplify terminator instructions, convert switches to lookup tables, etc. // FunctionPass *createCFGSimplificationPass( - int Threshold = -1, std::function Ftor = nullptr); - -//===----------------------------------------------------------------------===// -// -// LateCFGSimplification - Like CFGSimplification, but may also -// convert switches to lookup tables. -// -FunctionPass *createLateCFGSimplificationPass( - int Threshold = -1, std::function Ftor = nullptr); + unsigned Threshold = 1, bool ForwardSwitchCond = false, + bool ConvertSwitch = false, bool KeepLoops = true, + std::function Ftor = nullptr); //===----------------------------------------------------------------------===// // Index: llvm/trunk/include/llvm/Transforms/Scalar/SimplifyCFG.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar/SimplifyCFG.h +++ llvm/trunk/include/llvm/Transforms/Scalar/SimplifyCFG.h @@ -31,8 +31,16 @@ SimplifyCFGOptions Options; public: - /// Construct a pass with default options. - SimplifyCFGPass(); + /// The default constructor sets the pass options to create optimal IR, + /// rather than canonical IR. That is, by default we do transformations that + /// are likely to improve performance but make analysis more difficult. + /// FIXME: This is inverted from what most instantiations of the pass should + /// be. + SimplifyCFGPass() + : SimplifyCFGPass(SimplifyCFGOptions() + .forwardSwitchCondToPhi(true) + .convertSwitchToLookupTable(true) + .needCanonicalLoops(false)) {} /// Construct a pass with optional optimizations. SimplifyCFGPass(const SimplifyCFGOptions &PassOptions); Index: llvm/trunk/include/llvm/Transforms/Utils/Local.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h @@ -65,13 +65,36 @@ bool NeedCanonicalLoop; AssumptionCache *AC; - SimplifyCFGOptions(int BonusThreshold = 1, bool ForwardSwitchCond = false, + SimplifyCFGOptions(unsigned BonusThreshold = 1, + bool ForwardSwitchCond = false, bool SwitchToLookup = false, bool CanonicalLoops = true, AssumptionCache *AssumpCache = nullptr) : BonusInstThreshold(BonusThreshold), ForwardSwitchCondToPhi(ForwardSwitchCond), ConvertSwitchToLookupTable(SwitchToLookup), NeedCanonicalLoop(CanonicalLoops), AC(AssumpCache) {} + + // Support 'builder' pattern to set members by name at construction time. + SimplifyCFGOptions &bonusInstThreshold(int I) { + BonusInstThreshold = I; + return *this; + } + SimplifyCFGOptions &forwardSwitchCondToPhi(bool B) { + ForwardSwitchCondToPhi = B; + return *this; + } + SimplifyCFGOptions &convertSwitchToLookupTable(bool B) { + ConvertSwitchToLookupTable = B; + return *this; + } + SimplifyCFGOptions &needCanonicalLoops(bool B) { + NeedCanonicalLoop = B; + return *this; + } + SimplifyCFGOptions &setAssumptionCache(AssumptionCache *Cache) { + AC = Cache; + return *this; + } }; //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp @@ -131,7 +131,6 @@ initializeMemCpyOptLegacyPassPass(R); initializeDCELegacyPassPass(R); initializeCFGSimplifyPassPass(R); - initializeLateCFGSimplifyPassPass(R); } void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) { Index: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -365,7 +365,7 @@ // determine whether it succeeded. We can exploit existing control-flow in // ldrex/strex loops to simplify this, but it needs tidying up. if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy) - addPass(createLateCFGSimplificationPass()); + addPass(createCFGSimplificationPass(1, true, true, false)); // Run LoopDataPrefetch // Index: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp @@ -384,10 +384,11 @@ // determine whether it succeeded. We can exploit existing control-flow in // ldrex/strex loops to simplify this, but it needs tidying up. if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy) - addPass(createCFGSimplificationPass(-1, [this](const Function &F) { - const auto &ST = this->TM->getSubtarget(F); - return ST.hasAnyDataBarrier() && !ST.isThumb1Only(); - })); + addPass(createCFGSimplificationPass( + 1, false, false, true, [this](const Function &F) { + const auto &ST = this->TM->getSubtarget(F); + return ST.hasAnyDataBarrier() && !ST.isThumb1Only(); + })); TargetPassConfig::addIRPasses(); Index: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp +++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -625,7 +625,9 @@ } addExtensionsToPM(EP_Peephole, MPM); - MPM.add(createLateCFGSimplificationPass()); // Switches to lookup tables + // Switches to lookup tables and other transforms that may not be considered + // canonical by other IR passes. + MPM.add(createCFGSimplificationPass(1, true, true, false)); addInstructionCombiningPass(MPM); if (!DisableUnrollLoops) { Index: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp +++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp @@ -85,7 +85,6 @@ initializeIPSCCPLegacyPassPass(Registry); initializeSROALegacyPassPass(Registry); initializeCFGSimplifyPassPass(Registry); - initializeLateCFGSimplifyPassPass(Registry); initializeStructurizeCFGPass(Registry); initializeSimpleLoopUnswitchLegacyPassPass(Registry); initializeSinkingLegacyPassPass(Registry); @@ -119,11 +118,7 @@ } void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCFGSimplificationPass()); -} - -void LLVMAddLateCFGSimplificationPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createLateCFGSimplificationPass()); + unwrap(PM)->add(createCFGSimplificationPass(1, false, false, true)); } void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM) { Index: llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -45,9 +45,21 @@ #define DEBUG_TYPE "simplifycfg" -static cl::opt -UserBonusInstThreshold("bonus-inst-threshold", cl::Hidden, cl::init(1), - cl::desc("Control the number of bonus instructions (default = 1)")); +static cl::opt UserBonusInstThreshold( + "bonus-inst-threshold", cl::Hidden, cl::init(1), + cl::desc("Control the number of bonus instructions (default = 1)")); + +static cl::opt UserKeepLoops( + "keep-loops", cl::Hidden, cl::init(true), + cl::desc("Preserve canonical loop structure (default = true)")); + +static cl::opt UserSwitchToLookup( + "switch-to-lookup", cl::Hidden, cl::init(false), + cl::desc("Convert switches to lookup tables (default = false)")); + +static cl::opt UserForwardSwitchCond( + "forward-switch-cond", cl::Hidden, cl::init(false), + cl::desc("Forward switch condition to phi ops (default = false)")); STATISTIC(NumSimpl, "Number of blocks simplified"); @@ -179,13 +191,21 @@ return true; } -// FIXME: The new pass manager always creates a "late" simplifycfg pass using -// this default constructor. -SimplifyCFGPass::SimplifyCFGPass() - : Options(UserBonusInstThreshold, true, true, false) {} - -SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &PassOptions) - : Options(PassOptions) {} +// Command-line settings override compile-time settings. +SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &Opts) { + Options.BonusInstThreshold = UserBonusInstThreshold.getNumOccurrences() + ? UserBonusInstThreshold + : Opts.BonusInstThreshold; + Options.ForwardSwitchCondToPhi = UserForwardSwitchCond.getNumOccurrences() + ? UserForwardSwitchCond + : Opts.ForwardSwitchCondToPhi; + Options.ConvertSwitchToLookupTable = UserSwitchToLookup.getNumOccurrences() + ? UserSwitchToLookup + : Opts.ConvertSwitchToLookupTable; + Options.NeedCanonicalLoop = UserKeepLoops.getNumOccurrences() + ? UserKeepLoops + : Opts.NeedCanonicalLoop; +} PreservedAnalyses SimplifyCFGPass::run(Function &F, FunctionAnalysisManager &AM) { @@ -199,62 +219,49 @@ } namespace { -struct BaseCFGSimplifyPass : public FunctionPass { +struct CFGSimplifyPass : public FunctionPass { + static char ID; + SimplifyCFGOptions Options; std::function PredicateFtor; - int BonusInstThreshold; - bool ForwardSwitchCondToPhi; - bool ConvertSwitchToLookupTable; - bool KeepCanonicalLoops; - - BaseCFGSimplifyPass(int T, bool ForwardSwitchCond, bool ConvertSwitch, - bool KeepLoops, - std::function Ftor, char &ID) - : FunctionPass(ID), PredicateFtor(std::move(Ftor)), - ForwardSwitchCondToPhi(ForwardSwitchCond), - ConvertSwitchToLookupTable(ConvertSwitch), - KeepCanonicalLoops(KeepLoops) { - BonusInstThreshold = (T == -1) ? UserBonusInstThreshold : T; + + CFGSimplifyPass(unsigned Threshold = 1, bool ForwardSwitchCond = false, + bool ConvertSwitch = false, bool KeepLoops = true, + std::function Ftor = nullptr) + : FunctionPass(ID), PredicateFtor(std::move(Ftor)) { + + initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry()); + + // Check for command-line overrides of options for debug/customization. + Options.BonusInstThreshold = UserBonusInstThreshold.getNumOccurrences() + ? UserBonusInstThreshold + : Threshold; + + Options.ForwardSwitchCondToPhi = UserForwardSwitchCond.getNumOccurrences() + ? UserForwardSwitchCond + : ForwardSwitchCond; + + Options.ConvertSwitchToLookupTable = UserSwitchToLookup.getNumOccurrences() + ? UserSwitchToLookup + : ConvertSwitch; + + Options.NeedCanonicalLoop = + UserKeepLoops.getNumOccurrences() ? UserKeepLoops : KeepLoops; } + bool runOnFunction(Function &F) override { if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F))) return false; - AssumptionCache *AC = - &getAnalysis().getAssumptionCache(F); - const TargetTransformInfo &TTI = - getAnalysis().getTTI(F); - return simplifyFunctionCFG(F, TTI, - {BonusInstThreshold, ForwardSwitchCondToPhi, - ConvertSwitchToLookupTable, KeepCanonicalLoops, - AC}); + Options.AC = &getAnalysis().getAssumptionCache(F); + auto &TTI = getAnalysis().getTTI(F); + return simplifyFunctionCFG(F, TTI, Options); } - void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.addRequired(); AU.addPreserved(); } }; - -struct CFGSimplifyPass : public BaseCFGSimplifyPass { - static char ID; // Pass identification, replacement for typeid - - CFGSimplifyPass(int T = -1, - std::function Ftor = nullptr) - : BaseCFGSimplifyPass(T, false, false, true, Ftor, ID) { - initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry()); - } -}; - -struct LateCFGSimplifyPass : public BaseCFGSimplifyPass { - static char ID; // Pass identification, replacement for typeid - - LateCFGSimplifyPass(int T = -1, - std::function Ftor = nullptr) - : BaseCFGSimplifyPass(T, true, true, false, Ftor, ID) { - initializeLateCFGSimplifyPassPass(*PassRegistry::getPassRegistry()); - } -}; } char CFGSimplifyPass::ID = 0; @@ -265,24 +272,11 @@ INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false, false) -char LateCFGSimplifyPass::ID = 0; -INITIALIZE_PASS_BEGIN(LateCFGSimplifyPass, "latesimplifycfg", - "Simplify the CFG more aggressively", false, false) -INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) -INITIALIZE_PASS_END(LateCFGSimplifyPass, "latesimplifycfg", - "Simplify the CFG more aggressively", false, false) - // Public interface to the CFGSimplification pass FunctionPass * -llvm::createCFGSimplificationPass(int Threshold, - std::function Ftor) { - return new CFGSimplifyPass(Threshold, std::move(Ftor)); -} - -// Public interface to the LateCFGSimplification pass -FunctionPass * -llvm::createLateCFGSimplificationPass(int Threshold, +llvm::createCFGSimplificationPass(unsigned Threshold, bool ForwardSwitchCond, + bool ConvertSwitch, bool KeepLoops, std::function Ftor) { - return new LateCFGSimplifyPass(Threshold, std::move(Ftor)); + return new CFGSimplifyPass(Threshold, ForwardSwitchCond, ConvertSwitch, + KeepLoops, std::move(Ftor)); } Index: llvm/trunk/test/CodeGen/AArch64/cmpxchg-idioms.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/cmpxchg-idioms.ll +++ llvm/trunk/test/CodeGen/AArch64/cmpxchg-idioms.ll @@ -107,7 +107,7 @@ ; CHECK: [[FAILED]]: ; CHECK-NOT: cmp {{w[0-9]+}}, {{w[0-9]+}} -; verify the preheader is simplified by latesimplifycfg. +; verify the preheader is simplified by simplifycfg. ; CHECK: [[PH]]: ; CHECK: orr w22, wzr, #0x2 ; CHECK-NOT: orr w22, wzr, #0x4 Index: llvm/trunk/test/Transforms/LoopVectorize/X86/float-induction-x86.ll =================================================================== --- llvm/trunk/test/Transforms/LoopVectorize/X86/float-induction-x86.ll +++ llvm/trunk/test/Transforms/LoopVectorize/X86/float-induction-x86.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -O3 -latesimplifycfg -mcpu=core-avx2 -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefix AUTO_VEC %s +; RUN: opt < %s -O3 -simplifycfg -keep-loops=false -mcpu=core-avx2 -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefix AUTO_VEC %s ; This test checks auto-vectorization with FP induction variable. ; The FP operation is not "fast" and requires "fast-math" function attribute. Index: llvm/trunk/test/Transforms/LoopVectorize/float-induction.ll =================================================================== --- llvm/trunk/test/Transforms/LoopVectorize/float-induction.ll +++ llvm/trunk/test/Transforms/LoopVectorize/float-induction.ll @@ -1,7 +1,7 @@ ; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -dce -instcombine -S | FileCheck --check-prefix VEC4_INTERL1 %s ; RUN: opt < %s -loop-vectorize -force-vector-interleave=2 -force-vector-width=4 -dce -instcombine -S | FileCheck --check-prefix VEC4_INTERL2 %s ; RUN: opt < %s -loop-vectorize -force-vector-interleave=2 -force-vector-width=1 -dce -instcombine -S | FileCheck --check-prefix VEC1_INTERL2 %s -; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -dce -simplifycfg -instcombine -latesimplifycfg -S | FileCheck --check-prefix VEC2_INTERL1_PRED_STORE %s +; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -dce -simplifycfg -instcombine -simplifycfg -keep-loops=false -S | FileCheck --check-prefix VEC2_INTERL1_PRED_STORE %s @fp_inc = common global float 0.000000e+00, align 4 Index: llvm/trunk/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll @@ -1,8 +1,8 @@ -; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=static < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE -; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE -; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=ropi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE -; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE -; RUN: opt -S -latesimplifycfg -mtriple=arm -relocation-model=ropi-rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE +; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=static < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE +; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE +; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=ropi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE +; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE +; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=ropi-rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE ; CHECK: @{{.*}} = private unnamed_addr constant [3 x i32] [i32 1234, i32 5678, i32 15532] ; ENABLE: @{{.*}} = private unnamed_addr constant [3 x i32*] [i32* @c1, i32* @c2, i32* @c3] Index: llvm/trunk/test/Transforms/SimplifyCFG/CoveredLookupTable.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/CoveredLookupTable.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/CoveredLookupTable.ll @@ -1,4 +1,4 @@ -; RUN: opt -latesimplifycfg -S %s | FileCheck %s +; RUN: opt -simplifycfg -switch-to-lookup -S %s | FileCheck %s ; rdar://15268442 target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" Index: llvm/trunk/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -latesimplifycfg -S | FileCheck %s +; RUN: opt < %s -simplifycfg -forward-switch-cond=false -S | FileCheck %s --check-prefix=NO_FWD +; RUN: opt < %s -simplifycfg -forward-switch-cond=true -S | FileCheck %s --check-prefix=FWD ; PR10131 @@ -7,11 +8,31 @@ target triple = "i386-pc-linux-gnu" define i32 @t(i32 %m) nounwind readnone { -; CHECK-LABEL: @t( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[M:%.*]], 4 -; CHECK-NEXT: [[M_:%.*]] = select i1 [[SWITCH]], i32 [[M]], i32 4 -; CHECK-NEXT: ret i32 [[M_]] +; NO_FWD-LABEL: @t( +; NO_FWD-NEXT: entry: +; NO_FWD-NEXT: switch i32 [[M:%.*]], label [[SW_BB4:%.*]] [ +; NO_FWD-NEXT: i32 0, label [[RETURN:%.*]] +; NO_FWD-NEXT: i32 1, label [[SW_BB1:%.*]] +; NO_FWD-NEXT: i32 2, label [[SW_BB2:%.*]] +; NO_FWD-NEXT: i32 3, label [[SW_BB3:%.*]] +; NO_FWD-NEXT: ] +; NO_FWD: sw.bb1: +; NO_FWD-NEXT: br label [[RETURN]] +; NO_FWD: sw.bb2: +; NO_FWD-NEXT: br label [[RETURN]] +; NO_FWD: sw.bb3: +; NO_FWD-NEXT: br label [[RETURN]] +; NO_FWD: sw.bb4: +; NO_FWD-NEXT: br label [[RETURN]] +; NO_FWD: return: +; NO_FWD-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 4, [[SW_BB4]] ], [ 3, [[SW_BB3]] ], [ 2, [[SW_BB2]] ], [ 1, [[SW_BB1]] ], [ 0, [[ENTRY:%.*]] ] +; NO_FWD-NEXT: ret i32 [[RETVAL_0]] +; +; FWD-LABEL: @t( +; FWD-NEXT: entry: +; FWD-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[M:%.*]], 4 +; FWD-NEXT: [[M_:%.*]] = select i1 [[SWITCH]], i32 [[M]], i32 4 +; FWD-NEXT: ret i32 [[M_]] ; entry: switch i32 %m, label %sw.bb4 [ @@ -46,18 +67,35 @@ ; This then subsequently should allow squashing of the other trivial case blocks. define i32 @PR34471(i32 %x) { -; CHECK-LABEL: @PR34471( -; CHECK-NEXT: entry: -; CHECK-NEXT: switch i32 [[X:%.*]], label [[ELSE3:%.*]] [ -; CHECK-NEXT: i32 17, label [[RETURN:%.*]] -; CHECK-NEXT: i32 19, label [[RETURN]] -; CHECK-NEXT: i32 42, label [[RETURN]] -; CHECK-NEXT: ] -; CHECK: else3: -; CHECK-NEXT: br label [[RETURN]] -; CHECK: return: -; CHECK-NEXT: [[R:%.*]] = phi i32 [ 0, [[ELSE3]] ], [ [[X]], [[ENTRY:%.*]] ], [ [[X]], [[ENTRY]] ], [ [[X]], [[ENTRY]] ] -; CHECK-NEXT: ret i32 [[R]] +; NO_FWD-LABEL: @PR34471( +; NO_FWD-NEXT: entry: +; NO_FWD-NEXT: switch i32 [[X:%.*]], label [[ELSE3:%.*]] [ +; NO_FWD-NEXT: i32 17, label [[RETURN:%.*]] +; NO_FWD-NEXT: i32 19, label [[IF19:%.*]] +; NO_FWD-NEXT: i32 42, label [[IF42:%.*]] +; NO_FWD-NEXT: ] +; NO_FWD: if19: +; NO_FWD-NEXT: br label [[RETURN]] +; NO_FWD: if42: +; NO_FWD-NEXT: br label [[RETURN]] +; NO_FWD: else3: +; NO_FWD-NEXT: br label [[RETURN]] +; NO_FWD: return: +; NO_FWD-NEXT: [[R:%.*]] = phi i32 [ [[X]], [[IF19]] ], [ [[X]], [[IF42]] ], [ 0, [[ELSE3]] ], [ 17, [[ENTRY:%.*]] ] +; NO_FWD-NEXT: ret i32 [[R]] +; +; FWD-LABEL: @PR34471( +; FWD-NEXT: entry: +; FWD-NEXT: switch i32 [[X:%.*]], label [[ELSE3:%.*]] [ +; FWD-NEXT: i32 17, label [[RETURN:%.*]] +; FWD-NEXT: i32 19, label [[RETURN]] +; FWD-NEXT: i32 42, label [[RETURN]] +; FWD-NEXT: ] +; FWD: else3: +; FWD-NEXT: br label [[RETURN]] +; FWD: return: +; FWD-NEXT: [[R:%.*]] = phi i32 [ 0, [[ELSE3]] ], [ [[X]], [[ENTRY:%.*]] ], [ [[X]], [[ENTRY]] ], [ [[X]], [[ENTRY]] ] +; FWD-NEXT: ret i32 [[R]] ; entry: switch i32 %x, label %else3 [ Index: llvm/trunk/test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll @@ -1,6 +1,7 @@ -; RUN: opt < %s -latesimplifycfg -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s -; In the presence of "-no-jump-tables"="true", late simplifycfg should not -; convert any switch cases to lookup tables. +; RUN: opt < %s -simplifycfg -switch-to-lookup -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s + +; In the presence of "-no-jump-tables"="true", simplifycfg should not convert switches to lookup tables. + ; CHECK: @switch.table.bar = private unnamed_addr constant [4 x i32] [i32 55, i32 123, i32 0, i32 -1] ; CHECK-LABEL: foo ; CHECK-NOT: @switch.table.foo = private unnamed_addr constant [4 x i32] [i32 55, i32 123, i32 0, i32 -1] Index: llvm/trunk/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -latesimplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s +; RUN: opt -S -simplifycfg -switch-to-lookup < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s ; rdar://17887153 target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin12.0.0" Index: llvm/trunk/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -latesimplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s +; RUN: opt -S -simplifycfg -switch-to-lookup < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s ; rdar://17735071 target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin12.0.0" Index: llvm/trunk/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -latesimplifycfg -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s +; RUN: opt < %s -simplifycfg -switch-to-lookup=true -keep-loops=false -S -mtriple=x86_64-unknown-linux-gnu | 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-S128" target triple = "x86_64-unknown-linux-gnu" Index: llvm/trunk/test/Transforms/SimplifyCFG/multiple-phis.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/multiple-phis.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/multiple-phis.ll @@ -1,4 +1,4 @@ -; RUN: opt -latesimplifycfg -S < %s | FileCheck %s +; RUN: opt -simplifycfg -keep-loops=false -S < %s | FileCheck %s ; It's not worthwhile to if-convert one of the phi nodes and leave ; the other behind, because that still requires a branch. If Index: llvm/trunk/test/Transforms/SimplifyCFG/preserve-llvm-loop-metadata.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/preserve-llvm-loop-metadata.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/preserve-llvm-loop-metadata.ll @@ -1,4 +1,4 @@ -; RUN: opt -latesimplifycfg -S < %s | FileCheck %s +; RUN: opt -simplifycfg -keep-loops=false -S < %s | FileCheck %s define void @test1(i32 %n) #0 { entry: Index: llvm/trunk/test/Transforms/SimplifyCFG/rangereduce.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/rangereduce.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/rangereduce.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -latesimplifycfg -S | FileCheck %s +; RUN: opt < %s -simplifycfg -switch-to-lookup -S | FileCheck %s target datalayout = "e-n32"