diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp index a1aedd4e8f1..72377dc0adc 100644 --- a/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1262,9 +1262,14 @@ 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(CI.getOperand(0)); if (Call && Call->getCalledFunction() && TLI->has(LibFunc::sqrtf) && - Call->getCalledFunction()->getName() == TLI->getName(LibFunc::sqrt) && + (Call->getCalledFunction()->getName() == TLI->getName(LibFunc::sqrt) || + Call->getCalledFunction()->getIntrinsicID() == Intrinsic::sqrt) && Call->getNumArgOperands() == 1 && Call->hasOneUse()) { CastInst *Arg = dyn_cast(Call->getArgOperand(0)); @@ -1275,11 +1280,11 @@ Instruction *InstCombiner::visitFPTrunc(FPTruncInst &CI) { Arg->getOperand(0)->getType()->isFloatTy()) { Function *Callee = Call->getCalledFunction(); Module *M = CI.getParent()->getParent()->getParent(); - Constant *SqrtfFunc = M->getOrInsertFunction("sqrtf", - Callee->getAttributes(), - Builder->getFloatTy(), - Builder->getFloatTy(), - NULL); + 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()); diff --git a/test/Transforms/InstCombine/double-float-shrink-1.ll b/test/Transforms/InstCombine/double-float-shrink-1.ll index e5448ee0076..5cacb591e00 100644 --- a/test/Transforms/InstCombine/double-float-shrink-1.ll +++ b/test/Transforms/InstCombine/double-float-shrink-1.ll @@ -263,6 +263,7 @@ define double @sin_test2(float %f) nounwind readnone { ret double %call ; CHECK: call double @sin(double %conv) } + define float @sqrt_test(float %f) nounwind readnone { ; CHECK: sqrt_test %conv = fpext float %f to double @@ -272,6 +273,15 @@ define float @sqrt_test(float %f) nounwind readnone { ; CHECK: call float @sqrtf(float %f) } +define float @sqrt_int_test(float %f) nounwind readnone { +; CHECK: sqrt_int_test + %conv = fpext float %f to double + %call = call double @llvm.sqrt.f64(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @llvm.sqrt.f32(float %f) +} + define double @sqrt_test2(float %f) nounwind readnone { ; CHECK: sqrt_test2 %conv = fpext float %f to double @@ -331,3 +341,6 @@ declare double @acos(double) nounwind readnone declare double @acosh(double) nounwind readnone declare double @asin(double) nounwind readnone declare double @asinh(double) nounwind readnone + +declare double @llvm.sqrt.f64(double) nounwind readnone +