From 8564e0de96d18eba9d8501611591c7c3ef9d8be3 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Wed, 30 Mar 2011 15:42:35 +0000 Subject: [PATCH] InstCombine: If the divisor of an fdiv has an exact inverse, turn it into an fmul. Fixes PR9587. llvm-svn: 128546 --- .../InstCombine/InstCombineMulDivRem.cpp | 12 +++++++++ llvm/test/Transforms/InstCombine/fdiv.ll | 25 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 llvm/test/Transforms/InstCombine/fdiv.ll diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index d1a1fd6ddfac..665138748151 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -452,6 +452,18 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { if (Value *V = SimplifyFDivInst(Op0, Op1, TD)) return ReplaceInstUsesWith(I, V); + if (ConstantFP *Op1C = dyn_cast(Op1)) { + const APFloat &Op1F = Op1C->getValueAPF(); + + // If the divisor has an exact multiplicative inverse we can turn the fdiv + // into a cheaper fmul. + APFloat Reciprocal(Op1F.getSemantics()); + if (Op1F.getExactInverse(&Reciprocal)) { + ConstantFP *RFP = ConstantFP::get(Builder->getContext(), Reciprocal); + return BinaryOperator::CreateFMul(Op0, RFP); + } + } + return 0; } diff --git a/llvm/test/Transforms/InstCombine/fdiv.ll b/llvm/test/Transforms/InstCombine/fdiv.ll new file mode 100644 index 000000000000..f4e0b4841126 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/fdiv.ll @@ -0,0 +1,25 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +define float @test1(float %x) nounwind readnone ssp { + %div = fdiv float %x, 0x3810000000000000 + ret float %div + +; CHECK: @test1 +; CHECK-NEXT: fmul float %x, 0x47D0000000000000 +} + +define float @test2(float %x) nounwind readnone ssp { + %div = fdiv float %x, 0x47E0000000000000 + ret float %div + +; CHECK: @test2 +; CHECK-NEXT: fmul float %x, 0x3800000000000000 +} + +define float @test3(float %x) nounwind readnone ssp { + %div = fdiv float %x, 0x36A0000000000000 + ret float %div + +; CHECK: @test3 +; CHECK-NEXT: fdiv float %x, 0x36A0000000000000 +}