### Summary
ValueTracking currently allows InstSimplify to reason about the sign bit
of an `fmul` result based on the sign information of its operands. This
can lead to removing a subsequent `llvm.fabs` under the assumption that
the multiplication result is already non-negative.
However, `fmul` may produce NaNs whose sign bit is non-deterministic.
Since `llvm.fabs` canonicalizes the sign bit of NaNs, eliminating
llvm.fabs` in these cases can change observable behaviour.
### Change
Update ValueTracking to treat the sign bit of `fmul` as unknown when
NaNs are possible, preventing InstSimplify from incorrectly removing
llvm.fabs ` after `fmul`.
Fixes#179613
The handling for fma was very basic and only handled the
repeated input case. Re-use the fmul and fadd handling for more
accurate sign bit and nan handling.
In the case where both operands have the same sign,
as long as one of the operands is normal or infinity,
the result cannot underflow to a zero.
Pre-committing for #175614
Note some of the tests currently fail with alive, but not
due to this patch. Namely, when performing the fadd x, 0 -> x
simplification in functions with non-IEEE denormal handling.
The existing instsimplify ignores the denormals-are-zero hazard by
checking cannotBeNegativeZero instead of isKnownNeverLogicalZero.
Also note the self handling doesn't really do anything yet, other
than propagate consistent known-fpclass information until there is
multiple use support.
This also leaves behind the original ValueTracking support, without
switching to the new KnownFPClass:fadd utility. This will be easier
to clean up after the subsequent fsub support patch.
I'm working on optimizing out the tail sequences in the
implementations of the 4 different flavors of pow. These
include chains of selects on the various edge cases.
Related to #64870