@@ -6516,18 +6516,20 @@ ShouldBuildLookupTable(SwitchInst *SI, uint64_t TableSize,
6516
6516
}
6517
6517
6518
6518
static bool ShouldUseSwitchConditionAsTableIndex (
6519
- ConstantInt &MinCaseVal , const ConstantInt &MaxCaseVal ,
6519
+ const ConstantInt &BeginCaseVal , const ConstantInt &EndCaseVal ,
6520
6520
bool HasDefaultResults, const SmallDenseMap<PHINode *, Type *> &ResultTypes,
6521
6521
const DataLayout &DL, const TargetTransformInfo &TTI) {
6522
- if (MinCaseVal .isNullValue ())
6522
+ if (BeginCaseVal .isNullValue ())
6523
6523
return true ;
6524
- if (MinCaseVal.isNegative () ||
6525
- MaxCaseVal.getLimitedValue () == std::numeric_limits<uint64_t >::max () ||
6524
+ if (BeginCaseVal.getValue ().sge (EndCaseVal.getValue ()))
6525
+ return false ;
6526
+ if (BeginCaseVal.isNegative () ||
6527
+ EndCaseVal.getLimitedValue () == std::numeric_limits<uint64_t >::max () ||
6526
6528
!HasDefaultResults)
6527
6529
return false ;
6528
6530
return all_of (ResultTypes, [&](const auto &KV) {
6529
6531
return SwitchLookupTable::WouldFitInRegister (
6530
- DL, MaxCaseVal .getLimitedValue () + 1 /* TableSize */ ,
6532
+ DL, EndCaseVal .getLimitedValue () + 1 /* TableSize */ ,
6531
6533
KV.second /* ResultType */ );
6532
6534
});
6533
6535
}
@@ -6618,7 +6620,8 @@ static void reuseTableCompare(
6618
6620
// / lookup tables.
6619
6621
static bool SwitchToLookupTable (SwitchInst *SI, IRBuilder<> &Builder,
6620
6622
DomTreeUpdater *DTU, const DataLayout &DL,
6621
- const TargetTransformInfo &TTI) {
6623
+ const TargetTransformInfo &TTI,
6624
+ bool TryMinTableSize) {
6622
6625
assert (SI->getNumCases () > 1 && " Degenerate switch?" );
6623
6626
6624
6627
BasicBlock *BB = SI->getParent ();
@@ -6644,9 +6647,6 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6644
6647
// Figure out the corresponding result for each case value and phi node in the
6645
6648
// common destination, as well as the min and max case values.
6646
6649
assert (!SI->cases ().empty ());
6647
- SwitchInst::CaseIt CI = SI->case_begin ();
6648
- ConstantInt *MinCaseVal = CI->getCaseValue ();
6649
- ConstantInt *MaxCaseVal = CI->getCaseValue ();
6650
6650
6651
6651
BasicBlock *CommonDest = nullptr ;
6652
6652
@@ -6657,17 +6657,49 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6657
6657
SmallDenseMap<PHINode *, Type *> ResultTypes;
6658
6658
SmallVector<PHINode *, 4 > PHIs;
6659
6659
6660
- for (SwitchInst::CaseIt E = SI->case_end (); CI != E; ++CI) {
6661
- ConstantInt *CaseVal = CI->getCaseValue ();
6662
- if (CaseVal->getValue ().slt (MinCaseVal->getValue ()))
6663
- MinCaseVal = CaseVal;
6664
- if (CaseVal->getValue ().sgt (MaxCaseVal->getValue ()))
6665
- MaxCaseVal = CaseVal;
6660
+ SmallVector<ConstantInt *, 8 > CaseVals (llvm::map_range (
6661
+ SI->cases (), [](const auto &C) { return C.getCaseValue (); }));
6662
+
6663
+ llvm::sort (CaseVals, [](const auto *L, const auto *R) {
6664
+ return L->getValue ().slt (R->getValue ());
6665
+ });
6666
+ auto *CaseValIter = CaseVals.begin ();
6667
+ ConstantInt *BeginCaseVal = *CaseValIter;
6668
+ ConstantInt *EndCaseVal = CaseVals.back ();
6669
+ bool RangeOverflow = false ;
6670
+ uint64_t MinTableSize = EndCaseVal->getValue ()
6671
+ .ssub_ov (BeginCaseVal->getValue (), RangeOverflow)
6672
+ .getLimitedValue () +
6673
+ 1 ;
6674
+ // If there is no overflow, then this must be the minimal table.
6675
+ // The signed max-min can no longer build a lookup table, so return.
6676
+ if (RangeOverflow && TryMinTableSize) {
6677
+ // We consider cases where the starting to the endpoint will cross the
6678
+ // signed max and min. For example, for the i8 range `[-128, -127, 126,
6679
+ // 127]`, we choose from 126 to -127. The length of the lookup table is 4.
6680
+ while (CaseValIter != CaseVals.end ()) {
6681
+ auto *CurCaseVal = *CaseValIter++;
6682
+ if (CaseValIter == CaseVals.end ())
6683
+ break ;
6684
+ auto *NextCaseVal = *CaseValIter;
6685
+ const auto &NextVal = NextCaseVal->getValue ();
6686
+ const auto &CurVal = CurCaseVal->getValue ();
6687
+ uint64_t RequireTableSize = (CurVal - NextVal).getLimitedValue () + 1 ;
6688
+ if (RequireTableSize < MinTableSize) {
6689
+ BeginCaseVal = NextCaseVal;
6690
+ EndCaseVal = CurCaseVal;
6691
+ MinTableSize = RequireTableSize;
6692
+ }
6693
+ }
6694
+ }
6695
+
6696
+ for (const auto &CI : SI->cases ()) {
6697
+ ConstantInt *CaseVal = CI.getCaseValue ();
6666
6698
6667
6699
// Resulting value at phi nodes for this case value.
6668
6700
using ResultsTy = SmallVector<std::pair<PHINode *, Constant *>, 4 >;
6669
6701
ResultsTy Results;
6670
- if (!getCaseResults (SI, CaseVal, CI-> getCaseSuccessor (), &CommonDest,
6702
+ if (!getCaseResults (SI, CaseVal, CI. getCaseSuccessor (), &CommonDest,
6671
6703
Results, DL, TTI))
6672
6704
return false ;
6673
6705
@@ -6702,13 +6734,12 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6702
6734
}
6703
6735
6704
6736
bool UseSwitchConditionAsTableIndex = ShouldUseSwitchConditionAsTableIndex (
6705
- *MinCaseVal , *MaxCaseVal , HasDefaultResults, ResultTypes, DL, TTI);
6737
+ *BeginCaseVal , *EndCaseVal , HasDefaultResults, ResultTypes, DL, TTI);
6706
6738
uint64_t TableSize;
6707
6739
if (UseSwitchConditionAsTableIndex)
6708
- TableSize = MaxCaseVal ->getLimitedValue () + 1 ;
6740
+ TableSize = EndCaseVal ->getLimitedValue () + 1 ;
6709
6741
else
6710
- TableSize =
6711
- (MaxCaseVal->getValue () - MinCaseVal->getValue ()).getLimitedValue () + 1 ;
6742
+ TableSize = MinTableSize;
6712
6743
6713
6744
bool TableHasHoles = (NumResults < TableSize);
6714
6745
bool NeedMask = (TableHasHoles && !HasDefaultResults);
@@ -6721,13 +6752,16 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6721
6752
}
6722
6753
6723
6754
if (!ShouldBuildLookupTable (SI, TableSize, TTI, DL, ResultTypes))
6724
- return false ;
6755
+ // When a signed max-min cannot construct a lookup table, try to find a
6756
+ // range with a minimal lookup table.
6757
+ return !TryMinTableSize &&
6758
+ SwitchToLookupTable (SI, Builder, DTU, DL, TTI, true );
6725
6759
6726
6760
std::vector<DominatorTree::UpdateType> Updates;
6727
6761
6728
6762
// Compute the maximum table size representable by the integer type we are
6729
6763
// switching upon.
6730
- unsigned CaseSize = MinCaseVal ->getType ()->getPrimitiveSizeInBits ();
6764
+ unsigned CaseSize = BeginCaseVal ->getType ()->getPrimitiveSizeInBits ();
6731
6765
uint64_t MaxTableSize = CaseSize > 63 ? UINT64_MAX : 1ULL << CaseSize;
6732
6766
assert (MaxTableSize >= TableSize &&
6733
6767
" It is impossible for a switch to have more entries than the max "
@@ -6749,15 +6783,17 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6749
6783
Value *TableIndex;
6750
6784
ConstantInt *TableIndexOffset;
6751
6785
if (UseSwitchConditionAsTableIndex) {
6752
- TableIndexOffset = ConstantInt::get (MaxCaseVal ->getIntegerType (), 0 );
6786
+ TableIndexOffset = ConstantInt::get (EndCaseVal ->getIntegerType (), 0 );
6753
6787
TableIndex = SI->getCondition ();
6754
6788
} else {
6755
- TableIndexOffset = MinCaseVal ;
6789
+ TableIndexOffset = BeginCaseVal ;
6756
6790
// If the default is unreachable, all case values are s>= MinCaseVal. Then
6757
6791
// we can try to attach nsw.
6758
6792
bool MayWrap = true ;
6759
- if (!DefaultIsReachable) {
6760
- APInt Res = MaxCaseVal->getValue ().ssub_ov (MinCaseVal->getValue (), MayWrap);
6793
+ if (!DefaultIsReachable &&
6794
+ EndCaseVal->getValue ().sge (BeginCaseVal->getValue ())) {
6795
+ APInt Res =
6796
+ EndCaseVal->getValue ().ssub_ov (BeginCaseVal->getValue (), MayWrap);
6761
6797
(void )Res;
6762
6798
}
6763
6799
@@ -6798,7 +6834,7 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
6798
6834
// PHI value for the default case in case we're using a bit mask.
6799
6835
} else {
6800
6836
Value *Cmp = Builder.CreateICmpULT (
6801
- TableIndex, ConstantInt::get (MinCaseVal ->getType (), TableSize));
6837
+ TableIndex, ConstantInt::get (BeginCaseVal ->getType (), TableSize));
6802
6838
RangeCheckBranch =
6803
6839
Builder.CreateCondBr (Cmp, LookupBB, SI->getDefaultDest ());
6804
6840
if (DTU)
@@ -7112,7 +7148,7 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
7112
7148
// CVP. Therefore, only apply this transformation during late stages of the
7113
7149
// optimisation pipeline.
7114
7150
if (Options.ConvertSwitchToLookupTable &&
7115
- SwitchToLookupTable (SI, Builder, DTU, DL, TTI))
7151
+ SwitchToLookupTable (SI, Builder, DTU, DL, TTI, false ))
7116
7152
return requestResimplify ();
7117
7153
7118
7154
if (simplifySwitchOfPowersOfTwo (SI, Builder, DL, TTI))
0 commit comments