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 @@ -1668,10 +1668,6 @@ bool AllowApprox = Pow->hasApproxFunc(); bool Ignored; - // Bail out if simplifying libcalls to pow() is disabled. - if (!hasFloatFn(TLI, Ty, LibFunc_pow, LibFunc_powf, LibFunc_powl)) - return nullptr; - // Propagate the math semantics from the call to any created instructions. IRBuilderBase::FastMathFlagGuard Guard(B); B.setFastMathFlags(Pow->getFastMathFlags()); 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 @@ -38,9 +38,7 @@ define <2 x float> @test_simplify1v(<2 x float> %x) { ; CHECK-LABEL: @test_simplify1v( -; ANY-NEXT: ret <2 x float> -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: ret <2 x float> ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %x) ret <2 x float> %retval @@ -56,9 +54,7 @@ define <2 x double> @test_simplify2v(<2 x double> %x) { ; CHECK-LABEL: @test_simplify2v( -; ANY-NEXT: ret <2 x double> -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: ret <2 x double> ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %x) ret <2 x double> %retval @@ -198,9 +194,7 @@ define <2 x float> @test_simplify5v(<2 x float> %x) { ; CHECK-LABEL: @test_simplify5v( -; ANY-NEXT: ret <2 x float> -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> zeroinitializer) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: ret <2 x float> ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %retval @@ -216,9 +210,7 @@ define <2 x double> @test_simplify6v(<2 x double> %x) { ; CHECK-LABEL: @test_simplify6v( -; ANY-NEXT: ret <2 x double> -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> zeroinitializer) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: ret <2 x double> ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %retval @@ -306,9 +298,7 @@ define <2 x float> @test_simplify11v(<2 x float> %x) { ; CHECK-LABEL: @test_simplify11v( -; ANY-NEXT: ret <2 x float> [[X:%.*]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> ) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: ret <2 x float> [[X:%.*]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %retval @@ -324,9 +314,7 @@ define <2 x double> @test_simplify12v(<2 x double> %x) { ; CHECK-LABEL: @test_simplify12v( -; ANY-NEXT: ret <2 x double> [[X:%.*]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> ) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: ret <2 x double> [[X:%.*]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %retval @@ -353,10 +341,8 @@ define <2 x float> @pow2_strictv(<2 x float> %x) { ; CHECK-LABEL: @pow2_strictv( -; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]] -; ANY-NEXT: ret <2 x float> [[SQUARE]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> ) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]] +; CHECK-NEXT: ret <2 x float> [[SQUARE]] ; %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %r @@ -373,10 +359,8 @@ define <2 x double> @pow2_double_strictv(<2 x double> %x) { ; CHECK-LABEL: @pow2_double_strictv( -; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]] -; ANY-NEXT: ret <2 x double> [[SQUARE]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> ) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]] +; CHECK-NEXT: ret <2 x double> [[SQUARE]] ; %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %r @@ -422,10 +406,8 @@ define <2 x float> @pow_neg1_strictv(<2 x float> %x) { ; CHECK-LABEL: @pow_neg1_strictv( -; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> , [[X:%.*]] -; ANY-NEXT: ret <2 x float> [[RECIPROCAL]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> ) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> , [[X:%.*]] +; CHECK-NEXT: ret <2 x float> [[RECIPROCAL]] ; %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %r @@ -442,10 +424,8 @@ define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) { ; CHECK-LABEL: @pow_neg1_double_fastv( -; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> , [[X:%.*]] -; ANY-NEXT: ret <2 x double> [[RECIPROCAL]] -; MSVC-NEXT: [[POW:%.*]] = call fast <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> ) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> , [[X:%.*]] +; CHECK-NEXT: ret <2 x double> [[RECIPROCAL]] ; %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %r diff --git a/llvm/test/Transforms/InstCombine/pow-3.ll b/llvm/test/Transforms/InstCombine/pow-3.ll --- a/llvm/test/Transforms/InstCombine/pow-3.ll +++ b/llvm/test/Transforms/InstCombine/pow-3.ll @@ -8,8 +8,11 @@ define double @test_simplify_unavailable1(double %x) { ; CHECK-LABEL: @test_simplify_unavailable1( -; CHECK-NEXT: [[RETVAL:%.*]] = call double @llvm.pow.f64(double [[X:%.*]], double 5.000000e-01) -; CHECK-NEXT: ret double [[RETVAL]] +; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]]) +; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) +; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] +; CHECK-NEXT: ret double [[TMP1]] ; %retval = call double @llvm.pow.f64(double %x, double 0.5) ret double %retval diff --git a/llvm/test/Transforms/InstCombine/pow-amdgcn.ll b/llvm/test/Transforms/InstCombine/pow-amdgcn.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/pow-amdgcn.ll @@ -0,0 +1,55 @@ +; RUN: opt < %s -mtriple=amdgcn-- -targetlibinfo -instcombine -S | FileCheck %s + +; Check that a transform of llvm.pow to multiplies or divides happens for amdgcn (for which +; TLI says no lib functions). + +define float @pow_of_1(float %x) { +; CHECK-LABEL: @pow_of_1( +; CHECK-NEXT: ret float +; + %pow = call float @llvm.pow.f32(float 1.0, float %x) + ret float %pow +} + +define float @pow_minus_1(float %x) { +; CHECK-LABEL: @pow_minus_1( +; CHECK: = fdiv float +; + %pow = call float @llvm.pow.f32(float %x, float -1.0) + ret float %pow +} + +define float @pow_0(float %x) { +; CHECK-LABEL: @pow_0( +; CHECK-NEXT: ret float +; + %pow = call float @llvm.pow.f32(float %x, float 0.0) + ret float %pow +} + +define float @pow_1(float %x) { +; CHECK-LABEL: @pow_1( +; CHECK-NEXT: ret float +; + %pow = call float @llvm.pow.f32(float %x, float 1.0) + ret float %pow +} + +define float @pow_half(float %x) { +; CHECK-LABEL: @pow_half( +; CHECK: @llvm.sqrt +; + %pow = call float @llvm.pow.f32(float %x, float 0.5) + ret float %pow +} + +define float @pow_2(float %x) { +; CHECK-LABEL: @pow_2( +; CHECK: = fmul float +; + %pow = call float @llvm.pow.f32(float %x, float 2.0) + ret float %pow +} + +declare float @llvm.pow.f32(float, float) +