From: Sanjay Patel Date: Sat, 28 Oct 2017 18:43:07 +0000 (+0000) Subject: [SimplifyCFG] use pass options and remove the latesimplifycfg pass X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=72428f5e04d2f58ca4b3f3e4ff3a655bca6ebaa6;p=llvm [SimplifyCFG] use pass options and remove the latesimplifycfg pass This is no-functional-change-intended. This is repackaging the functionality of D30333 (defer switch-to-lookup-tables) and D35411 (defer folding unconditional branches) with pass parameters rather than a named "latesimplifycfg" pass. Now that we have individual options to control the functionality, we could decouple when these fire (but that's an independent patch if desired). The next planned step would be to add another option bit to disable the sinking transform mentioned in D38566. This should also make it clear that the new pass manager needs to be updated to limit simplifycfg in the same way as the old pass manager. Differential Revision: https://reviews.llvm.org/D38631 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316835 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm-c/Transforms/Scalar.h b/include/llvm-c/Transforms/Scalar.h index b9612b9cec0..8991e090484 100644 --- a/include/llvm-c/Transforms/Scalar.h +++ b/include/llvm-c/Transforms/Scalar.h @@ -44,9 +44,6 @@ void LLVMAddAlignmentFromAssumptionsPass(LLVMPassManagerRef PM); /** See llvm::createCFGSimplificationPass function. */ void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM); -/** See llvm::createLateCFGSimplificationPass function. */ -void LLVMAddLateCFGSimplificationPass(LLVMPassManagerRef PM); - /** See llvm::createDeadStoreEliminationPass function. */ void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM); diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 6b0e6acadad..c3ad8fe41af 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -174,7 +174,6 @@ void initializeIntervalPartitionPass(PassRegistry&); void initializeJumpThreadingPass(PassRegistry&); void initializeLCSSAVerificationPassPass(PassRegistry&); void initializeLCSSAWrapperPassPass(PassRegistry&); -void initializeLateCFGSimplifyPassPass(PassRegistry&); void initializeLazyBlockFrequencyInfoPassPass(PassRegistry&); void initializeLazyBranchProbabilityInfoPassPass(PassRegistry&); void initializeLazyMachineBlockFrequencyInfoPassPass(PassRegistry&); diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index abc3bac9367..765e63926da 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -75,7 +75,6 @@ namespace { (void) llvm::createCallGraphDOTPrinterPass(); (void) llvm::createCallGraphViewerPass(); (void) llvm::createCFGSimplificationPass(); - (void) llvm::createLateCFGSimplificationPass(); (void) llvm::createCFLAndersAAWrapperPass(); (void) llvm::createCFLSteensAAWrapperPass(); (void) llvm::createStructurizeCFGPass(); diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index d9a10c086d9..8ef65774a93 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -255,18 +255,12 @@ FunctionPass *createJumpThreadingPass(int Threshold = -1); //===----------------------------------------------------------------------===// // // 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); //===----------------------------------------------------------------------===// // diff --git a/include/llvm/Transforms/Scalar/SimplifyCFG.h b/include/llvm/Transforms/Scalar/SimplifyCFG.h index ef47fa8e684..e955673283e 100644 --- a/include/llvm/Transforms/Scalar/SimplifyCFG.h +++ b/include/llvm/Transforms/Scalar/SimplifyCFG.h @@ -31,8 +31,16 @@ class SimplifyCFGPass : public PassInfoMixin { 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); diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index fe344a7fac6..8d54ef3436a 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -65,13 +65,36 @@ struct SimplifyCFGOptions { 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; + } }; //===----------------------------------------------------------------------===// diff --git a/lib/LTO/LTOCodeGenerator.cpp b/lib/LTO/LTOCodeGenerator.cpp index ba5c04d5b1a..9759c0c6c1d 100644 --- a/lib/LTO/LTOCodeGenerator.cpp +++ b/lib/LTO/LTOCodeGenerator.cpp @@ -131,7 +131,6 @@ void LTOCodeGenerator::initializeLTOPasses() { initializeMemCpyOptLegacyPassPass(R); initializeDCELegacyPassPass(R); initializeCFGSimplifyPassPass(R); - initializeLateCFGSimplifyPassPass(R); } void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) { diff --git a/lib/Target/AArch64/AArch64TargetMachine.cpp b/lib/Target/AArch64/AArch64TargetMachine.cpp index 1762475ac93..daf4e22c15b 100644 --- a/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -365,7 +365,7 @@ void AArch64PassConfig::addIRPasses() { // 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 // diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index 39b8df401aa..1d1bb5d1de4 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -384,10 +384,11 @@ void ARMPassConfig::addIRPasses() { // 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(); diff --git a/lib/Transforms/IPO/PassManagerBuilder.cpp b/lib/Transforms/IPO/PassManagerBuilder.cpp index 35ca107c325..bb15cf510c7 100644 --- a/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -625,7 +625,9 @@ void PassManagerBuilder::populateModulePassManager( } 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) { diff --git a/lib/Transforms/Scalar/Scalar.cpp b/lib/Transforms/Scalar/Scalar.cpp index ba7a6fe9377..c1034ace206 100644 --- a/lib/Transforms/Scalar/Scalar.cpp +++ b/lib/Transforms/Scalar/Scalar.cpp @@ -85,7 +85,6 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) { initializeIPSCCPLegacyPassPass(Registry); initializeSROALegacyPassPass(Registry); initializeCFGSimplifyPassPass(Registry); - initializeLateCFGSimplifyPassPass(Registry); initializeStructurizeCFGPass(Registry); initializeSimpleLoopUnswitchLegacyPassPass(Registry); initializeSinkingLegacyPassPass(Registry); @@ -119,11 +118,7 @@ void LLVMAddAlignmentFromAssumptionsPass(LLVMPassManagerRef PM) { } 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) { diff --git a/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/lib/Transforms/Scalar/SimplifyCFGPass.cpp index 6f38e5d11b5..789e0a47793 100644 --- a/lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ b/lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -45,9 +45,21 @@ using namespace llvm; #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 @@ static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI, 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 @@ PreservedAnalyses SimplifyCFGPass::run(Function &F, } 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_DEPENDENCY(AssumptionCacheTracker) 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)); } diff --git a/test/CodeGen/AArch64/cmpxchg-idioms.ll b/test/CodeGen/AArch64/cmpxchg-idioms.ll index cae09b28979..da0f7073ace 100644 --- a/test/CodeGen/AArch64/cmpxchg-idioms.ll +++ b/test/CodeGen/AArch64/cmpxchg-idioms.ll @@ -107,7 +107,7 @@ define i1 @test_conditional2(i32 %a, i32 %b, i32* %c) { ; 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 diff --git a/test/Transforms/LoopVectorize/X86/float-induction-x86.ll b/test/Transforms/LoopVectorize/X86/float-induction-x86.ll index bf455807c58..af4a48d3a22 100644 --- a/test/Transforms/LoopVectorize/X86/float-induction-x86.ll +++ b/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. diff --git a/test/Transforms/LoopVectorize/float-induction.ll b/test/Transforms/LoopVectorize/float-induction.ll index cf6ec88478b..a8b66f44ffa 100644 --- a/test/Transforms/LoopVectorize/float-induction.ll +++ b/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 diff --git a/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll b/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll index 90a9aa4d95b..ce86c0a5735 100644 --- a/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll +++ b/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] diff --git a/test/Transforms/SimplifyCFG/CoveredLookupTable.ll b/test/Transforms/SimplifyCFG/CoveredLookupTable.ll index a42349e3d87..acf40c46e02 100644 --- a/test/Transforms/SimplifyCFG/CoveredLookupTable.ll +++ b/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" diff --git a/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll b/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll index 4dcccef03d8..f7910768c16 100644 --- a/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll +++ b/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 datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3 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 @@ return: ; preds = %entry, %sw.bb4, %sw ; 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 [ diff --git a/test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll b/test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll index c775389d690..33949fd4706 100644 --- a/test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll +++ b/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] diff --git a/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll b/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll index e335c407865..345f2d3dd66 100644 --- a/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll +++ b/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" diff --git a/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll b/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll index bd4e03cf918..fc8f2a6358d 100644 --- a/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll +++ b/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" diff --git a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll index e61e9153b79..7766049e553 100644 --- a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll +++ b/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" diff --git a/test/Transforms/SimplifyCFG/multiple-phis.ll b/test/Transforms/SimplifyCFG/multiple-phis.ll index 823e2500eac..fa32bb9220b 100644 --- a/test/Transforms/SimplifyCFG/multiple-phis.ll +++ b/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 diff --git a/test/Transforms/SimplifyCFG/preserve-llvm-loop-metadata.ll b/test/Transforms/SimplifyCFG/preserve-llvm-loop-metadata.ll index e357104f2a6..5e5a2c36e46 100644 --- a/test/Transforms/SimplifyCFG/preserve-llvm-loop-metadata.ll +++ b/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: diff --git a/test/Transforms/SimplifyCFG/rangereduce.ll b/test/Transforms/SimplifyCFG/rangereduce.ll index 62b2b7a72e8..930a679739a 100644 --- a/test/Transforms/SimplifyCFG/rangereduce.ll +++ b/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"