[InstCombine] fold fmul/fdiv with fabs operands
authorSanjay Patel <spatel@rotateright.com>
Thu, 25 Jun 2020 15:28:04 +0000 (11:28 -0400)
committerSanjay Patel <spatel@rotateright.com>
Thu, 25 Jun 2020 15:35:38 +0000 (11:35 -0400)
commitc9e8c9e3ea2681dc18dd3a2d43d6aa8f37252649
treef419b83a38b60580d73fcefdf2425264284ba035
parentb044a8227078823c83c213765f220e502b2346ed
[InstCombine] fold fmul/fdiv with fabs operands

fabs(X) * fabs(Y) --> fabs(X * Y)
fabs(X) / fabs(Y) --> fabs(X / Y)

If both operands of fmul/fdiv are positive, then the result must be positive.

There's a NAN corner-case that prevents removing the more specific fold just
above this one:
fabs(X) * fabs(X) -> X * X
That fold works even with NAN because the sign-bit result of the multiply is
not specified if X is NAN.

We can't remove that and use the more general fold that is proposed here
because once we convert to this:
fabs (X * X)
...it is not legal to simplify the 'fabs' out of that expression when X is NAN.
That's because fabs() guarantees that the sign-bit is always cleared - even
for NAN values.

So this patch has the potential to lose information, but it seems unlikely if
we do the more specific fold ahead of this one.

Differential Revision: https://reviews.llvm.org/D82277
llvm/lib/Transforms/InstCombine/InstCombineInternal.h
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/test/Transforms/InstCombine/fdiv.ll
llvm/test/Transforms/InstCombine/fmul.ll