[llvm] [SimplifyCFG] Consider a cross signed max-min table in `switchToLookupTable` (PR #67885)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 8 23:22:15 PDT 2024
================
@@ -6676,17 +6676,48 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
SmallDenseMap<PHINode *, Type *> ResultTypes;
SmallVector<PHINode *, 4> PHIs;
- for (SwitchInst::CaseIt E = SI->case_end(); CI != E; ++CI) {
- ConstantInt *CaseVal = CI->getCaseValue();
- if (CaseVal->getValue().slt(MinCaseVal->getValue()))
- MinCaseVal = CaseVal;
- if (CaseVal->getValue().sgt(MaxCaseVal->getValue()))
- MaxCaseVal = CaseVal;
+ SmallVector<ConstantInt *, 8> CaseVals(llvm::map_range(
+ SI->cases(), [](const auto &C) { return C.getCaseValue(); }));
+
+ llvm::sort(CaseVals, [](const auto *L, const auto *R) {
+ return L->getValue().slt(R->getValue());
+ });
+ auto *CaseValIter = CaseVals.begin();
+ ConstantInt *BeginCaseVal = *CaseValIter;
+ ConstantInt *EndCaseVal = CaseVals.back();
+ bool RangeOverflow = false;
+ uint64_t LookupTableSize =
+ EndCaseVal->getValue()
+ .ssub_ov(BeginCaseVal->getValue(), RangeOverflow)
+ .getLimitedValue() +
+ 1;
+ if (RangeOverflow && ConsiderCrossSignedMaxMinTable) {
+ // We consider cases where the starting to the endpoint will cross the
+ // signed max and min. For example, for the i8 range `[-128, -127, 126,
+ // 127]`, we choose from 126 to -127. The length of the lookup table is 4.
+ while (CaseValIter != CaseVals.end()) {
+ auto *CurCaseVal = *CaseValIter++;
+ if (CaseValIter == CaseVals.end())
+ break;
+ auto *NextCaseVal = *CaseValIter;
+ const auto &NextVal = NextCaseVal->getValue();
+ const auto &CurVal = CurCaseVal->getValue();
+ uint64_t RequireTableSize = (CurVal - NextVal).getLimitedValue() + 1;
+ if (RequireTableSize < LookupTableSize) {
+ BeginCaseVal = NextCaseVal;
+ EndCaseVal = CurCaseVal;
+ LookupTableSize = RequireTableSize;
+ }
+ }
+ }
----------------
goldsteinn wrote:
IIUC this is looking for max distance between any two values. If so think this can be simplified as:
```
ConstantInt *BeginCaseVal = nullptr;
ConstantInt *EndCaseVal = nullptr;
uint64_t LookupTableSize = 0;
APInt UnsignedDif = UnsignedMax(CaseVals) - UnsignedMin(CaseVals);
APInt SignedDif = SignedMax(CaseVals) - SignedMin(CaseVals);
if (ConsiderCrossSignedMaxMinTable && UnsignedDif.ult(SignedDif)) {
// Cross signed min case
BeginCaseVal = UnsignedMin(CaseVals);
EndCaseVal = UnsignedMax(CaseVals);
LookupTableSize = UnsignedDif.getLimitedValue() + 1;
} else {
// Crossing 0 case
BeginCaseVal = SignedMin(CaseVals);
EndCaseVal = SignedMax(CaseVals);
LookupTableSize = SignedDif.getLimitedValue() + 1;
}
```
https://github.com/llvm/llvm-project/pull/67885
More information about the llvm-commits
mailing list