[llvm] [SimplifyCFG] Improve reduceSwitchRange to avoid unnecessary subtractions (PR #198374)

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Fri May 22 08:04:03 PDT 2026


================
@@ -7582,31 +7582,50 @@ static bool reduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
   if (isSwitchDense(Values))
     return false;
 
-  // First, transform the values such that they start at zero and ascend.
-  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))
-    // Transform didn't create a dense switch.
+  struct RangeReduction {
+    int64_t Base;
+    unsigned Shift;
+  };
+
+  auto TryGetRangeReductionForBase =
+      [&](int64_t CandidateBase) -> std::optional<RangeReduction> {
+    SmallVector<int64_t, 4> ReducedValues;
+    ReducedValues.reserve(Values.size());
----------------
zmodem wrote:

Would it be easier to make a copy of Values first, and then modify it (like the original code did)?

```
... ReducedValues = Values;
for (int64_t &V : ReducedValues) {
  ...
```

https://github.com/llvm/llvm-project/pull/198374


More information about the llvm-commits mailing list