]> granicus.if.org Git - llvm/commitdiff
[CodeGen] Replace -max-jump-table-size with -max-jump-table-targets
authorEvandro Menezes <e.menezes@samsung.com>
Wed, 25 Sep 2019 16:10:20 +0000 (16:10 +0000)
committerEvandro Menezes <e.menezes@samsung.com>
Wed, 25 Sep 2019 16:10:20 +0000 (16:10 +0000)
Modern processors predict the targets of an indirect branch regardless of
the size of any jump table used to glean its target address.  Moreover,
branch predictors typically use resources limited by the number of actual
targets that occur at run time.

This patch changes the semantics of the option `-max-jump-table-size` to limit
the number of different targets instead of the number of entries in a jump
table.  Thus, it is now renamed to `-max-jump-table-targets`.

Before, when `-max-jump-table-size` was specified, it could happen that
cluster jump tables could have targets used repeatedly, but each one was
counted and typically resulted in tables with the same number of entries.
With this patch, when specifying `-max-jump-table-targets`, tables may have
different lengths, since the number of unique targets is counted towards the
limit, but the number of unique targets in tables is the same, but for the
last one containing the balance of targets.

Differential revision: https://reviews.llvm.org/D60295

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372893 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/BasicTTIImpl.h
include/llvm/CodeGen/SwitchLoweringUtils.h
include/llvm/CodeGen/TargetLowering.h
lib/CodeGen/SwitchLoweringUtils.cpp
lib/CodeGen/TargetLoweringBase.cpp
lib/Target/AArch64/AArch64ISelLowering.cpp
lib/Target/AArch64/AArch64Subtarget.cpp
lib/Target/AArch64/AArch64Subtarget.h
test/CodeGen/AArch64/max-jump-table.ll

index 75e0f844fd07597ff964cab3582ab2fbc8600023..8473eb8ebb290e244dc08c6044bc9c03867b10f8 100644 (file)
@@ -373,7 +373,7 @@ public:
           (MaxCaseVal - MinCaseVal)
               .getLimitedValue(std::numeric_limits<uint64_t>::max() - 1) + 1;
       // Check whether a range of clusters is dense enough for a jump table
-      if (TLI->isSuitableForJumpTable(&SI, N, Range)) {
+      if (TLI->isSuitableForJumpTable(&SI, N, 0, Range)) {
         JumpTableSize = Range;
         return 1;
       }
index 31b5f794d90c699828b6e830b06bf46bc35c6ca8..ef87c86dfb0a3d687bdcde74295b83700ed75885 100644 (file)
@@ -221,14 +221,6 @@ struct BitTestBlock {
         Cases(std::move(C)), Prob(Pr) {}
 };
 
-/// Return the range of values within a range.
-uint64_t getJumpTableRange(const CaseClusterVector &Clusters, unsigned First,
-                           unsigned Last);
-
-/// Return the number of cases within a range.
-uint64_t getJumpTableNumCases(const SmallVectorImpl<unsigned> &TotalCases,
-                              unsigned First, unsigned Last);
-
 struct SwitchWorkListItem {
   MachineBasicBlock *MBB;
   CaseClusterIt FirstCluster;
index 608692fcb57cca3b9b2a4c148ab0052175eb6a0f..42d9341210d73caa76c5d6421b64d39e01801d41 100644 (file)
@@ -1022,8 +1022,10 @@ public:
   }
 
   /// Return true if lowering to a jump table is suitable for a set of case
-  /// clusters which may contain \p NumCases cases, \p Range range of values.
-  virtual bool isSuitableForJumpTable(const SwitchInst *SI, uint64_t NumCases,
+  /// clusters which may contain \p NumCases cases, \p Range range of values,
+  /// \p NumTargets targets.
+  virtual bool isSuitableForJumpTable(const SwitchInst *SI,
+                                      uint64_t NumCases, uint64_t NumTargets,
                                       uint64_t Range) const {
     // FIXME: This function check the maximum table size and density, but the
     // minimum size is not checked. It would be nice if the minimum size is
@@ -1032,14 +1034,14 @@ public:
     // getEstimatedNumberOfCaseClusters() in BasicTTIImpl.
     const bool OptForSize = SI->getParent()->getParent()->hasOptSize();
     const unsigned MinDensity = getMinimumJumpTableDensity(OptForSize);
-    const unsigned MaxJumpTableSize = getMaximumJumpTableSize();
-    
-    // Check whether the number of cases is small enough and
+    const unsigned MaxJumpTableTargets = getMaximumJumpTableTargets();
+
+    // Check whether the number of targets is small enough and
     // the range is dense enough for a jump table.
-    if ((OptForSize || Range <= MaxJumpTableSize) &&
-        (NumCases * 100 >= Range * MinDensity)) {
+    if ((OptForSize || NumTargets <= MaxJumpTableTargets) &&
+        NumCases * 100 >= Range * MinDensity)
       return true;
-    }
+
     return false;
   }
 
@@ -1542,9 +1544,8 @@ public:
   /// Return lower limit of the density in a jump table.
   unsigned getMinimumJumpTableDensity(bool OptForSize) const;
 
-  /// Return upper limit for number of entries in a jump table.
-  /// Zero if no limit.
-  unsigned getMaximumJumpTableSize() const;
+  /// Return upper limit for number of targets in a jump table.
+  unsigned getMaximumJumpTableTargets() const;
 
   virtual bool isJumpTableRelative() const {
     return TM.isPositionIndependent();
@@ -1951,9 +1952,8 @@ protected:
   /// Indicate the minimum number of blocks to generate jump tables.
   void setMinimumJumpTableEntries(unsigned Val);
 
-  /// Indicate the maximum number of entries in jump tables.
-  /// Set to zero to generate unlimited jump tables.
-  void setMaximumJumpTableSize(unsigned);
+  /// Indicate the maximum number of targets in jump tables.
+  void setMaximumJumpTableTargets(unsigned);
 
   /// If set to a physical register, this specifies the register that
   /// llvm.savestack/llvm.restorestack should save and restore.
index 83acf7f80715beb6edffb1711d2210a36174fa70..2b9999d0b41b106cb16bf8f93b64c8ba237ef6f5 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/SwitchLoweringUtils.h"
 
 using namespace llvm;
 using namespace SwitchCG;
 
-uint64_t SwitchCG::getJumpTableRange(const CaseClusterVector &Clusters,
-                                     unsigned First, unsigned Last) {
-  assert(Last >= First);
-  const APInt &LowCase = Clusters[First].Low->getValue();
-  const APInt &HighCase = Clusters[Last].High->getValue();
-  assert(LowCase.getBitWidth() == HighCase.getBitWidth());
-
-  // FIXME: A range of consecutive cases has 100% density, but only requires one
-  // comparison to lower. We should discriminate against such consecutive ranges
-  // in jump tables.
-  return (HighCase - LowCase).getLimitedValue((UINT64_MAX - 1) / 100) + 1;
-}
+// Collection of partition stats, made up of, for a given cluster,
+// the range of the cases, their number and the number of unique targets.
+struct PartitionStats {
+  uint64_t Range, Cases, Targets;
+};
+
+static PartitionStats getJumpTableStats(const CaseClusterVector &Clusters,
+                                        unsigned First, unsigned Last,
+                                        bool HasReachableDefault) {
+  assert(Last >= First && "Invalid order of clusters");
+
+  SmallSet<const MachineBasicBlock *, 8> Targets;
+  PartitionStats Stats;
+
+  Stats.Cases = 0;
+  for (unsigned i = First; i <= Last; ++i) {
+    const APInt &Hi = Clusters[i].High->getValue(),
+                &Lo = Clusters[i].Low->getValue();
+    Stats.Cases += (Hi - Lo).getLimitedValue() + 1;
+
+    Targets.insert(Clusters[i].MBB);
+  }
+  assert(Stats.Cases < UINT64_MAX / 100 && "Too many cases");
+
+  const APInt &Hi = Clusters[Last].High->getValue(),
+              &Lo = Clusters[First].Low->getValue();
+  assert(Hi.getBitWidth() == Lo.getBitWidth());
+  Stats.Range = (Hi - Lo).getLimitedValue((UINT64_MAX - 1) / 100) + 1;
+  assert(Stats.Range >= Stats.Cases && "Invalid range or number of cases");
+
+  Stats.Targets =
+      Targets.size() + (HasReachableDefault && Stats.Range > Stats.Cases);
 
-uint64_t
-SwitchCG::getJumpTableNumCases(const SmallVectorImpl<unsigned> &TotalCases,
-                               unsigned First, unsigned Last) {
-  assert(Last >= First);
-  assert(TotalCases[Last] >= TotalCases[First]);
-  uint64_t NumCases =
-      TotalCases[Last] - (First == 0 ? 0 : TotalCases[First - 1]);
-  return NumCases;
+  return Stats;
 }
 
 void SwitchCG::SwitchLowering::findJumpTables(CaseClusterVector &Clusters,
@@ -64,23 +78,13 @@ void SwitchCG::SwitchLowering::findJumpTables(CaseClusterVector &Clusters,
   if (N < 2 || N < MinJumpTableEntries)
     return;
 
-  // Accumulated number of cases in each cluster and those prior to it.
-  SmallVector<unsigned, 8> TotalCases(N);
-  for (unsigned i = 0; i < N; ++i) {
-    const APInt &Hi = Clusters[i].High->getValue();
-    const APInt &Lo = Clusters[i].Low->getValue();
-    TotalCases[i] = (Hi - Lo).getLimitedValue() + 1;
-    if (i != 0)
-      TotalCases[i] += TotalCases[i - 1];
-  }
-
-  uint64_t Range = getJumpTableRange(Clusters,0, N - 1);
-  uint64_t NumCases = getJumpTableNumCases(TotalCases, 0, N - 1);
-  assert(NumCases < UINT64_MAX / 100);
-  assert(Range >= NumCases);
+  const bool HasReachableDefault =
+      !isa<UnreachableInst>(DefaultMBB->getBasicBlock()->getFirstNonPHIOrDbg());
+  PartitionStats Stats =
+      getJumpTableStats(Clusters, 0, N - 1, HasReachableDefault);
 
   // Cheap case: the whole range may be suitable for jump table.
-  if (TLI->isSuitableForJumpTable(SI, NumCases, Range)) {
+  if (TLI->isSuitableForJumpTable(SI, Stats.Cases, Stats.Targets, Stats.Range)) {
     CaseCluster JTCluster;
     if (buildJumpTable(Clusters, 0, N - 1, SI, DefaultMBB, JTCluster)) {
       Clusters[0] = JTCluster;
@@ -104,9 +108,6 @@ void SwitchCG::SwitchLowering::findJumpTables(CaseClusterVector &Clusters,
   SmallVector<unsigned, 8> MinPartitions(N);
   // LastElement[i] is the last element of the partition starting at i.
   SmallVector<unsigned, 8> LastElement(N);
-  // PartitionsScore[i] is used to break ties when choosing between two
-  // partitionings resulting in the same number of partitions.
-  SmallVector<unsigned, 8> PartitionsScore(N);
   // For PartitionsScore, a small number of comparisons is considered as good as
   // a jump table and a single comparison is considered better than a jump
   // table.
@@ -116,6 +117,11 @@ void SwitchCG::SwitchLowering::findJumpTables(CaseClusterVector &Clusters,
     FewCases = 1,
     SingleCase = 2
   };
+  // PartitionsScore[i] is used to break ties when choosing between two
+  // partitionings resulting in the same number of partitions.
+  SmallVector<unsigned, 8> PartitionsScore(N);
+  // PartitionsStats[j] is the stats for the partition Clusters[i..j].
+  SmallVector<PartitionStats, 8> PartitionsStats(N);
 
   // Base case: There is only one way to partition Clusters[N-1].
   MinPartitions[N - 1] = 1;
@@ -129,16 +135,16 @@ void SwitchCG::SwitchLowering::findJumpTables(CaseClusterVector &Clusters,
     MinPartitions[i] = MinPartitions[i + 1] + 1;
     LastElement[i] = i;
     PartitionsScore[i] = PartitionsScore[i + 1] + PartitionScores::SingleCase;
+    for (int64_t j = i + 1; j < N; j++)
+      PartitionsStats[j] =
+          getJumpTableStats(Clusters, i, j, HasReachableDefault);
 
     // Search for a solution that results in fewer partitions.
     for (int64_t j = N - 1; j > i; j--) {
       // Try building a partition from Clusters[i..j].
-      Range = getJumpTableRange(Clusters, i, j);
-      NumCases = getJumpTableNumCases(TotalCases, i, j);
-      assert(NumCases < UINT64_MAX / 100);
-      assert(Range >= NumCases);
-
-      if (TLI->isSuitableForJumpTable(SI, NumCases, Range)) {
+      if (TLI->isSuitableForJumpTable(SI, PartitionsStats[j].Cases,
+                                      PartitionsStats[j].Targets,
+                                      PartitionsStats[j].Range)) {
         unsigned NumPartitions = 1 + (j == N - 1 ? 0 : MinPartitions[j + 1]);
         unsigned Score = j == N - 1 ? 0 : PartitionsScore[j + 1];
         int64_t NumEntries = j - i + 1;
index 0eb10a11042160d7caa0b0436d73a663be58e9ee..557df03784d7859bbe796d3aba2bf11691225d87 100644 (file)
@@ -72,9 +72,9 @@ static cl::opt<unsigned> MinimumJumpTableEntries
   ("min-jump-table-entries", cl::init(4), cl::Hidden,
    cl::desc("Set minimum number of entries to use a jump table."));
 
-static cl::opt<unsigned> MaximumJumpTableSize
-  ("max-jump-table-size", cl::init(UINT_MAX), cl::Hidden,
-   cl::desc("Set maximum size of jump tables."));
+static cl::opt<unsigned> MaximumJumpTableTargets
+  ("max-jump-table-targets", cl::init(UINT_MAX), cl::Hidden,
+   cl::desc("Set maximum number of targets to use in a jump table."));
 
 /// Minimum jump table density for normal functions.
 static cl::opt<unsigned>
@@ -1778,16 +1778,16 @@ void TargetLoweringBase::setMinimumJumpTableEntries(unsigned Val) {
   MinimumJumpTableEntries = Val;
 }
 
-unsigned TargetLoweringBase::getMinimumJumpTableDensity(bool OptForSize) const {
-  return OptForSize ? OptsizeJumpTableDensity : JumpTableDensity;
+unsigned TargetLoweringBase::getMaximumJumpTableTargets() const {
+  return MaximumJumpTableTargets;
 }
 
-unsigned TargetLoweringBase::getMaximumJumpTableSize() const {
-  return MaximumJumpTableSize;
+void TargetLoweringBase::setMaximumJumpTableTargets(unsigned Val) {
+  MaximumJumpTableTargets = Val;
 }
 
-void TargetLoweringBase::setMaximumJumpTableSize(unsigned Val) {
-  MaximumJumpTableSize = Val;
+unsigned TargetLoweringBase::getMinimumJumpTableDensity(bool OptForSize) const {
+  return OptForSize ? OptsizeJumpTableDensity : JumpTableDensity;
 }
 
 //===----------------------------------------------------------------------===//
index ae09714395a8e2e6923c94ea532b7089d4ca4f3e..9628000b477dafd349fd5b2db1e2c985280e1f36 100644 (file)
@@ -647,11 +647,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
   setPrefFunctionAlignment(
       llvm::Align(1ULL << STI.getPrefFunctionLogAlignment()));
 
-  // Only change the limit for entries in a jump table if specified by
+  // Only change the limit for targets in a jump table if specified by
   // the sub target, but not at the command line.
-  unsigned MaxJT = STI.getMaximumJumpTableSize();
-  if (MaxJT && getMaximumJumpTableSize() == UINT_MAX)
-    setMaximumJumpTableSize(MaxJT);
+  if (getMaximumJumpTableTargets() == UINT_MAX)
+    setMaximumJumpTableTargets(STI.getMaximumJumpTableTargets());
 
   setHasExtractBitsInsn(true);
 
index 558bea368eff2b71f98905c101ce10de22b58fc1..085a2ec5fe0317597b334767b371002557782a18 100644 (file)
@@ -96,13 +96,13 @@ void AArch64Subtarget::initializeProperties() {
     break;
   case ExynosM1:
     MaxInterleaveFactor = 4;
-    MaxJumpTableSize = 8;
+    MaxJumpTableTargets = 8;
     PrefFunctionLogAlignment = 4;
     PrefLoopLogAlignment = 3;
     break;
   case ExynosM3:
     MaxInterleaveFactor = 4;
-    MaxJumpTableSize = 20;
+    MaxJumpTableTargets = 20;
     PrefFunctionLogAlignment = 5;
     PrefLoopLogAlignment = 4;
     break;
index 757a46999868a426aca7523e29fff962562293b7..fa6e35e7c3da5e81a70f070ab6cc3eb4848fbc4a 100644 (file)
@@ -200,7 +200,7 @@ protected:
   unsigned MaxPrefetchIterationsAhead = UINT_MAX;
   unsigned PrefFunctionLogAlignment = 0;
   unsigned PrefLoopLogAlignment = 0;
-  unsigned MaxJumpTableSize = 0;
+  unsigned MaxJumpTableTargets = UINT_MAX;
   unsigned WideningBaseCost = 0;
 
   // ReserveXRegister[i] - X#i is not available as a general purpose register.
@@ -364,7 +364,7 @@ public:
   }
   unsigned getPrefLoopLogAlignment() const { return PrefLoopLogAlignment; }
 
-  unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; }
+  unsigned getMaximumJumpTableTargets() const { return MaxJumpTableTargets; }
 
   unsigned getWideningBaseCost() const { return WideningBaseCost; }
 
index 431db27432542845270e6d9f64eef4cc9351faa3..7eeffce73ad4e0df7acec154d8cb0c89b1d9fe66 100644 (file)
@@ -1,9 +1,9 @@
-; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40                         -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK0  < %t
-; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-size=4  -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK4  < %t
-; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-size=8  -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK8  < %t
-; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-size=16 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK16 < %t
-; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m1         -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM1 < %t
-; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m3         -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM3 < %t
+; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40                            -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK0  < %t
+; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-targets=4  -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK4  < %t
+; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-targets=8  -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK8  < %t
+; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-targets=16 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK16 < %t
+; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m1            -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM1 < %t
+; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m3            -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM3 < %t
 
 declare void @ext(i32, i32)
 
@@ -86,11 +86,11 @@ entry:
 ; CHECK0-NOT:   %jump-table.1:
 ; CHECK4-NEXT:  %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4{{$}}
 ; CHECK4-NOT:   %jump-table.1:
-; CHECK8-NEXT:  %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4{{$}}
+; CHECK8-NEXT:  %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.5 %bb.6{{$}}
 ; CHECK8-NOT:   %jump-table.1:
 ; CHECK16-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.5 %bb.6{{$}}
 ; CHECK16-NOT:  %jump-table.1:
-; CHECKM1-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4{{$}}
+; CHECKM1-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.5 %bb.6{{$}}
 ; CHECKM1-NOT:  %jump-table.1:
 ; CHECKM3-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.5 %bb.6{{$}}
 ; CHECKM3-NOT:  %jump-table.1:
@@ -102,6 +102,7 @@ bb3: tail call void @ext(i32 4, i32 3) br label %return
 bb4: tail call void @ext(i32 3, i32 4) br label %return
 bb5: tail call void @ext(i32 2, i32 5) br label %return
 bb6: tail call void @ext(i32 1, i32 6) br label %return
+
 return: ret void
 }
 
@@ -131,14 +132,13 @@ entry:
 ; CHECK4-NEXT:  %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4
 ; CHECK4-NEXT:  %jump-table.1: %bb.5 %bb.6 %bb.7 %bb.8
 ; CHECK4-NOT:   %jump-table.2:
-; CHECK8-NEXT:  %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4
-; CHECK8-NEXT:  %jump-table.1: %bb.5 %bb.6 %bb.7 %bb.8 %bb.13 %bb.9 %bb.10
+; CHECK8-NEXT:  %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7
+; CHECK8-NEXT:  %jump-table.1: %bb.8 %bb.13 %bb.9 %bb.10 %bb.13 %bb.11 %bb.12
 ; CHECK8-NOT:   %jump-table.2:
-; CHECK16-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7
-; CHECK16-NEXT: %jump-table.1: %bb.8 %bb.13 %bb.9 %bb.10 %bb.13 %bb.11 %bb.12
-; CHECK16-NOT:  %jump-table.2:
-; CHECKM1-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4
-; CHECKM1-NEXT: %jump-table.1: %bb.5 %bb.6 %bb.7 %bb.8 %bb.13 %bb.9 %bb.10
+; CHECK16-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7 %bb.8 %bb.13 %bb.9 %bb.10 %bb.13 %bb.11 %bb.12
+; CHECK16-NOT:  %jump-table.1:
+; CHECKM1-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7
+; CHECKM1-NEXT: %jump-table.1: %bb.8 %bb.13 %bb.9 %bb.10 %bb.13 %bb.11 %bb.12
 ; CHECKM1-NOT:  %jump-table.2:
 ; CHECKM3-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7 %bb.8 %bb.13 %bb.9 %bb.10
 ; CHECKM3-NOT:  %jump-table.1:
@@ -185,15 +185,15 @@ entry:
 ; CHECK0-NOT:   %jump-table.1:
 ; CHECK4-NEXT:  %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4
 ; CHECK4-NEXT:  %jump-table.1: %bb.5 %bb.6 %bb.7 %bb.8
-; CHECK4-NOT:   %jump-table.2:
-; CHECK8-NEXT:  %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4
-; CHECK8-NEXT:  %jump-table.1: %bb.5 %bb.6 %bb.7 %bb.8 %bb.13 %bb.9 %bb.10
+; CHECK4-NEXT:  %jump-table.2: %bb.9 %bb.10 %bb.13 %bb.11 %bb.12
+; CHECK4-NOT:   %jump-table.3:
+; CHECK8-NEXT:  %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7 %bb.8
+; CHECK8-NEXT:  %jump-table.1: %bb.9 %bb.10 %bb.13 %bb.11 %bb.12
 ; CHECK8-NOT:   %jump-table.2:
-; CHECK16-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7
-; CHECK16-NEXT: %jump-table.1: %bb.8 %bb.13 %bb.9 %bb.10 %bb.13 %bb.11 %bb.12
-; CHECK16-NOT:  %jump-table.2:
-; CHECKM1-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4
-; CHECKM1-NEXT: %jump-table.1: %bb.5 %bb.6 %bb.7 %bb.8 %bb.13 %bb.9 %bb.10
+; CHECK16-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7 %bb.8 %bb.13 %bb.9 %bb.10 %bb.13 %bb.11 %bb.12
+; CHECK16-NOT:  %jump-table.1:
+; CHECKM1-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7 %bb.8
+; CHECKM1-NEXT: %jump-table.1: %bb.9 %bb.10 %bb.13 %bb.11 %bb.12
 ; CHECKM1-NOT:  %jump-table.2:
 ; CHECKM3-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.13 %bb.5 %bb.6 %bb.7 %bb.8 %bb.13 %bb.9 %bb.10
 ; CHECKM3-NOT:  %jump-table.1: