[llvm] [SimplifyCFG] Improve reduceSwitchRange to avoid unnecessary subtractions (PR #198374)
Alexis Engelke via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 5 09:54:43 PDT 2026
================
@@ -7637,34 +7672,24 @@ static bool reduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
llvm::sort(Values);
// If the switch is already dense, there's nothing useful to do here.
- if (isSwitchDense(Values, SI->getFunction()->hasOptSize()))
+ bool OptSize = SI->getFunction()->hasOptSize();
+ if (isSwitchDense(Values, OptSize))
return false;
- // First, transform the values such that they start at zero and ascend.
+ // Find a Base and corresponding Shift that results in a dense switch range.
+ // Values[0] is the local minimum.
int64_t Base = Values[0];
- for (auto &V : Values)
- V -= (uint64_t)(Base);
-
- // Now we have signed numbers that have been shifted so that, given enough
- // precision, there are no negative values. Since the rest of the transform
- // is bitwise only, we switch now to an unsigned representation.
-
- // This transform can be done speculatively because it is so cheap - it
- // results in a single rotate operation being inserted.
-
- // countTrailingZeros(0) returns 64. As Values is guaranteed to have more than
- // one element and LLVM disallows duplicate cases, Shift is guaranteed to be
- // less than 64.
- unsigned Shift = 64;
- for (auto &V : Values)
- Shift = std::min(Shift, (unsigned)llvm::countr_zero((uint64_t)V));
- assert(Shift < 64);
- if (Shift > 0)
- for (auto &V : Values)
- V = (int64_t)((uint64_t)V >> Shift);
-
- if (!isSwitchDense(Values, SI->getFunction()->hasOptSize()))
- // Transform didn't create a dense switch.
+ std::optional<unsigned> Shift;
+ // Prefer Base=0 when the case values are still dense after shifting out their
+ // common low zero bits without subtracting a base. This avoids creating an
+ // unnecessary `(condition - local_min)` expression.
+ if ((Shift = getDenseSwitchRangeReductionShift(Values, /*Base=*/0,
+ /*OptSize=*/true)))
+ Base = 0;
+ else if (Base != 0)
+ Shift = getDenseSwitchRangeReductionShift(Values, Base, OptSize);
----------------
aengelke wrote:
Sounds good, but please add these considerations as a comment into the code.
https://github.com/llvm/llvm-project/pull/198374
More information about the llvm-commits
mailing list