[llvm] afb24cb - AMDGPU: Don't require all flags to expand fast powr

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 1 05:22:22 PDT 2023


Author: Matt Arsenault
Date: 2023-09-01T08:22:16-04:00
New Revision: afb24cbb6965a8fd5329c8332112aa0de0af5d61

URL: https://github.com/llvm/llvm-project/commit/afb24cbb6965a8fd5329c8332112aa0de0af5d61
DIFF: https://github.com/llvm/llvm-project/commit/afb24cbb6965a8fd5329c8332112aa0de0af5d61.diff

LOG: AMDGPU: Don't require all flags to expand fast powr

This was requiring all fast math flags, which is practically
useless. This wouldn't fire using all the standard OpenCL fast math
flags. This only needs afn nnan and ninf.

https://reviews.llvm.org/D158904

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
    llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
    llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
    llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
index afe88c21d840be..bc4ad345ae2e53 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
@@ -114,6 +114,7 @@ class AMDGPULibCalls {
 
 protected:
   bool isUnsafeMath(const FPMathOperator *FPOp) const;
+  bool isUnsafeFiniteOnlyMath(const FPMathOperator *FPOp) const;
 
   bool canIncreasePrecisionOfConstantFold(const FPMathOperator *FPOp) const;
 
@@ -405,6 +406,11 @@ bool AMDGPULibCalls::isUnsafeMath(const FPMathOperator *FPOp) const {
   return UnsafeFPMath || FPOp->isFast();
 }
 
+bool AMDGPULibCalls::isUnsafeFiniteOnlyMath(const FPMathOperator *FPOp) const {
+  return UnsafeFPMath ||
+         (FPOp->hasApproxFunc() && FPOp->hasNoNaNs() && FPOp->hasNoInfs());
+}
+
 bool AMDGPULibCalls::canIncreasePrecisionOfConstantFold(
     const FPMathOperator *FPOp) const {
   // TODO: Refine to approxFunc or contract
@@ -819,10 +825,6 @@ bool AMDGPULibCalls::fold_pow(FPMathOperator *FPOp, IRBuilder<> &B,
     CINT = CDV ? dyn_cast_or_null<ConstantInt>(CDV->getSplatValue()) : nullptr;
   }
 
-  // No unsafe math , no constant argument, do nothing
-  if (!isUnsafeMath(FPOp) && !CF && !CINT && !CZero)
-    return false;
-
   // 0x1111111 means that we don't do anything for this call.
   int ci_opr1 = (CINT ? (int)CINT->getSExtValue() : 0x1111111);
 
@@ -878,7 +880,7 @@ bool AMDGPULibCalls::fold_pow(FPMathOperator *FPOp, IRBuilder<> &B,
     }
   }
 
-  if (!isUnsafeMath(FPOp))
+  if (!isUnsafeFiniteOnlyMath(FPOp))
     return false;
 
   // Unsafe Math optimization

diff  --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
index 5eb990d35f07c3..bca4646e76c49f 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
@@ -1675,8 +1675,9 @@ define float @test_pow_afn_f32__y_3(float %x) {
 define float @test_pow_afn_f32_nnan_ninf__y_3(float %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_3
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 3.000000e+00)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[X]]
+; CHECK-NEXT:    ret float [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 3.0)
   ret float %pow
@@ -1695,8 +1696,9 @@ define float @test_pow_afn_f32__y_4(float %x) {
 define float @test_pow_afn_f32_nnan_ninf__y_4(float %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_4
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 4.000000e+00)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    ret float [[__POWX21]]
 ;
   %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 4.0)
   ret float %pow
@@ -1725,8 +1727,10 @@ define float @test_pow_afn_f32__y_5(float %x) {
 define float @test_pow_afn_f32_nnan_ninf__y_5(float %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_5
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 5.000000e+00)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret float [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 5.0)
   ret float %pow
@@ -1745,8 +1749,11 @@ define float @test_pow_afn_f32__y_neg5(float %x) {
 define float @test_pow_afn_f32_nnan_ninf__y_neg5(float %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_neg5
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float -5.000000e+00)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[X]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWPROD]]
+; CHECK-NEXT:    ret float [[__1POWPROD]]
 ;
   %pow = tail call afn nnan ninf float @_Z3powff(float %x, float -5.0)
   ret float %pow
@@ -1755,8 +1762,11 @@ define float @test_pow_afn_f32_nnan_ninf__y_neg5(float %x) {
 define float @test_pow_afn_f32_nnan_ninf__y_10(float %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_10
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 1.000000e+01)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWX22:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[__POWX21]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX22]]
+; CHECK-NEXT:    ret float [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 10.0)
   ret float %pow
@@ -1765,8 +1775,10 @@ define float @test_pow_afn_f32_nnan_ninf__y_10(float %x) {
 define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_poison(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_poison
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> poison)
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[__FABS:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn <2 x float> @_Z4log2Dv2_f(<2 x float> [[__FABS]])
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn <2 x float> @_Z4exp2Dv2_f(<2 x float> poison)
+; CHECK-NEXT:    ret <2 x float> poison
 ;
   %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> poison)
   ret <2 x float> %pow
@@ -1775,8 +1787,9 @@ define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_poison(<2 x float> %x) {
 define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_3(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_3
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 3.000000e+00, float 3.000000e+00>)
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 3.0, float 3.0>)
   ret <2 x float> %pow
@@ -1785,8 +1798,9 @@ define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_3(<2 x float> %x) {
 define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 4.000000e+00, float 4.000000e+00>)
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    ret <2 x float> [[__POWX21]]
 ;
   %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 4.0, float 4.0>)
   ret <2 x float> %pow
@@ -1815,8 +1829,10 @@ define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4_5_undef(<2 x float> %x) {
 define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_5(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_5
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 5.000000e+00, float 5.000000e+00>)
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 5.0, float 5.0>)
   ret <2 x float> %pow
@@ -1825,8 +1841,10 @@ define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_5(<2 x float> %x) {
 define float @test_pow_afn_f32_nnan_ninf__y_5_known_positive(float nofpclass(ninf nsub nnorm) %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_5_known_positive
 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 5.000000e+00)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret float [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 5.0)
   ret float %pow
@@ -1836,8 +1854,10 @@ define float @test_pow_afn_f32_nnan_ninf__y_5_known_positive(float nofpclass(nin
 define float @test_pow_afn_f32_nnan_ninf__y_5_known_positive_with_ninf_flag(float nofpclass(nsub nnorm) %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_5_known_positive_with_ninf_flag
 ; CHECK-SAME: (float nofpclass(nsub nnorm) [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 5.000000e+00)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret float [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 5.0)
   ret float %pow
@@ -1856,8 +1876,9 @@ define double @test_pow_afn_f64__y_3(double %x) {
 define double @test_pow_afn_f64_nnan_ninf__y_3(double %x) {
 ; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_3
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double 3.000000e+00)
-; CHECK-NEXT:    ret double [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn double [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn double [[__POWX2]], [[X]]
+; CHECK-NEXT:    ret double [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double 3.0)
   ret double %pow
@@ -1876,8 +1897,9 @@ define double @test_pow_afn_f64__y_4(double %x) {
 define double @test_pow_afn_f64_nnan_ninf__y_4(double %x) {
 ; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_4
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double 4.000000e+00)
-; CHECK-NEXT:    ret double [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn double [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn double [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    ret double [[__POWX21]]
 ;
   %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double 4.0)
   ret double %pow
@@ -1906,8 +1928,10 @@ define double @test_pow_afn_f64__y_5(double %x) {
 define double @test_pow_afn_f64_nnan_ninf__y_5(double %x) {
 ; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_5
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double 5.000000e+00)
-; CHECK-NEXT:    ret double [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn double [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn double [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn double [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret double [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double 5.0)
   ret double %pow
@@ -1926,8 +1950,11 @@ define double @test_pow_afn_f64__y_neg5(double %x) {
 define double @test_pow_afn_f64_nnan_ninf__y_neg5(double %x) {
 ; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_neg5
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double -5.000000e+00)
-; CHECK-NEXT:    ret double [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn double [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn double [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn double [[__POWX21]], [[X]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn double 1.000000e+00, [[__POWPROD]]
+; CHECK-NEXT:    ret double [[__1POWPROD]]
 ;
   %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double -5.0)
   ret double %pow
@@ -1936,8 +1963,11 @@ define double @test_pow_afn_f64_nnan_ninf__y_neg5(double %x) {
 define double @test_pow_afn_f64_nnan_ninf__y_10(double %x) {
 ; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_10
 ; CHECK-SAME: (double [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double 1.000000e+01)
-; CHECK-NEXT:    ret double [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn double [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn double [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWX22:%.*]] = fmul nnan ninf afn double [[__POWX21]], [[__POWX21]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn double [[__POWX2]], [[__POWX22]]
+; CHECK-NEXT:    ret double [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double 10.0)
   ret double %pow
@@ -1946,8 +1976,9 @@ define double @test_pow_afn_f64_nnan_ninf__y_10(double %x) {
 define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_3(<2 x double> %x) {
 ; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_3
 ; CHECK-SAME: (<2 x double> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> <double 3.000000e+00, double 3.000000e+00>)
-; CHECK-NEXT:    ret <2 x double> [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x double> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x double> [[__POWX2]], [[X]]
+; CHECK-NEXT:    ret <2 x double> [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> <double 3.0, double 3.0>)
   ret <2 x double> %pow
@@ -1956,8 +1987,9 @@ define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_3(<2 x double> %x) {
 define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_4(<2 x double> %x) {
 ; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_4
 ; CHECK-SAME: (<2 x double> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> <double 4.000000e+00, double 4.000000e+00>)
-; CHECK-NEXT:    ret <2 x double> [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x double> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn <2 x double> [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    ret <2 x double> [[__POWX21]]
 ;
   %pow = tail call afn nnan ninf <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> <double 4.0, double 4.0>)
   ret <2 x double> %pow
@@ -1976,8 +2008,10 @@ define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_4_5(<2 x double> %x) {
 define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_5(<2 x double> %x) {
 ; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_5
 ; CHECK-SAME: (<2 x double> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> <double 5.000000e+00, double 5.000000e+00>)
-; CHECK-NEXT:    ret <2 x double> [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x double> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn <2 x double> [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x double> [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret <2 x double> [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> <double 5.0, double 5.0>)
   ret <2 x double> %pow
@@ -1996,8 +2030,9 @@ define half @test_pow_afn_f16__y_3(half %x) {
 define half @test_pow_afn_f16_nnan_ninf__y_3(half %x) {
 ; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_3
 ; CHECK-SAME: (half [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xH4200)
-; CHECK-NEXT:    ret half [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn half [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn half [[__POWX2]], [[X]]
+; CHECK-NEXT:    ret half [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half 3.0)
   ret half %pow
@@ -2016,8 +2051,9 @@ define half @test_pow_afn_f16__y_4(half %x) {
 define half @test_pow_afn_f16_nnan_ninf__y_4(half %x) {
 ; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_4
 ; CHECK-SAME: (half [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xH4400)
-; CHECK-NEXT:    ret half [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn half [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn half [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    ret half [[__POWX21]]
 ;
   %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half 4.0)
   ret half %pow
@@ -2046,8 +2082,10 @@ define half @test_pow_afn_f16__y_5(half %x) {
 define half @test_pow_afn_f16_nnan_ninf__y_5(half %x) {
 ; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_5
 ; CHECK-SAME: (half [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xH4500)
-; CHECK-NEXT:    ret half [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn half [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn half [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn half [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret half [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half 5.0)
   ret half %pow
@@ -2066,8 +2104,11 @@ define half @test_pow_afn_f16__y_neg5(half %x) {
 define half @test_pow_afn_f16_nnan_ninf__y_neg5(half %x) {
 ; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_neg5
 ; CHECK-SAME: (half [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xHC500)
-; CHECK-NEXT:    ret half [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn half [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn half [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn half [[__POWX21]], [[X]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn half 0xH3C00, [[__POWPROD]]
+; CHECK-NEXT:    ret half [[__1POWPROD]]
 ;
   %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half -5.0)
   ret half %pow
@@ -2076,8 +2117,11 @@ define half @test_pow_afn_f16_nnan_ninf__y_neg5(half %x) {
 define half @test_pow_afn_f16_nnan_ninf__y_10(half %x) {
 ; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_10
 ; CHECK-SAME: (half [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xH4900)
-; CHECK-NEXT:    ret half [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn half [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn half [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWX22:%.*]] = fmul nnan ninf afn half [[__POWX21]], [[__POWX21]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn half [[__POWX2]], [[__POWX22]]
+; CHECK-NEXT:    ret half [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half 10.0)
   ret half %pow
@@ -2086,8 +2130,9 @@ define half @test_pow_afn_f16_nnan_ninf__y_10(half %x) {
 define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_3(<2 x half> %x) {
 ; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_3
 ; CHECK-SAME: (<2 x half> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> <half 0xH4200, half 0xH4200>)
-; CHECK-NEXT:    ret <2 x half> [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x half> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x half> [[__POWX2]], [[X]]
+; CHECK-NEXT:    ret <2 x half> [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> <half 3.0, half 3.0>)
   ret <2 x half> %pow
@@ -2096,8 +2141,9 @@ define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_3(<2 x half> %x) {
 define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_4(<2 x half> %x) {
 ; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_4
 ; CHECK-SAME: (<2 x half> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> <half 0xH4400, half 0xH4400>)
-; CHECK-NEXT:    ret <2 x half> [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x half> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn <2 x half> [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    ret <2 x half> [[__POWX21]]
 ;
   %pow = tail call afn nnan ninf <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> <half 4.0, half 4.0>)
   ret <2 x half> %pow
@@ -2116,8 +2162,10 @@ define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_4_5(<2 x half> %x) {
 define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_5(<2 x half> %x) {
 ; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_5
 ; CHECK-SAME: (<2 x half> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> <half 0xH4500, half 0xH4500>)
-; CHECK-NEXT:    ret <2 x half> [[POW]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x half> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn <2 x half> [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x half> [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret <2 x half> [[__POWPROD]]
 ;
   %pow = tail call afn nnan ninf <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> <half 5.0, half 5.0>)
   ret <2 x half> %pow

diff  --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
index b2aca1bf9d0956..7f8b8f944857d3 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
@@ -674,8 +674,18 @@ define float @test_pown_afn_nnan_ninf_f32(float %x, i32 %y) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32
 ; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 [[Y]])
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__FABS:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn float @_Z4log2f(float [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn float [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn float @_Z4exp2f(float [[__YLOGX]])
+; CHECK-NEXT:    [[__YEVEN:%.*]] = shl i32 [[Y]], 31
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast float [[X]] to i32
+; CHECK-NEXT:    [[__POW_SIGN:%.*]] = and i32 [[__YEVEN]], [[TMP0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[__EXP2]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[__POW_SIGN]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32 [[TMP2]] to float
+; CHECK-NEXT:    ret float [[TMP3]]
 ;
 entry:
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 %y)
@@ -686,8 +696,19 @@ define <2 x float> @test_pown_afn_nnan_ninf_v2f32(<2 x float> %x, <2 x i32> %y)
 ; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32
 ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[CALL]]
+; CHECK-NEXT:    [[__FABS:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn <2 x float> @_Z4log2Dv2_f(<2 x float> [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp <2 x i32> [[Y]] to <2 x float>
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn <2 x float> [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn <2 x float> @_Z4exp2Dv2_f(<2 x float> [[__YLOGX]])
+; CHECK-NEXT:    [[__YTOU:%.*]] = fptosi <2 x float> [[POWNI2F]] to <2 x i32>
+; CHECK-NEXT:    [[__YEVEN:%.*]] = shl <2 x i32> [[__YTOU]], <i32 31, i32 31>
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
+; CHECK-NEXT:    [[__POW_SIGN:%.*]] = and <2 x i32> [[__YEVEN]], [[TMP0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x float> [[__EXP2]] to <2 x i32>
+; CHECK-NEXT:    [[TMP2:%.*]] = or <2 x i32> [[__POW_SIGN]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast <2 x i32> [[TMP2]] to <2 x float>
+; CHECK-NEXT:    ret <2 x float> [[TMP3]]
 ;
 entry:
   %call = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> %y)
@@ -698,8 +719,19 @@ define double @test_pown_afn_nnan_ninf_f64(double %x, i32 %y) {
 ; CHECK-LABEL: define double @test_pown_afn_nnan_ninf_f64
 ; CHECK-SAME: (double [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn double @_Z4powndi(double [[X]], i32 [[Y]])
-; CHECK-NEXT:    ret double [[CALL]]
+; CHECK-NEXT:    [[__FABS:%.*]] = call nnan ninf afn double @llvm.fabs.f64(double [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn double @_Z4log2d(double [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp i32 [[Y]] to double
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn double [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn double @_Z4exp2d(double [[__YLOGX]])
+; CHECK-NEXT:    [[__YTOU:%.*]] = zext i32 [[Y]] to i64
+; CHECK-NEXT:    [[__YEVEN:%.*]] = shl i64 [[__YTOU]], 63
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast double [[X]] to i64
+; CHECK-NEXT:    [[__POW_SIGN:%.*]] = and i64 [[__YEVEN]], [[TMP0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast double [[__EXP2]] to i64
+; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[__POW_SIGN]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i64 [[TMP2]] to double
+; CHECK-NEXT:    ret double [[TMP3]]
 ;
 entry:
   %call = tail call nnan ninf afn double @_Z4powndi(double %x, i32 %y)
@@ -710,8 +742,19 @@ define <2 x double> @test_pown_afn_nnan_ninf_v2f64(<2 x double> %x, <2 x i32> %y
 ; CHECK-LABEL: define <2 x double> @test_pown_afn_nnan_ninf_v2f64
 ; CHECK-SAME: (<2 x double> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x double> @_Z4pownDv2_dDv2_i(<2 x double> [[X]], <2 x i32> [[Y]])
-; CHECK-NEXT:    ret <2 x double> [[CALL]]
+; CHECK-NEXT:    [[__FABS:%.*]] = call nnan ninf afn <2 x double> @llvm.fabs.v2f64(<2 x double> [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn <2 x double> @_Z4log2Dv2_d(<2 x double> [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp <2 x i32> [[Y]] to <2 x double>
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn <2 x double> [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn <2 x double> @_Z4exp2Dv2_d(<2 x double> [[__YLOGX]])
+; CHECK-NEXT:    [[__YTOU1:%.*]] = zext <2 x i32> [[Y]] to <2 x i64>
+; CHECK-NEXT:    [[__YEVEN:%.*]] = shl <2 x i64> [[__YTOU1]], <i64 63, i64 63>
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x double> [[X]] to <2 x i64>
+; CHECK-NEXT:    [[__POW_SIGN:%.*]] = and <2 x i64> [[__YEVEN]], [[TMP0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x double> [[__EXP2]] to <2 x i64>
+; CHECK-NEXT:    [[TMP2:%.*]] = or <2 x i64> [[__POW_SIGN]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to <2 x double>
+; CHECK-NEXT:    ret <2 x double> [[TMP3]]
 ;
 entry:
   %call = tail call nnan ninf afn <2 x double> @_Z4pownDv2_dDv2_i(<2 x double> %x, <2 x i32> %y)
@@ -722,8 +765,19 @@ define half @test_pown_afn_nnan_ninf_f16(half %x, i32 %y) {
 ; CHECK-LABEL: define half @test_pown_afn_nnan_ninf_f16
 ; CHECK-SAME: (half [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn half @_Z4pownDhi(half [[X]], i32 [[Y]])
-; CHECK-NEXT:    ret half [[CALL]]
+; CHECK-NEXT:    [[__FABS:%.*]] = call nnan ninf afn half @llvm.fabs.f16(half [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn half @_Z4log2Dh(half [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp i32 [[Y]] to half
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn half [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn half @_Z4exp2Dh(half [[__YLOGX]])
+; CHECK-NEXT:    [[__YTOU:%.*]] = trunc i32 [[Y]] to i16
+; CHECK-NEXT:    [[__YEVEN:%.*]] = shl i16 [[__YTOU]], 15
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast half [[X]] to i16
+; CHECK-NEXT:    [[__POW_SIGN:%.*]] = and i16 [[__YEVEN]], [[TMP0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast half [[__EXP2]] to i16
+; CHECK-NEXT:    [[TMP2:%.*]] = or i16 [[__POW_SIGN]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i16 [[TMP2]] to half
+; CHECK-NEXT:    ret half [[TMP3]]
 ;
 entry:
   %call = tail call nnan ninf afn half @_Z4pownDhi(half %x, i32 %y)
@@ -734,8 +788,19 @@ define <2 x half> @test_pown_afn_nnan_ninf_v2f16(<2 x half> %x, <2 x i32> %y) {
 ; CHECK-LABEL: define <2 x half> @test_pown_afn_nnan_ninf_v2f16
 ; CHECK-SAME: (<2 x half> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x half> @_Z4pownDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> [[Y]])
-; CHECK-NEXT:    ret <2 x half> [[CALL]]
+; CHECK-NEXT:    [[__FABS:%.*]] = call nnan ninf afn <2 x half> @llvm.fabs.v2f16(<2 x half> [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn <2 x half> @_Z4log2Dv2_Dh(<2 x half> [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp <2 x i32> [[Y]] to <2 x half>
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn <2 x half> [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn <2 x half> @_Z4exp2Dv2_Dh(<2 x half> [[__YLOGX]])
+; CHECK-NEXT:    [[__YTOU:%.*]] = fptosi <2 x half> [[POWNI2F]] to <2 x i16>
+; CHECK-NEXT:    [[__YEVEN:%.*]] = shl <2 x i16> [[__YTOU]], <i16 15, i16 15>
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x half> [[X]] to <2 x i16>
+; CHECK-NEXT:    [[__POW_SIGN:%.*]] = and <2 x i16> [[__YEVEN]], [[TMP0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x half> [[__EXP2]] to <2 x i16>
+; CHECK-NEXT:    [[TMP2:%.*]] = or <2 x i16> [[__POW_SIGN]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast <2 x i16> [[TMP2]] to <2 x half>
+; CHECK-NEXT:    ret <2 x half> [[TMP3]]
 ;
 entry:
   %call = tail call nnan ninf afn <2 x half> @_Z4pownDv2_DhDv2_i(<2 x half> %x, <2 x i32> %y)
@@ -791,8 +856,9 @@ define float @test_pown_fast_f32__y_poison(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_3(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_3
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 3)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[X]]
+; CHECK-NEXT:    ret float [[__POWPROD]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 3)
   ret float %call
@@ -801,8 +867,10 @@ define float @test_pown_afn_nnan_ninf_f32__y_3(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_neg3(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg3
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -3)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[X]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWPROD]]
+; CHECK-NEXT:    ret float [[__1POWPROD]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -3)
   ret float %call
@@ -811,8 +879,9 @@ define float @test_pown_afn_nnan_ninf_f32__y_neg3(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_4(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_4
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 4)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    ret float [[__POWX21]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 4)
   ret float %call
@@ -821,8 +890,10 @@ define float @test_pown_afn_nnan_ninf_f32__y_4(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_neg4(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg4
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -4)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWX21]]
+; CHECK-NEXT:    ret float [[__1POWPROD]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -4)
   ret float %call
@@ -831,8 +902,10 @@ define float @test_pown_afn_nnan_ninf_f32__y_neg4(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_5(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_5
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 5)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret float [[__POWPROD]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 5)
   ret float %call
@@ -841,8 +914,11 @@ define float @test_pown_afn_nnan_ninf_f32__y_5(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_neg5(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg5
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -5)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[X]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWPROD]]
+; CHECK-NEXT:    ret float [[__1POWPROD]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -5)
   ret float %call
@@ -851,8 +927,11 @@ define float @test_pown_afn_nnan_ninf_f32__y_neg5(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_7(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_7
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 7)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD2:%.*]] = fmul nnan ninf afn float [[__POWPROD]], [[__POWX21]]
+; CHECK-NEXT:    ret float [[__POWPROD2]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 7)
   ret float %call
@@ -861,8 +940,12 @@ define float @test_pown_afn_nnan_ninf_f32__y_7(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_neg7(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg7
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -7)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD2:%.*]] = fmul nnan ninf afn float [[__POWPROD]], [[__POWX21]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWPROD2]]
+; CHECK-NEXT:    ret float [[__1POWPROD]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -7)
   ret float %call
@@ -871,8 +954,10 @@ define float @test_pown_afn_nnan_ninf_f32__y_neg7(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_8(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_8
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 8)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWX22:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[__POWX21]]
+; CHECK-NEXT:    ret float [[__POWX22]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 8)
   ret float %call
@@ -881,8 +966,11 @@ define float @test_pown_afn_nnan_ninf_f32__y_8(float %x) {
 define float @test_pown_afn_nnan_ninf_f32__y_neg8(float %x) {
 ; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg8
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -8)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWX22:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[__POWX21]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWX22]]
+; CHECK-NEXT:    ret float [[__1POWPROD]]
 ;
   %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -8)
   ret float %call
@@ -892,8 +980,9 @@ define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_3(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_3
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 3, i32 3>)
-; CHECK-NEXT:    ret <2 x float> [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POWPROD]]
 ;
 entry:
   %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 3, i32 3>)
@@ -904,8 +993,9 @@ define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_4(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_4
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 4, i32 4>)
-; CHECK-NEXT:    ret <2 x float> [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    ret <2 x float> [[__POWX21]]
 ;
 entry:
   %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 4, i32 4>)
@@ -916,8 +1006,10 @@ define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_neg3(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_neg3
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 -3, i32 -3>)
-; CHECK-NEXT:    ret <2 x float> [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[X]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[__POWPROD]]
+; CHECK-NEXT:    ret <2 x float> [[__1POWPROD]]
 ;
 entry:
   %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 -3, i32 -3>)
@@ -928,8 +1020,10 @@ define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_neg4(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_neg4
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 -4, i32 -4>)
-; CHECK-NEXT:    ret <2 x float> [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__1POWPROD:%.*]] = fdiv nnan ninf afn <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[__POWX21]]
+; CHECK-NEXT:    ret <2 x float> [[__1POWPROD]]
 ;
 entry:
   %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 -4, i32 -4>)
@@ -940,8 +1034,10 @@ define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_5(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_5
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 5, i32 5>)
-; CHECK-NEXT:    ret <2 x float> [[CALL]]
+; CHECK-NEXT:    [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    [[__POWX21:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[__POWX2]]
+; CHECK-NEXT:    [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX21]], [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POWPROD]]
 ;
 entry:
   %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 5, i32 5>)
@@ -976,8 +1072,18 @@ define float @test_pown_afn_ninf_nnan_f32__x_known_positive(float nofpclass(ninf
 ; CHECK-LABEL: define float @test_pown_afn_ninf_nnan_f32__x_known_positive
 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 [[Y]])
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[__FABS:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn float @_Z4log2f(float [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn float [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn float @_Z4exp2f(float [[__YLOGX]])
+; CHECK-NEXT:    [[__YEVEN:%.*]] = shl i32 [[Y]], 31
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast float [[X]] to i32
+; CHECK-NEXT:    [[__POW_SIGN:%.*]] = and i32 [[__YEVEN]], [[TMP0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[__EXP2]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[__POW_SIGN]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32 [[TMP2]] to float
+; CHECK-NEXT:    ret float [[TMP3]]
 ;
 entry:
   %call = tail call afn ninf nnan float @_Z4pownfi(float %x, i32 %y)

diff  --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll
index 9c136c946ab92f..e08a182a3cd67e 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll
@@ -1013,8 +1013,10 @@ define float @test_powr_afn_f32_nnan_x_known_positive(float nofpclass(ninf nnorm
 define float @test_powr_afn_f32_nnan_ninf_x_known_positive(float nofpclass(ninf nnorm nsub) %x, float %y) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_nnan_ninf_x_known_positive
 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn float @_Z4powrff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn float @_Z4log2f(float [[X]])
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn float [[__LOG2]], [[Y]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn float @_Z4exp2f(float [[__YLOGX]])
+; CHECK-NEXT:    ret float [[__EXP2]]
 ;
   %powr = tail call afn nnan ninf float @_Z4powrff(float %x, float %y)
   ret float %powr
@@ -1033,8 +1035,10 @@ define <2 x float> @test_powr_afn_v2f32_nnan_x_known_positive(<2 x float> nofpcl
 define <2 x float> @test_powr_afn_v2f32_nnan_ninf_x_known_positive(<2 x float> nofpclass(ninf nnorm nsub) %x, <2 x float> %y) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_nnan_ninf_x_known_positive
 ; CHECK-SAME: (<2 x float> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn <2 x float> @_Z4log2Dv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn <2 x float> [[__LOG2]], [[Y]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn <2 x float> @_Z4exp2Dv2_f(<2 x float> [[__YLOGX]])
+; CHECK-NEXT:    ret <2 x float> [[__EXP2]]
 ;
   %powr = tail call afn nnan ninf <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
   ret <2 x float> %powr
@@ -1108,8 +1112,10 @@ define float @test_powr_afn_nnan_ninf_f32_known_integral_sitofp(float %x, i32 %y
 ; CHECK-LABEL: define float @test_powr_afn_nnan_ninf_f32_known_integral_sitofp
 ; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
-; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn float @_Z4powrff(float [[X]], float [[Y_CAST]])
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn float @_Z4log2f(float [[X]])
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn float [[__LOG2]], [[Y_CAST]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn float @_Z4exp2f(float [[__YLOGX]])
+; CHECK-NEXT:    ret float [[__EXP2]]
 ;
   %y.cast = sitofp i32 %y to float
   %powr = tail call afn nnan ninf float @_Z4powrff(float %x, float %y.cast)
@@ -1144,8 +1150,10 @@ define float @test_powr_afn_nnan_ninf_f32_known_integral_uitofp(float %x, i32 %y
 ; CHECK-LABEL: define float @test_powr_afn_nnan_ninf_f32_known_integral_uitofp
 ; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp i32 [[Y]] to float
-; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn float @_Z4powrff(float [[X]], float [[Y_CAST]])
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn float @_Z4log2f(float [[X]])
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn float [[__LOG2]], [[Y_CAST]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn float @_Z4exp2f(float [[__YLOGX]])
+; CHECK-NEXT:    ret float [[__EXP2]]
 ;
   %y.cast = uitofp i32 %y to float
   %powr = tail call afn nnan ninf float @_Z4powrff(float %x, float %y.cast)
@@ -1156,8 +1164,10 @@ define <2 x float> @test_powr_afn_nnan_ninf_v2f32_known_integral_sitofp(<2 x flo
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_nnan_ninf_v2f32_known_integral_sitofp
 ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
 ; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp <2 x i32> [[Y]] to <2 x float>
-; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn <2 x float> @_Z4log2Dv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn <2 x float> [[__LOG2]], [[Y_CAST]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn <2 x float> @_Z4exp2Dv2_f(<2 x float> [[__YLOGX]])
+; CHECK-NEXT:    ret <2 x float> [[__EXP2]]
 ;
   %y.cast = sitofp <2 x i32> %y to <2 x float>
   %powr = tail call afn nnan ninf <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y.cast)
@@ -1192,8 +1202,10 @@ define <2 x float> @test_powr_afn_nnan_ninf_v2f32_known_integral_uitofp(<2 x flo
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_nnan_ninf_v2f32_known_integral_uitofp
 ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
 ; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp <2 x i32> [[Y]] to <2 x float>
-; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[__LOG2:%.*]] = call nnan ninf afn <2 x float> @_Z4log2Dv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul nnan ninf afn <2 x float> [[__LOG2]], [[Y_CAST]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call nnan ninf afn <2 x float> @_Z4exp2Dv2_f(<2 x float> [[__YLOGX]])
+; CHECK-NEXT:    ret <2 x float> [[__EXP2]]
 ;
   %y.cast = uitofp <2 x i32> %y to <2 x float>
   %powr = tail call afn nnan ninf <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y.cast)


        


More information about the llvm-commits mailing list