Do constant folding according to
posion * C -> poison C * poison -> poison undef * C -> 0 C * undef -> 0
for smul_fix and smul_fix_sat intrinsics (for any scale).
Differential D98410
[ConstantFold] Handle undef/poison when constant folding smul_fix/smul_fix_sat bjope on Mar 11 2021, 3:58 AM. Authored by
Details Do constant folding according to posion * C -> poison C * poison -> poison undef * C -> 0 C * undef -> 0 for smul_fix and smul_fix_sat intrinsics (for any scale).
Diff Detail
Event Timeline
Comment Actions Wouldn't folding C * undef and undef * C into an undef, rather than 0, be valid/better? Is there a reason we cannot do that? Comment Actions I figure that it would be wrong if for example C is zero, because then the result can't take any other value than zero. Or if C is 2 and scale is 0, then the result can't be odd. So undef include values that isn't possible for every combination of the other operands. The poison propagation is a bit more new for me. I hope I got that part correct. Comment Actions Yep, this is right.
Comment Actions Aha, I see! This is an interesting reasoning. I think it is fine to do what you're doing for the sake of simplicity, what follows under the horizontal line below is a bunch of my rambling (feel free to ignore all of it) Taking a regular mul instruction as an example mul i32 1, undef # => undef mul i32 2, undef # => 0 mul i32 3, undef # => undef These make sense to me, though require some roundabout reasoning. 1 * undef = undef is trivial. 2 * undef follows the same reasoning as yours in that there's no bit-pattern undef can take that would result in 0 bit set here. That same reasoning could apply for 3 * undef too – but it does not because of wrap-around (I think). And this is where the following snippet from the smul.fix definition comes in:
Basically, unless the intrinsic is multiplying undef by 1 or by 0, I believe there's an implicit invocation of UB. That's because there exist bit patterns of an undef operand that multiplied by other values would cause the resulting value to not fit within the fixed point type's range (right?). Whether we manifest this UB as undef or 0 probably doesn't matter too much, but I think either option would be valid. Comment Actions It depends a bit on the scale. If you for example multiply by 0.5 then you won't get any overflow. On the other hand, smul.fix with scale=0 is pretty much like a regular mul but not sure we need to make a special case for that.
|
Just a side note not really related to this patch; I suspect that we perhaps could use APFixedPoint here, somehow, in the future.