mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
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.
llvm-svn: 172117
This commit is contained in:
parent
7eb475a77d
commit
9e81fe53cf
@ -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) &&
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user