Handle sqrt() shrinking in SimplifyLibCalls like any other call

This patch removes a chunk of special case logic for folding 
(float)sqrt((double)x) -> sqrtf(x)
in InstCombineCasts and handles it in the mainstream path of SimplifyLibCalls.

No functional change intended, but I loosened the restriction on the existing
sqrt testcases to allow for this optimization even without unsafe-fp-math because
that's the existing behavior.

I also added a missing test case for not shrinking the llvm.sqrt.f64 intrinsic
in case the result is used as a double.

Differential Revision: http://reviews.llvm.org/D5919



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220514 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjay Patel
2014-10-23 21:52:45 +00:00
parent 4d529076b6
commit d2153694e0
3 changed files with 33 additions and 47 deletions

View File

@ -1317,42 +1317,6 @@ Instruction *InstCombiner::visitFPTrunc(FPTruncInst &CI) {
}
}
// Fold (fptrunc (sqrt (fpext x))) -> (sqrtf x)
// Note that we restrict this transformation based on
// TLI->has(LibFunc::sqrtf), even for the sqrt intrinsic, because
// TLI->has(LibFunc::sqrtf) is sufficient to guarantee that the
// single-precision intrinsic can be expanded in the backend.
CallInst *Call = dyn_cast<CallInst>(CI.getOperand(0));
if (Call && Call->getCalledFunction() && TLI->has(LibFunc::sqrtf) &&
(Call->getCalledFunction()->getName() == TLI->getName(LibFunc::sqrt) ||
Call->getCalledFunction()->getIntrinsicID() == Intrinsic::sqrt) &&
Call->getNumArgOperands() == 1 &&
Call->hasOneUse()) {
CastInst *Arg = dyn_cast<CastInst>(Call->getArgOperand(0));
if (Arg && Arg->getOpcode() == Instruction::FPExt &&
CI.getType()->isFloatTy() &&
Call->getType()->isDoubleTy() &&
Arg->getType()->isDoubleTy() &&
Arg->getOperand(0)->getType()->isFloatTy()) {
Function *Callee = Call->getCalledFunction();
Module *M = CI.getParent()->getParent()->getParent();
Constant *SqrtfFunc = (Callee->getIntrinsicID() == Intrinsic::sqrt) ?
Intrinsic::getDeclaration(M, Intrinsic::sqrt, Builder->getFloatTy()) :
M->getOrInsertFunction("sqrtf", Callee->getAttributes(),
Builder->getFloatTy(), Builder->getFloatTy(),
NULL);
CallInst *ret = CallInst::Create(SqrtfFunc, Arg->getOperand(0),
"sqrtfcall");
ret->setAttributes(Callee->getAttributes());
// Remove the old Call. With -fmath-errno, it won't get marked readnone.
ReplaceInstUsesWith(*Call, UndefValue::get(Call->getType()));
EraseInstFromFunction(*Call);
return ret;
}
}
return nullptr;
}