@@ -6534,18 +6534,20 @@ ShouldBuildLookupTable(SwitchInst *SI, uint64_t TableSize,
6534
6534
}
6535
6535
6536
6536
static bool ShouldUseSwitchConditionAsTableIndex (
6537
- ConstantInt &MinCaseVal , const ConstantInt &MaxCaseVal ,
6537
+ const ConstantInt &BeginCaseVal , const ConstantInt &EndCaseVal ,
6538
6538
bool HasDefaultResults, const SmallDenseMap<PHINode *, Type *> &ResultTypes,
6539
6539
const DataLayout &DL, const TargetTransformInfo &TTI) {
6540
- if (MinCaseVal .isNullValue ())
6540
+ if (BeginCaseVal .isNullValue ())
6541
6541
return true ;
6542
- if (MinCaseVal.isNegative () ||
6543
- MaxCaseVal.getLimitedValue () == std::numeric_limits<uint64_t >::max () ||
6542
+ if (BeginCaseVal.getValue ().sge (EndCaseVal.getValue ()))
6543
+ return false ;
6544
+ if (BeginCaseVal.isNegative () ||
6545
+ EndCaseVal.getLimitedValue () == std::numeric_limits<uint64_t >::max () ||
6544
6546
!HasDefaultResults)
6545
6547
return false ;
6546
6548
return all_of (ResultTypes, [&](const auto &KV) {
6547
6549
return SwitchLookupTable::WouldFitInRegister (
6548
- DL, MaxCaseVal .getLimitedValue () + 1 /* TableSize */ ,
6550
+ DL, EndCaseVal .getLimitedValue () + 1 /* TableSize */ ,
6549
6551
KV.second /* ResultType */ );
6550
6552
});
6551
6553
}
@@ -6637,7 +6639,8 @@ static void reuseTableCompare(
6637
6639
// / lookup tables.
6638
6640
static bool SwitchToLookupTable (SwitchInst *SI, IRBuilder<> &Builder,
6639
6641
DomTreeUpdater *DTU, const DataLayout &DL,
6640
- const TargetTransformInfo &TTI) {
6642
+ const TargetTransformInfo &TTI,
6643
+ bool TryMinTableSize) {
6641
6644
assert (SI->getNumCases () > 1 && " Degenerate switch?" );
6642
6645
6643
6646
BasicBlock *BB = SI->getParent ();
@@ -6663,9 +6666,6 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6663
6666
// Figure out the corresponding result for each case value and phi node in the
6664
6667
// common destination, as well as the min and max case values.
6665
6668
assert (!SI->cases ().empty ());
6666
- SwitchInst::CaseIt CI = SI->case_begin ();
6667
- ConstantInt *MinCaseVal = CI->getCaseValue ();
6668
- ConstantInt *MaxCaseVal = CI->getCaseValue ();
6669
6669
6670
6670
BasicBlock *CommonDest = nullptr ;
6671
6671
@@ -6676,17 +6676,49 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6676
6676
SmallDenseMap<PHINode *, Type *> ResultTypes;
6677
6677
SmallVector<PHINode *, 4 > PHIs;
6678
6678
6679
- for (SwitchInst::CaseIt E = SI->case_end (); CI != E; ++CI) {
6680
- ConstantInt *CaseVal = CI->getCaseValue ();
6681
- if (CaseVal->getValue ().slt (MinCaseVal->getValue ()))
6682
- MinCaseVal = CaseVal;
6683
- if (CaseVal->getValue ().sgt (MaxCaseVal->getValue ()))
6684
- MaxCaseVal = CaseVal;
6679
+ SmallVector<ConstantInt *, 8 > CaseVals (llvm::map_range (
6680
+ SI->cases (), [](const auto &C) { return C.getCaseValue (); }));
6681
+
6682
+ llvm::sort (CaseVals, [](const auto *L, const auto *R) {
6683
+ return L->getValue ().slt (R->getValue ());
6684
+ });
6685
+ auto *CaseValIter = CaseVals.begin ();
6686
+ ConstantInt *BeginCaseVal = *CaseValIter;
6687
+ ConstantInt *EndCaseVal = CaseVals.back ();
6688
+ bool RangeOverflow = false ;
6689
+ uint64_t MinTableSize = EndCaseVal->getValue ()
6690
+ .ssub_ov (BeginCaseVal->getValue (), RangeOverflow)
6691
+ .getLimitedValue () +
6692
+ 1 ;
6693
+ // If there is no overflow, then this must be the minimal table.
6694
+ // The signed max-min can no longer build a lookup table, so return.
6695
+ if (RangeOverflow && TryMinTableSize) {
6696
+ // We consider cases where the starting to the endpoint will cross the
6697
+ // signed max and min. For example, for the i8 range `[-128, -127, 126,
6698
+ // 127]`, we choose from 126 to -127. The length of the lookup table is 4.
6699
+ while (CaseValIter != CaseVals.end ()) {
6700
+ auto *CurCaseVal = *CaseValIter++;
6701
+ if (CaseValIter == CaseVals.end ())
6702
+ break ;
6703
+ auto *NextCaseVal = *CaseValIter;
6704
+ const auto &NextVal = NextCaseVal->getValue ();
6705
+ const auto &CurVal = CurCaseVal->getValue ();
6706
+ uint64_t RequireTableSize = (CurVal - NextVal).getLimitedValue () + 1 ;
6707
+ if (RequireTableSize < MinTableSize) {
6708
+ BeginCaseVal = NextCaseVal;
6709
+ EndCaseVal = CurCaseVal;
6710
+ MinTableSize = RequireTableSize;
6711
+ }
6712
+ }
6713
+ }
6714
+
6715
+ for (const auto &CI : SI->cases ()) {
6716
+ ConstantInt *CaseVal = CI.getCaseValue ();
6685
6717
6686
6718
// Resulting value at phi nodes for this case value.
6687
6719
using ResultsTy = SmallVector<std::pair<PHINode *, Constant *>, 4 >;
6688
6720
ResultsTy Results;
6689
- if (!getCaseResults (SI, CaseVal, CI-> getCaseSuccessor (), &CommonDest,
6721
+ if (!getCaseResults (SI, CaseVal, CI. getCaseSuccessor (), &CommonDest,
6690
6722
Results, DL, TTI))
6691
6723
return false ;
6692
6724
@@ -6721,13 +6753,12 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6721
6753
}
6722
6754
6723
6755
bool UseSwitchConditionAsTableIndex = ShouldUseSwitchConditionAsTableIndex (
6724
- *MinCaseVal , *MaxCaseVal , HasDefaultResults, ResultTypes, DL, TTI);
6756
+ *BeginCaseVal , *EndCaseVal , HasDefaultResults, ResultTypes, DL, TTI);
6725
6757
uint64_t TableSize;
6726
6758
if (UseSwitchConditionAsTableIndex)
6727
- TableSize = MaxCaseVal ->getLimitedValue () + 1 ;
6759
+ TableSize = EndCaseVal ->getLimitedValue () + 1 ;
6728
6760
else
6729
- TableSize =
6730
- (MaxCaseVal->getValue () - MinCaseVal->getValue ()).getLimitedValue () + 1 ;
6761
+ TableSize = MinTableSize;
6731
6762
6732
6763
// If the default destination is unreachable, or if the lookup table covers
6733
6764
// all values of the conditional variable, branch directly to the lookup table
@@ -6757,13 +6788,16 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6757
6788
}
6758
6789
6759
6790
if (!ShouldBuildLookupTable (SI, TableSize, TTI, DL, ResultTypes))
6760
- return false ;
6791
+ // When a signed max-min cannot construct a lookup table, try to find a
6792
+ // range with a minimal lookup table.
6793
+ return !TryMinTableSize &&
6794
+ SwitchToLookupTable (SI, Builder, DTU, DL, TTI, true );
6761
6795
6762
6796
std::vector<DominatorTree::UpdateType> Updates;
6763
6797
6764
6798
// Compute the maximum table size representable by the integer type we are
6765
6799
// switching upon.
6766
- unsigned CaseSize = MinCaseVal ->getType ()->getPrimitiveSizeInBits ();
6800
+ unsigned CaseSize = BeginCaseVal ->getType ()->getPrimitiveSizeInBits ();
6767
6801
uint64_t MaxTableSize = CaseSize > 63 ? UINT64_MAX : 1ULL << CaseSize;
6768
6802
assert (MaxTableSize >= TableSize &&
6769
6803
" It is impossible for a switch to have more entries than the max "
@@ -6779,15 +6813,17 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6779
6813
Value *TableIndex;
6780
6814
ConstantInt *TableIndexOffset;
6781
6815
if (UseSwitchConditionAsTableIndex) {
6782
- TableIndexOffset = ConstantInt::get (MaxCaseVal ->getIntegerType (), 0 );
6816
+ TableIndexOffset = ConstantInt::get (EndCaseVal ->getIntegerType (), 0 );
6783
6817
TableIndex = SI->getCondition ();
6784
6818
} else {
6785
- TableIndexOffset = MinCaseVal ;
6819
+ TableIndexOffset = BeginCaseVal ;
6786
6820
// If the default is unreachable, all case values are s>= MinCaseVal. Then
6787
6821
// we can try to attach nsw.
6788
6822
bool MayWrap = true ;
6789
- if (!DefaultIsReachable) {
6790
- APInt Res = MaxCaseVal->getValue ().ssub_ov (MinCaseVal->getValue (), MayWrap);
6823
+ if (!DefaultIsReachable &&
6824
+ EndCaseVal->getValue ().sge (BeginCaseVal->getValue ())) {
6825
+ APInt Res =
6826
+ EndCaseVal->getValue ().ssub_ov (BeginCaseVal->getValue (), MayWrap);
6791
6827
(void )Res;
6792
6828
}
6793
6829
@@ -6830,7 +6866,7 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6830
6866
// PHI value for the default case in case we're using a bit mask.
6831
6867
} else {
6832
6868
Value *Cmp = Builder.CreateICmpULT (
6833
- TableIndex, ConstantInt::get (MinCaseVal ->getType (), TableSize));
6869
+ TableIndex, ConstantInt::get (BeginCaseVal ->getType (), TableSize));
6834
6870
RangeCheckBranch =
6835
6871
Builder.CreateCondBr (Cmp, LookupBB, SI->getDefaultDest ());
6836
6872
if (DTU)
@@ -7145,7 +7181,7 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
7145
7181
// CVP. Therefore, only apply this transformation during late stages of the
7146
7182
// optimisation pipeline.
7147
7183
if (Options.ConvertSwitchToLookupTable &&
7148
- SwitchToLookupTable (SI, Builder, DTU, DL, TTI))
7184
+ SwitchToLookupTable (SI, Builder, DTU, DL, TTI, false ))
7149
7185
return requestResimplify ();
7150
7186
7151
7187
if (simplifySwitchOfPowersOfTwo (SI, Builder, DL, TTI))
0 commit comments