Skip to content

Commit

Permalink
Teach InstCombine to hoist FABS and FNEG through FPTRUNC instructions…
Browse files Browse the repository at this point in the history
…. 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
  • Loading branch information
resistor committed Jan 10, 2013
1 parent 244b7a4 commit e9d4eba
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
28 changes: 27 additions & 1 deletion lib/Transforms/InstCombine/InstCombineCasts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<IntrinsicInst>(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<CallInst>(CI.getOperand(0));
if (Call && Call->getCalledFunction() && TLI->has(LibFunc::sqrtf) &&
Expand Down
19 changes: 19 additions & 0 deletions test/Transforms/InstCombine/fpcast.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit e9d4eba

Please sign in to comment.