If either X or Y is odd and the other is non-zero, the result is
non-zero.
Alive2 Link:
https://alive2.llvm.org/ce/z/9V7-es
Differential D149418
[ValueTracking] Add additional cases for `isKnownNonZero(mul X, Y)` goldstein.w.n on Apr 27 2023, 11:21 PM. Authored by
Details If either X or Y is odd and the other is non-zero, the result is Alive2 Link: https://alive2.llvm.org/ce/z/9V7-es
Diff Detail
Event Timeline
Comment Actions I'm probably missing something obvious here, but what does it matter that one of the operands is odd? If we are multiplying two numbers where one is odd or even (as long as its non-zero) and the other is non-zero, the result will be non-zero, no? I can't figure out what's special about odd in this context. Comment Actions Its because multiple by odd preserves the low-bit from the input i.e Comment Actions Ah I see now, thank you! So in general, the only way a multiply with two non-zero source operands can result in a 0 is from overflow, but if at least one of those operands is odd, any overflow will never result in overflowing to 0. Edit: Nvm, the below is actually incorrect. I was only considering a single overflow (so 0b10000 in a 4 bit result), but it's possible to get multiple overflow (0b110000 in a 4 bit result) which could still be 0 without being a power of two. Comment Actions Made a mistake in my assumptions in the previous comment, but I do see how this patch makes sense now. Comment Actions This made me think of something, we can actually strengthen this case. Odd is just a special case really the result is X * Y != 0 is the same is Lowbit(X) * Lowbit(Y) != 0. Patch incoming! |
Similar to the add case, we should compute mul known bits here based on the already computed XKnown/YKnown, rather than computing them again via the fallback.
I think just using KnownBits::mul should be enough, as the NSW case handled by computeKnownBitsMul is already handled better above.