4 ms·
I think this bug fix is wrong, the previous behavior was both correct and better, and the actual bug is probably in alive2. The bug report claims > The domain
by fluffything 6y ago
I think this bug fix is wrong, the previous behavior was both correct and better, and the actual bug is probably in alive2.
The bug report claims
> The domain for (llvm.maximum undef, %x) depends on %x,
But this claim is not true. Here is why, when the LLVM docs state:
> [llvm.maximum returns] the maximum of the two argument, propagating NAN [...]
they are referring to IEEE's 754 maximum semantics, which state that if one floating-point argument to the function is a NAN, the function returns a NAN.
However, IEEE assumes that floating point values are composed of bits, which can be 0 or 1.
That assumption does not hold in LLVM, where a bit can take any of three values: 0, 1, or undef (well there is also poison, but lets leave that aside).
According to IEEE, llvm.maximum(%x, NAN) must return NAN _if_ x is not undef. But if x is undef, then IEEE does not hold.
The LLVM docs do not say what this function should return in that case, so the behavior is IMO currently undefined, and any optimization for this is correct, so we might as well pick the one that enables most optimizations, and that's returning undef (e.g. these cases only legitimally happen in dead code, e.g., expanded from macros, and you want the compiler to better remove this dead code).
There is also the issue of consistency. If we were to replace llvm.maximum(%x, NAN) with llvm.select(%x >= NAN, %x, NAN) then you would think that any number compared with NAN compares to false, and this always returns NAN, but that does not hold for undef, where you get llvm.select(undef, undef, NAN) returning undef or just being plain UB.
So IMO the assumption motivating this fix is wrong. It assumes that undef is a floating-point value, but it isn't. It is something else, and the floating-point rules of NAN comparisons with undef do not apply to it. This fix will only remove optimizations, and delay broken code from standing out, because if your program tries to execute `llvm.maximum(undef, %x)`, your program is broken.
[0]: https://llvm.org/docs/LangRef.html#llvm-maximum-intrinsic https://llvm.org/docs/LangRef.html#llvm-maximum-intrinsic