Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1122,6 +1122,10 @@ return Op1; if (Op2C->isExactlyValue(2.0)) // pow(x, 2.0) -> x*x return B.CreateFMul(Op1, Op1, "pow2"); + if (Op2C->isExactlyValue(3.0)) { // pow(x, 3.0) -> x*x*x + Value *Pow2 = B.CreateFMul(Op1, Op1, "pow3"); + return B.CreateFMul(Pow2, Op1, "pow3"); + } if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), Op1, "powrecip"); return nullptr; Index: test/Transforms/InstCombine/pow-1.ll =================================================================== --- test/Transforms/InstCombine/pow-1.ll +++ test/Transforms/InstCombine/pow-1.ll @@ -188,5 +188,25 @@ ; CHECK-NO-EXP10: call double @pow } +; Check pow(x, 3.0) -> x*x*x. + +define float @test_simplify20(float %x) { +; CHECK-LABEL: @test_simplify20( + %retval = call float @powf(float %x, float 3.0) +; CHECK-NEXT: [[SQUARE:%[a-z0-9]+]] = fmul float %x, %x +; CHECK-NEXT: [[CUBE:%[a-z0-9]+]] = fmul float [[SQUARE]], %x + ret float %retval +; CHECK-NEXT: ret float [[CUBE]] +} + +define double @test_simplify21(double %x) { +; CHECK-LABEL: @test_simplify21( + %retval = call double @pow(double %x, double 3.0) +; CHECK-NEXT: [[SQUARE:%[a-z0-9]+]] = fmul double %x, %x +; CHECK-NEXT: [[CUBE:%[a-z0-9]+]] = fmul double [[SQUARE]], %x + ret double %retval +; CHECK-NEXT: ret double [[CUBE]] +} + ; CHECK: attributes [[NUW_RO]] = { nounwind readonly }