From e9d4eba45122892670fe24458bf161e559a799e7 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 10 Jan 2013 22:06:52 +0000 Subject: [PATCH] Teach InstCombine to hoist FABS and FNEG through FPTRUNC instructions. The application of these operations commutes with the truncation, so we should prefer to do them in the smallest size we can, to save register space, use smaller constant pool entries, etc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172117 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineCasts.cpp | 28 ++++++++++++++++++- test/Transforms/InstCombine/fpcast.ll | 19 +++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp index 5af444235c7..c782032c458 100644 --- a/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1204,8 +1204,34 @@ Instruction *InstCombiner::visitFPTrunc(FPTruncInst &CI) { } break; } + + // (fptrunc (fneg x)) -> (fneg (fptrunc x)) + if (BinaryOperator::isFNeg(OpI)) { + Value *InnerTrunc = Builder->CreateFPTrunc(OpI->getOperand(1), + CI.getType()); + return BinaryOperator::CreateFNeg(InnerTrunc); + } } - + + IntrinsicInst *II = dyn_cast(CI.getOperand(0)); + if (II) { + switch (II->getIntrinsicID()) { + default: break; + case Intrinsic::fabs: { + // (fptrunc (fabs x)) -> (fabs (fptrunc x)) + Value *InnerTrunc = Builder->CreateFPTrunc(II->getArgOperand(0), + CI.getType()); + Type *IntrinsicType[] = { CI.getType() }; + Function *Overload = + Intrinsic::getDeclaration(CI.getParent()->getParent()->getParent(), + II->getIntrinsicID(), IntrinsicType); + + Value *Args[] = { InnerTrunc }; + return CallInst::Create(Overload, Args, II->getName()); + } + } + } + // Fold (fptrunc (sqrt (fpext x))) -> (sqrtf x) CallInst *Call = dyn_cast(CI.getOperand(0)); if (Call && Call->getCalledFunction() && TLI->has(LibFunc::sqrtf) && diff --git a/test/Transforms/InstCombine/fpcast.ll b/test/Transforms/InstCombine/fpcast.ll index bc6aa0a6891..09f053289dc 100644 --- a/test/Transforms/InstCombine/fpcast.ll +++ b/test/Transforms/InstCombine/fpcast.ll @@ -13,3 +13,22 @@ define i8 @test2() { ; CHECK: ret i8 -1 } +; CHECK: test3 +define half @test3(float %a) { +; CHECK: fptrunc +; CHECK: llvm.fabs.f16 + %b = call float @llvm.fabs.f32(float %a) + %c = fptrunc float %b to half + ret half %c +} + +; CHECK: test4 +define half @test4(float %a) { +; CHECK: fptrunc +; CHECK: fsub + %b = fsub float -0.0, %a + %c = fptrunc float %b to half + ret half %c +} + +declare float @llvm.fabs.f32(float) nounwind readonly