Four things here:
- Generalize the fold to handle non-splat divisors. Reasonably trivial.
- Unban power-of-two divisors. I don't see any reason why they should be illegal.
- There is no ban in Hacker's Delight
- I think the ban came from the same bug that caused the miscompile - in floor((2^W - 1) / D) we were dividing by D0 instead of D, and we were ensuring that D0 is not 1, which made sense.
- Unban 1 divisors. I no longer believe Hacker's Delight actually says that the fold is invalid for D = 0. Further considerations:
- We know that
- (X u% 1) == 0 can be constant-folded to 1,
- (X u% 1) != 0 can be constant-folded to 0,
- Also, we know that
- X u<= -1 can be constant-folded to 1,
- X u> -1 can be constant-folded to 0,
- https://godbolt.org/z/7jnZJX https://rise4fun.com/Alive/oF6p
- We know will end up with the following: (setule/setugt (rotr (mul N, P), K), Q)
- Therefore, for given new DAG nodes and comparison predicates (ule/ugt), we will still produce the correct answer if: Q is a all-ones constant; and both P and K are *anything* other than undef.
- The fold will indeed produce Q = all-ones.
- We know that
- Try to re-splat the P and K vectors - we don't care about their values for the lines where divisor was 1.
This comment doesn't really grok well, if I've understood correctly it should be something like:
"If Values contains values that either match the predicate and the non-matching values are the same 'splat' values, then replace all of them with the 'splat' value."
But I'm not sure that's much better.