Index: llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1167,6 +1167,10 @@ Value *Shrunk = nullptr; bool Ignored; + // Bail out if simplifying libcalls to pow() is disabled. + if (!hasUnaryFloatFn(TLI, Ty, LibFunc_pow, LibFunc_powf, LibFunc_powl)) + return nullptr; + // Propagate the math semantics from the call to any created instructions. IRBuilder<>::FastMathFlagGuard Guard(B); B.setFastMathFlags(Pow->getFastMathFlags()); @@ -1179,7 +1183,7 @@ // Evaluate special cases related to the base. // pow(1.0, x) -> 1.0 - if (match(Base, m_SpecificFP(1.0))) + if (match(Base, m_FPOne())) return Base; // pow(2.0, x) -> exp2(x) @@ -1207,9 +1211,6 @@ Function *CalleeFn = BaseFn->getCalledFunction(); if (CalleeFn && TLI->getLibFunc(CalleeFn->getName(), LibFn) && (LibFn == LibFunc_exp || LibFn == LibFunc_exp2) && TLI->has(LibFn)) { - IRBuilder<>::FastMathFlagGuard Guard(B); - B.setFastMathFlags(Pow->getFastMathFlags()); - Value *FMul = B.CreateFMul(BaseFn->getArgOperand(0), Expo, "mul"); return emitUnaryFloatFnCall(FMul, CalleeFn->getName(), B, CalleeFn->getAttributes()); @@ -1218,31 +1219,28 @@ // Evaluate special cases related to the exponent. - if (Value *Sqrt = replacePowWithSqrt(Pow, B)) - return Sqrt; - - ConstantFP *ExpoC = dyn_cast(Expo); - if (!ExpoC) - return Shrunk; - // pow(x, -1.0) -> 1.0 / x - if (ExpoC->isExactlyValue(-1.0)) + if (match(Expo, m_SpecificFP(-1.0))) return B.CreateFDiv(ConstantFP::get(Ty, 1.0), Base, "reciprocal"); // pow(x, 0.0) -> 1.0 - if (ExpoC->getValueAPF().isZero()) - return ConstantFP::get(Ty, 1.0); + if (match(Expo, m_SpecificFP(0.0))) + return ConstantFP::get(Ty, 1.0); // pow(x, 1.0) -> x - if (ExpoC->isExactlyValue(1.0)) + if (match(Expo, m_FPOne())) return Base; // pow(x, 2.0) -> x * x - if (ExpoC->isExactlyValue(2.0)) + if (match(Expo, m_SpecificFP(2.0))) return B.CreateFMul(Base, Base, "square"); + if (Value *Sqrt = replacePowWithSqrt(Pow, B)) + return Sqrt; + // FIXME: Correct the transforms and pull this into replacePowWithSqrt(). - if (ExpoC->isExactlyValue(0.5) && + ConstantFP *ExpoC = dyn_cast(Expo); + if (ExpoC && ExpoC->isExactlyValue(0.5) && hasUnaryFloatFn(TLI, Ty, LibFunc_sqrt, LibFunc_sqrtf, LibFunc_sqrtl)) { // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))). // This is faster than calling pow(), and still handles -0.0 and @@ -1262,30 +1260,29 @@ return Sqrt; } - // pow(x, n) -> x * x * x * .... - if (Pow->isFast()) { - APFloat ExpoA = abs(ExpoC->getValueAPF()); - // We limit to a max of 7 fmul(s). Thus the maximum exponent is 32. - // This transformation applies to integer exponents only. - if (!ExpoA.isInteger() || - ExpoA.compare - (APFloat(ExpoA.getSemantics(), 32.0)) == APFloat::cmpGreaterThan) - return Shrunk; - - // We will memoize intermediate products of the Addition Chain. - Value *InnerChain[33] = {nullptr}; - InnerChain[1] = Base; - InnerChain[2] = B.CreateFMul(Base, Base, "square"); - - // We cannot readily convert a non-double type (like float) to a double. - // So we first convert it to something which could be converted to double. - ExpoA.convert(APFloat::IEEEdouble(), APFloat::rmTowardZero, &Ignored); - Value *FMul = getPow(InnerChain, ExpoA.convertToDouble(), B); - - // If the exponent is negative, then get the reciprocal. - if (ExpoC->isNegative()) - FMul = B.CreateFDiv(ConstantFP::get(Ty, 1.0), FMul, "reciprocal"); - return FMul; + // pow(x, n) -> x * x * x * ... + const APFloat *ExpoF; + if (Pow->isFast() && match(Expo, m_APFloat(ExpoF))) { + // We limit to a max of 7 multiplications, thus the maximum exponent is 32. + APFloat LimF(ExpoF->getSemantics(), 33.0), + ExpoA(abs(*ExpoF)); + if (ExpoA.isInteger() && ExpoA.compare(LimF) == APFloat::cmpLessThan) { + // We will memoize intermediate products of the Addition Chain. + Value *InnerChain[33] = {nullptr}; + InnerChain[1] = Base; + InnerChain[2] = B.CreateFMul(Base, Base, "square"); + + // We cannot readily convert a non-double type (like float) to a double. + // So we first convert it to something which could be converted to double. + ExpoA.convert(APFloat::IEEEdouble(), APFloat::rmTowardZero, &Ignored); + Value *FMul = getPow(InnerChain, ExpoA.convertToDouble(), B); + + // If the exponent is negative, then get the reciprocal. + if (ExpoF->isNegative()) + FMul = B.CreateFDiv(ConstantFP::get(Ty, 1.0), FMul, "reciprocal"); + + return FMul; + } } return Shrunk; Index: llvm/test/Transforms/InstCombine/double-float-shrink-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/double-float-shrink-1.ll +++ llvm/test/Transforms/InstCombine/double-float-shrink-1.ll @@ -346,7 +346,7 @@ define float @pow_test1(float %f, float %g) { ; CHECK-LABEL: @pow_test1( -; CHECK-NEXT: [[POWF:%.*]] = call fast float @powf(float %f, float %g) +; CHECK-NEXT: [[POWF:%.*]] = call fast float @powf(float [[F:%.*]], float [[G:%.*]]) ; CHECK-NEXT: ret float [[POWF]] ; %df = fpext float %f to double Index: llvm/test/Transforms/InstCombine/pow-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/pow-1.ll +++ llvm/test/Transforms/InstCombine/pow-1.ll @@ -95,7 +95,7 @@ ; CHECK-LABEL: @test_simplify5v( %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %retval -; CHECK-NEXT: %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> zeroinitializer) +; CHECK-NEXT: ret <2 x float> } define double @test_simplify6(double %x) { @@ -109,7 +109,7 @@ ; CHECK-LABEL: @test_simplify6v( %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %retval -; CHECK-NEXT: %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> zeroinitializer) +; CHECK-NEXT: ret <2 x double> } ; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity. @@ -165,7 +165,7 @@ ; CHECK-LABEL: @test_simplify11v( %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %retval -; CHECK-NEXT: %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) +; CHECK-NEXT: ret <2 x float> %x } define double @test_simplify12(double %x) { @@ -179,7 +179,7 @@ ; CHECK-LABEL: @test_simplify12v( %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %retval -; CHECK-NEXT: %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) +; CHECK-NEXT: ret <2 x double> %x } ; Check pow(x, 2.0) -> x*x. @@ -195,7 +195,7 @@ define <2 x float> @pow2_strictv(<2 x float> %x) { ; CHECK-LABEL: @pow2_strictv( -; CHECK-NEXT: [[POW2:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) +; CHECK-NEXT: [[POW2:%.*]] = fmul <2 x float> %x, %x ; CHECK-NEXT: ret <2 x float> [[POW2]] ; %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) @@ -212,7 +212,7 @@ } define <2 x double> @pow2_double_strictv(<2 x double> %x) { ; CHECK-LABEL: @pow2_double_strictv( -; CHECK-NEXT: [[POW2:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) +; CHECK-NEXT: [[POW2:%.*]] = fmul <2 x double> %x, %x ; CHECK-NEXT: ret <2 x double> [[POW2]] ; %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) @@ -243,7 +243,7 @@ define <2 x float> @pow_neg1_strictv(<2 x float> %x) { ; CHECK-LABEL: @pow_neg1_strictv( -; CHECK-NEXT: [[POWRECIP:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) +; CHECK-NEXT: [[POWRECIP:%.*]] = fdiv <2 x float> , %x ; CHECK-NEXT: ret <2 x float> [[POWRECIP]] ; %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) @@ -261,7 +261,7 @@ define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) { ; CHECK-LABEL: @pow_neg1_double_fastv( -; CHECK-NEXT: [[POWRECIP:%.*]] = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) +; CHECK-NEXT: [[POWRECIP:%.*]] = fdiv fast <2 x double> , %x ; CHECK-NEXT: ret <2 x double> [[POWRECIP]] ; %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> )