[llvm] r199420 - Teach InstCombine that (fmul X, -1.0) can be simplified to (fneg X), which LLVM expresses as (fsub -0.0, X).

Philip Reames listmail at philipreames.com
Thu Jan 16 14:19:59 PST 2014


Owen,

Could you give a quick justification on why this is a correct 
optimization?  I'm not saying it's wrong, but given the complexity of 
floating point it doesn't seem obviously correct either.

The case which has me hesitating is where X is a really large number 
(large exponent).  Multiplication clearly gets an exact answer.  Does 
the addition?  Adding small and large number is a notoriously error 
prone thing in floating point.  Another concerning case might be where X 
is undef.  Does the transformation increase the set of possible outputs?

I'm very open to being convinced this is correct; I'm simply raising a 
concern since I didn't see any justification given.

Philip

On 1/16/14 12:36 PM, Owen Anderson wrote:
> Author: resistor
> Date: Thu Jan 16 14:36:42 2014
> New Revision: 199420
>
> URL: http://llvm.org/viewvc/llvm-project?rev=199420&view=rev
> Log:
> Teach InstCombine that (fmul X, -1.0) can be simplified to (fneg X), which LLVM expresses as (fsub -0.0, X).
>
> Modified:
>      llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
>      llvm/trunk/test/Transforms/InstCombine/fmul.ll
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=199420&r1=199419&r2=199420&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Thu Jan 16 14:36:42 2014
> @@ -426,6 +426,16 @@ Instruction *InstCombiner::visitFMul(Bin
>           return NV;
>   
>       ConstantFP *C = dyn_cast<ConstantFP>(Op1);
> +
> +    // (fmul X, -1.0) --> (fsub -0.0, X)
> +    if (C && C->isExactlyValue(-1.0)) {
> +      Instruction *RI = BinaryOperator::CreateFSub(
> +        ConstantFP::getNegativeZero(C->getType()),
> +        Op0);
> +      RI->copyFastMathFlags(&I);
> +      return RI;
> +    }
> +
>       if (C && AllowReassociate && C->getValueAPF().isFiniteNonZero()) {
>         // Let MDC denote an expression in one of these forms:
>         // X * C, C/X, X/C, where C is a constant.
>
> Modified: llvm/trunk/test/Transforms/InstCombine/fmul.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fmul.ll?rev=199420&r1=199419&r2=199420&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/fmul.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/fmul.ll Thu Jan 16 14:36:42 2014
> @@ -93,3 +93,15 @@ for.body:
>   for.end:                                          ; preds = %for.cond
>     ret void
>   }
> +
> +; X * -1.0 => -0.0 - X
> +define float @test9(float %x) {
> +  %mul = fmul float %x, -1.0
> +  ret float %mul
> +
> +; CHECK-LABEL: @test9(
> +; CHECK-NOT: fmul
> +; CHECK: fsub
> +}
> +
> +
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list