]> granicus.if.org Git - llvm/commitdiff
[SimplifyCFG] use pass options and remove the latesimplifycfg pass
authorSanjay Patel <spatel@rotateright.com>
Sat, 28 Oct 2017 18:43:07 +0000 (18:43 +0000)
committerSanjay Patel <spatel@rotateright.com>
Sat, 28 Oct 2017 18:43:07 +0000 (18:43 +0000)
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

25 files changed:
include/llvm-c/Transforms/Scalar.h
include/llvm/InitializePasses.h
include/llvm/LinkAllPasses.h
include/llvm/Transforms/Scalar.h
include/llvm/Transforms/Scalar/SimplifyCFG.h
include/llvm/Transforms/Utils/Local.h
lib/LTO/LTOCodeGenerator.cpp
lib/Target/AArch64/AArch64TargetMachine.cpp
lib/Target/ARM/ARMTargetMachine.cpp
lib/Transforms/IPO/PassManagerBuilder.cpp
lib/Transforms/Scalar/Scalar.cpp
lib/Transforms/Scalar/SimplifyCFGPass.cpp
test/CodeGen/AArch64/cmpxchg-idioms.ll
test/Transforms/LoopVectorize/X86/float-induction-x86.ll
test/Transforms/LoopVectorize/float-induction.ll
test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll
test/Transforms/SimplifyCFG/CoveredLookupTable.ll
test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll
test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll
test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll
test/Transforms/SimplifyCFG/X86/switch-table-bug.ll
test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
test/Transforms/SimplifyCFG/multiple-phis.ll
test/Transforms/SimplifyCFG/preserve-llvm-loop-metadata.ll
test/Transforms/SimplifyCFG/rangereduce.ll

index b9612b9cec0443dc1761b68096bd4e3bbea46654..8991e0904849cd84851eb538147acc4218638464 100644 (file)
@@ -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);
 
index 6b0e6acadad9596e1c9caae4ab9f1f780a04846d..c3ad8fe41af8092e0508709796870d4a92fae141 100644 (file)
@@ -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&);
index abc3bac9367367754b14e02e05e47c07d0813a61..765e63926daec8b65b2f60d634acaee722dde45d 100644 (file)
@@ -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();
index d9a10c086d9808af1a2e62d49c1b4ad4e9cd084b..8ef65774a93ef934a3375d382a02b4afd78d2c93 100644 (file)
@@ -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<bool(const Function &)> Ftor = nullptr);
-
-//===----------------------------------------------------------------------===//
-//
-// LateCFGSimplification - Like CFGSimplification, but may also
-// convert switches to lookup tables.
-//
-FunctionPass *createLateCFGSimplificationPass(
-    int Threshold = -1, std::function<bool(const Function &)> Ftor = nullptr);
+    unsigned Threshold = 1, bool ForwardSwitchCond = false,
+    bool ConvertSwitch = false, bool KeepLoops = true,
+    std::function<bool(const Function &)> Ftor = nullptr);
 
 //===----------------------------------------------------------------------===//
 //
index ef47fa8e684a14eabbd1c7d1f16b3e75904731e9..e955673283ec448cfb00362cfddeb952b2f254a6 100644 (file)
@@ -31,8 +31,16 @@ class SimplifyCFGPass : public PassInfoMixin<SimplifyCFGPass> {
   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 fe344a7fac6783933aea6391aa54a82fa0a7ad47..8d54ef3436aab68f9ab90fe943587b2dca8aacc4 100644 (file)
@@ -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;
+  }
 };
 
 //===----------------------------------------------------------------------===//
index ba5c04d5b1a835c18a76d160653f0523d1dbdfca..9759c0c6c1d9830f0fa5901024587cd008b84f70 100644 (file)
@@ -131,7 +131,6 @@ void LTOCodeGenerator::initializeLTOPasses() {
   initializeMemCpyOptLegacyPassPass(R);
   initializeDCELegacyPassPass(R);
   initializeCFGSimplifyPassPass(R);
-  initializeLateCFGSimplifyPassPass(R);
 }
 
 void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
index 1762475ac93fabd505922be84c6c348ff25c9fcd..daf4e22c15bff73ba1575bf2126961c182f17ccf 100644 (file)
@@ -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
   //
index 39b8df401aa57bac2bca155f7e3716c693819383..1d1bb5d1de43bc48c131391d731c74b9a3049eb3 100644 (file)
@@ -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<ARMSubtarget>(F);
-      return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
-    }));
+    addPass(createCFGSimplificationPass(
+        1, false, false, true, [this](const Function &F) {
+          const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F);
+          return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
+        }));
 
   TargetPassConfig::addIRPasses();
 
index 35ca107c3259f4d77cda43b1e24756be3fda18e8..bb15cf510c778c039e1b79e0bcb89c80dec36bf2 100644 (file)
@@ -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) {
index ba7a6fe937780cda99fa93c2603f29c587fe68f3..c1034ace20685952397c3709e84c1b761c554fbd 100644 (file)
@@ -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) {
index 6f38e5d11b58b66d6375650effd18dc7bb5218eb..789e0a477932852ae5e579d9871266e520b077b1 100644 (file)
@@ -45,9 +45,21 @@ using namespace llvm;
 
 #define DEBUG_TYPE "simplifycfg"
 
-static cl::opt<unsigned>
-UserBonusInstThreshold("bonus-inst-threshold", cl::Hidden, cl::init(1),
-   cl::desc("Control the number of bonus instructions (default = 1)"));
+static cl::opt<unsigned> UserBonusInstThreshold(
+    "bonus-inst-threshold", cl::Hidden, cl::init(1),
+    cl::desc("Control the number of bonus instructions (default = 1)"));
+
+static cl::opt<bool> UserKeepLoops(
+    "keep-loops", cl::Hidden, cl::init(true),
+    cl::desc("Preserve canonical loop structure (default = true)"));
+
+static cl::opt<bool> UserSwitchToLookup(
+    "switch-to-lookup", cl::Hidden, cl::init(false),
+    cl::desc("Convert switches to lookup tables (default = false)"));
+
+static cl::opt<bool> 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<bool(const Function &)> PredicateFtor;
-  int BonusInstThreshold;
-  bool ForwardSwitchCondToPhi;
-  bool ConvertSwitchToLookupTable;
-  bool KeepCanonicalLoops;
-
-  BaseCFGSimplifyPass(int T, bool ForwardSwitchCond, bool ConvertSwitch,
-                      bool KeepLoops,
-                      std::function<bool(const 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<bool(const 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<AssumptionCacheTracker>().getAssumptionCache(F);
-    const TargetTransformInfo &TTI =
-        getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
-    return simplifyFunctionCFG(F, TTI,
-                               {BonusInstThreshold, ForwardSwitchCondToPhi,
-                                ConvertSwitchToLookupTable, KeepCanonicalLoops,
-                                AC});
+    Options.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+    auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+    return simplifyFunctionCFG(F, TTI, Options);
   }
-
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<AssumptionCacheTracker>();
     AU.addRequired<TargetTransformInfoWrapperPass>();
     AU.addPreserved<GlobalsAAWrapperPass>();
   }
 };
-
-struct CFGSimplifyPass : public BaseCFGSimplifyPass {
-  static char ID; // Pass identification, replacement for typeid
-
-  CFGSimplifyPass(int T = -1,
-                  std::function<bool(const 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<bool(const 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<bool(const 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<bool(const Function &)> Ftor) {
-  return new LateCFGSimplifyPass(Threshold, std::move(Ftor));
+  return new CFGSimplifyPass(Threshold, ForwardSwitchCond, ConvertSwitch,
+                             KeepLoops, std::move(Ftor));
 }
index cae09b289797ae17b68d36efc3d0e06c959336d4..da0f7073acefba5e522cf43027f976dfa1673d37 100644 (file)
@@ -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
index bf455807c5862c28dcd642eb282d2375973be171..af4a48d3a22a0d521b225b5db917b88ca1662786 100644 (file)
@@ -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 cf6ec88478befd2fc8ac09a7e237faa728060747..a8b66f44ffa5aab7cdf7ae98658813eb1b4111ee 100644 (file)
@@ -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 90a9aa4d95b7dde979c0be159f0a0a1cbac7d7c2..ce86c0a5735c457a0c5cd2471fbff81020d4922a 100644 (file)
@@ -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 a42349e3d874219f168af9e55fb5349c23fce504..acf40c46e024717a51722723fb87fae172047ec2 100644 (file)
@@ -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 4dcccef03d887a0b4efe93e582b0ad40592aed9d..f7910768c163e8d7fab7b4213b864746fe7c6f6a 100644 (file)
@@ -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 [
index c775389d6903fb5fe4b8829c5716a2e3be4545e3..33949fd4706bfea7a11c26867de539dc0e22f28f 100644 (file)
@@ -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 e335c4078651fe46ecfea0d13f63880e867631c8..345f2d3dd664f7482003481d355e8e7815a97bb3 100644 (file)
@@ -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 bd4e03cf91827869267cf4625a0c08e6c17ae7f4..fc8f2a6358d17ba749e160de70ae6d984c93964e 100644 (file)
@@ -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 e61e9153b797a924a9e042b663414e601162dc7b..7766049e553ce40956e092203b10451f18beeefe 100644 (file)
@@ -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 823e2500eac1eafb4967c472374fb367edd85083..fa32bb9220bca6d516ff08608b76ff5989b9c8aa 100644 (file)
@@ -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 e357104f2a66e41259cc995cb0ca301179e0faf5..5e5a2c36e462385d4913116a080b91d0d8b0fc74 100644 (file)
@@ -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 62b2b7a72e800e822e54ca38f938ceb7df6d18fd..930a679739ad16b6fffa4dfd0f72858107d1602a 100644 (file)
@@ -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"