diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1534,7 +1534,8 @@ } // pow(2.0 ** n, x) -> exp2(n * x) - if (hasFloatFn(TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) { + if (Pow->doesNotAccessMemory() || + hasFloatFn(TLI, Ty, LibFunc_exp2, LibFunc_exp2f, LibFunc_exp2l)) { APFloat BaseR = APFloat(1.0); BaseR.convert(BaseF->getSemantics(), APFloat::rmTowardZero, &Ignored); BaseR = BaseR / *BaseF; diff --git a/llvm/test/Transforms/InstCombine/pow-1.ll b/llvm/test/Transforms/InstCombine/pow-1.ll --- a/llvm/test/Transforms/InstCombine/pow-1.ll +++ b/llvm/test/Transforms/InstCombine/pow-1.ll @@ -107,13 +107,8 @@ define <2 x float> @test_simplify3v(<2 x float> %x) { ; CHECK-LABEL: @test_simplify3v( -; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X:%.*]]) -; ANY-NEXT: ret <2 x float> [[EXP2]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) -; MSVC-NEXT: ret <2 x float> [[POW]] -; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls -; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) -; NOLIB-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X:%.*]]) +; CHECK-NEXT: ret <2 x float> [[EXP2]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %x) ret <2 x float> %retval @@ -121,14 +116,9 @@ define <2 x double> @test_simplify3vn(<2 x double> %x) { ; CHECK-LABEL: @test_simplify3vn( -; ANY-NEXT: [[MUL:%.*]] = fmul <2 x double> [[X:%.*]], -; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]]) -; ANY-NEXT: ret <2 x double> [[EXP2]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) -; MSVC-NEXT: ret <2 x double> [[POW]] -; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls -; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) -; NOLIB-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x double> [[X:%.*]], +; CHECK-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]]) +; CHECK-NEXT: ret <2 x double> [[EXP2]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %x) ret <2 x double> %retval @@ -174,13 +164,8 @@ define <2 x double> @test_simplify4v(<2 x double> %x) { ; CHECK-LABEL: @test_simplify4v( -; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X:%.*]]) -; ANY-NEXT: ret <2 x double> [[EXP2]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) -; MSVC-NEXT: ret <2 x double> [[POW]] -; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls -; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) -; NOLIB-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X:%.*]]) +; CHECK-NEXT: ret <2 x double> [[EXP2]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %x) ret <2 x double> %retval @@ -188,14 +173,9 @@ define <2 x float> @test_simplify4vn(<2 x float> %x) { ; CHECK-LABEL: @test_simplify4vn( -; ANY-NEXT: [[MUL:%.*]] = fneg <2 x float> [[X:%.*]] -; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]]) -; ANY-NEXT: ret <2 x float> [[EXP2]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) -; MSVC-NEXT: ret <2 x float> [[POW]] -; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls -; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) -; NOLIB-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: [[MUL:%.*]] = fneg <2 x float> [[X:%.*]] +; CHECK-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]]) +; CHECK-NEXT: ret <2 x float> [[EXP2]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %x) ret <2 x float> %retval