|
@@ -5559,25 +5559,23 @@ static bool ReduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
|
|
|
// 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.
|
|
|
- uint64_t GCD = 0;
|
|
|
- for (auto &V : Values)
|
|
|
- GCD = GreatestCommonDivisor64(GCD, (uint64_t)V);
|
|
|
|
|
|
- // This transform can be done speculatively because it is so cheap - it results
|
|
|
- // in a single rotate operation being inserted. This can only happen if the
|
|
|
- // factor extracted is a power of 2.
|
|
|
- // FIXME: If the GCD is an odd number we can multiply by the multiplicative
|
|
|
- // inverse of GCD and then perform this transform.
|
|
|
+ // This transform can be done speculatively because it is so cheap - it
|
|
|
+ // results in a single rotate operation being inserted.
|
|
|
// FIXME: It's possible that optimizing a switch on powers of two might also
|
|
|
// be beneficial - flag values are often powers of two and we could use a CLZ
|
|
|
// as the key function.
|
|
|
- if (GCD <= 1 || !isPowerOf2_64(GCD))
|
|
|
- // No common divisor found or too expensive to compute key function.
|
|
|
- return false;
|
|
|
|
|
|
- unsigned Shift = Log2_64(GCD);
|
|
|
+ // 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)
|
|
|
- V = (int64_t)((uint64_t)V >> Shift);
|
|
|
+ Shift = std::min(Shift, countTrailingZeros((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.
|