[llvm] AMDGPU: Libcall expand fast pow/powr/pown/rootn for float case (PR #180553)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 9 07:58:54 PST 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/180553

This is to eliminate the special case global unsafe math options
in these functions from the library. The core operation only
uses about 4 instructions, and then there's an additional prolog
and/or epilog to fixup special cases.

I have an alternative patch which implements this by using separate
entrypoints in the library, and having the pass replace the calls
instead of this full handling. However, given the unfortunate state
of library development, it requires a full year to make cross project
changes. This is the most expedient path to deleting the control library;
in the future we can do libcall emission when compiler has the real
ability to properly emit new calls.

This is mostly a direct port of these functions:
https://github.com/ROCm/llvm-project/blob/amd-staging/amd/device-libs/ocml/src/powF_base.h

I used copilot to do the heavy lifting on the drudgery of writing out
all the IRBuilder calls. It mostly worked, though it made mistakes in
porting != (used the ONE instead of UNE), plus some API usage errors.

The exact output isn't exactly the same. The ordering of some instructions
is different and some conditions and selects are inverted. This expansion
also preserves the flags, so the finite only case optimizes better than
with the library code (this is largely because fast math flags aren't propagated
yet, except for the few places SimplifyDemandedFPClass is called).

Alive2 verifies the library function with the special fast math path
functions have the same behavior as the result of this expansion. afn
only case: https://alive2.llvm.org/ce/z/uoPBC2

I did not bother trying to specially optimize the finite only cases here.
They get cleaned up by instcombine anyway, so doing so would only be a
hypothetical compile time improvement for a lot of additional complexity.
The exception would be existing, overlapped code in the pass.
There's some overlap here with existing code in the pass. The afn+ninf+nnan
case for powr already does the rewrite to the 4 instruction core sequence,
which takes precedence over this. In the future this should be merged,
but it's more annoying now since the old path also handles it for the f64
case via libcall emission since the intrinsic won't work.

>From deae092893e3721bc17281e8d92c49c208ddf1b0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sun, 20 Aug 2023 11:03:11 -0400
Subject: [PATCH] AMDGPU: Libcall expand fast pow/powr/pown/rootn for float
 case

This is to eliminate the special case global unsafe math options
in these functions from the library. The core operation only
uses about 4 instructions, and then there's an additional prolog
and/or epilog to fixup special cases.

I have an alternative patch which implements this by using separate
entrypoints in the library, and having the pass replace the calls
instead of this full handling. However, given the unfortunate state
of library development, it requires a full year to make cross project
changes. This is the most expedient path to deleting the control library;
in the future we can do libcall emission when compiler has the real
ability to properly emit new calls.

This is mostly a direct port of these functions:
https://github.com/ROCm/llvm-project/blob/amd-staging/amd/device-libs/ocml/src/powF_base.h

I used copilot to do the heavy lifting on the drudgery of writing out
all the IRBuilder calls. It mostly worked, though it made mistakes in
porting != (used the ONE instead of UNE), plus some API usage errors.

The exact output isn't exactly the same. The ordering of some instructions
is different and some conditions and selects are inverted. This expansion
also preserves the flags, so the finite only case optimizes better than
with the library code (this is largely because fast math flags aren't propagated
yet, except for the few places SimplifyDemandedFPClass is called).

Alive2 verifies the library function with the special fast math path
functions have the same behavior as the result of this expansion. afn
only case: https://alive2.llvm.org/ce/z/uoPBC2

I did not bother trying to specially optimize the finite only cases here.
They get cleaned up by instcombine anyway, so doing so would only be a
hypothetical compile time improvement for a lot of additional complexity.
The exception would be existing, overlapped code in the pass.
There's some overlap here with existing code in the pass. The afn+ninf+nnan
case for powr already does the rewrite to the 4 instruction core sequence,
which takes precedence over this. In the future this should be merged,
but it's more annoying now since the old path also handles it for the f64
case via libcall emission since the intrinsic won't work.
---
 llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp     |  288 ++++-
 .../amdgpu-simplify-libcall-pow-codegen.ll    |   49 +-
 .../AMDGPU/amdgpu-simplify-libcall-pow.ll     | 1094 ++++++++++++++++-
 .../AMDGPU/amdgpu-simplify-libcall-pown.ll    |   85 +-
 .../AMDGPU/amdgpu-simplify-libcall-powr.ll    |  829 +++++++++++--
 .../AMDGPU/amdgpu-simplify-libcall-rootn.ll   |  362 +++++-
 llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll |   18 +-
 7 files changed, 2523 insertions(+), 202 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
index 4de9349fe5166..d0c13d154995d 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
@@ -19,6 +19,7 @@
 #include "llvm/IR/AttributeMask.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/MDBuilder.h"
 #include "llvm/IR/PatternMatch.h"
 #include <cmath>
@@ -43,6 +44,8 @@ static cl::list<std::string> UseNative("amdgpu-use-native",
 #define MATH_SQRT2   numbers::sqrt2
 #define MATH_SQRT1_2 numbers::inv_sqrt2
 
+enum class PowKind { Pow, PowR, PowN, RootN };
+
 namespace llvm {
 
 class AMDGPULibCalls {
@@ -69,6 +72,9 @@ class AMDGPULibCalls {
   // pow/powr/pown
   bool fold_pow(FPMathOperator *FPOp, IRBuilder<> &B, const FuncInfo &FInfo);
 
+  /// Peform a fast math expansion of pow, powr, pown or rootn.
+  bool expandFastPow(FPMathOperator *FPOp, IRBuilder<> &B, PowKind Kind);
+
   // rootn
   bool fold_rootn(FPMathOperator *FPOp, IRBuilder<> &B, const FuncInfo &FInfo);
 
@@ -710,13 +716,35 @@ bool AMDGPULibCalls::fold(CallInst *CI) {
         }
       }
 
-      return fold_pow(FPOp, B, FInfo);
+      if (fold_pow(FPOp, B, FInfo))
+        return true;
+
+      if (!FMF.approxFunc())
+        return false;
+      return expandFastPow(FPOp, B, PowKind::Pow);
     }
     case AMDGPULibFunc::EI_POWR:
+      if (fold_pow(FPOp, B, FInfo))
+        return true;
+      if (!FMF.approxFunc())
+        return false;
+      if (!shouldReplaceLibcallWithIntrinsic(CI))
+        return false;
+      return expandFastPow(FPOp, B, PowKind::PowR);
     case AMDGPULibFunc::EI_POWN:
-      return fold_pow(FPOp, B, FInfo);
+      if (fold_pow(FPOp, B, FInfo))
+        return true;
+      if (!FMF.approxFunc())
+        return false;
+      if (!shouldReplaceLibcallWithIntrinsic(CI))
+        return false;
+      return expandFastPow(FPOp, B, PowKind::PowN);
     case AMDGPULibFunc::EI_ROOTN:
-      return fold_rootn(FPOp, B, FInfo);
+      if (fold_rootn(FPOp, B, FInfo))
+        return true;
+      if (!FMF.approxFunc())
+        return false;
+      return expandFastPow(FPOp, B, PowKind::RootN);
     case AMDGPULibFunc::EI_SQRT:
       // TODO: Allow with strictfp + constrained intrinsic
       return tryReplaceLibcallWithSimpleIntrinsic(
@@ -1170,6 +1198,260 @@ bool AMDGPULibCalls::fold_rootn(FPMathOperator *FPOp, IRBuilder<> &B,
   return false;
 }
 
+// is_integer(y) => trunc(y) == y
+static Value *emitIsInteger(IRBuilder<> &B, Value *Y) {
+  Value *TruncY = B.CreateUnaryIntrinsic(Intrinsic::trunc, Y);
+  return B.CreateFCmpOEQ(TruncY, Y);
+}
+
+static Value *emitIsEvenInteger(IRBuilder<> &B, Value *Y) {
+  // Even integers are still integers after division by 2.
+  auto *HalfY = B.CreateFMul(Y, ConstantFP::get(Y->getType(), 0.5));
+  return emitIsInteger(B, HalfY);
+}
+
+// is_odd_integer(y) => is_integer(y) && !is_even_integer(y)
+static Value *emitIsOddInteger(IRBuilder<> &B, Value *Y) {
+  Value *IsIntY = emitIsInteger(B, Y);
+  Value *IsEvenY = emitIsEvenInteger(B, Y);
+  Value *NotEvenY = B.CreateNot(IsEvenY);
+  return B.CreateAnd(IsIntY, NotEvenY);
+}
+
+// isinf(val) => fabs(val) == +inf
+static Value *emitIsInf(IRBuilder<> &B, Value *val) {
+  auto *fabsVal = B.CreateUnaryIntrinsic(Intrinsic::fabs, val);
+  return B.CreateFCmpOEQ(fabsVal, ConstantFP::getInfinity(val->getType()));
+}
+
+// y * log2(fabs(x))
+static Value *emitFastExpYLnx(IRBuilder<> &B, Value *X, Value *Y) {
+  Value *AbsX = B.CreateUnaryIntrinsic(Intrinsic::fabs, X);
+  Value *LogAbsX = B.CreateUnaryIntrinsic(Intrinsic::log2, AbsX);
+  Value *YTimesLogX = B.CreateFMul(Y, LogAbsX);
+  return B.CreateUnaryIntrinsic(Intrinsic::exp2, YTimesLogX);
+}
+
+/// Emit special case management epilog code for fast pow, powr, pown, and rootn
+/// expansions. \p x and \p y should be the arguments to the library call
+/// (possibly with some values clamped). \p expylnx should be the result to use
+/// in normal circumstances.
+static Value *emitPowFixup(IRBuilder<> &B, Value *X, Value *Y, Value *ExpYLnX,
+                           PowKind Kind) {
+  Constant *Zero = ConstantFP::getZero(X->getType());
+  Constant *One = ConstantFP::get(X->getType(), 1.0);
+  Constant *QNaN = ConstantFP::getQNaN(X->getType());
+  Constant *PInf = ConstantFP::getInfinity(X->getType());
+
+  switch (Kind) {
+  case PowKind::Pow: {
+    // is_odd_integer(y)
+    Value *IsOddY = emitIsOddInteger(B, Y);
+
+    // ret = copysign(expylnx, is_odd_y ? x : 1.0f)
+    Value *SelSign = B.CreateSelect(IsOddY, X, One);
+    Value *Ret = B.CreateCopySign(ExpYLnX, SelSign);
+
+    // if (x < 0 && !is_integer(y)) ret = QNAN
+    Value *IsIntY = emitIsInteger(B, Y);
+    Value *condNegX = B.CreateFCmpOLT(X, Zero);
+    Value *condNotIntY = B.CreateNot(IsIntY);
+    Value *condNaN = B.CreateAnd(condNegX, condNotIntY);
+    Ret = B.CreateSelect(condNaN, QNaN, Ret);
+
+    // if (isinf(ay)) { ... }
+
+    // FIXME: Missing backend optimization to save on materialization cost of
+    // mixed sign constant infinities.
+    Value *YIsInf = emitIsInf(B, Y);
+
+    Value *AY = B.CreateUnaryIntrinsic(Intrinsic::fabs, Y);
+    Value *YIsNegInf = B.CreateFCmpUNE(Y, AY);
+
+    Value *AX = B.CreateUnaryIntrinsic(Intrinsic::fabs, X);
+    Value *AxEqOne = B.CreateFCmpOEQ(AX, One);
+    Value *AxLtOne = B.CreateFCmpOLT(AX, One);
+    Value *XorCond = B.CreateXor(AxLtOne, YIsNegInf);
+    Value *SelInf =
+        B.CreateSelect(AxEqOne, AX, B.CreateSelect(XorCond, Zero, AY));
+    Ret = B.CreateSelect(YIsInf, SelInf, Ret);
+
+    // if (isinf(ax) || x == 0.0f) { ... }
+    Value *XIsInf = emitIsInf(B, X);
+    Value *XEqZero = B.CreateFCmpOEQ(X, Zero);
+    Value *AxInfOrZero = B.CreateOr(XIsInf, XEqZero);
+    Value *YLtZero = B.CreateFCmpOLT(Y, Zero);
+    Value *XorZeroInf = B.CreateXor(XEqZero, YLtZero);
+    Value *SelVal = B.CreateSelect(XorZeroInf, Zero, PInf);
+    Value *SelSign2 = B.CreateSelect(IsOddY, X, Zero);
+    Value *Copysign = B.CreateCopySign(SelVal, SelSign2);
+    Ret = B.CreateSelect(AxInfOrZero, Copysign, Ret);
+
+    // if (isunordered(x, y)) ret = QNAN
+    Value *isUnordered = B.CreateFCmpUNO(X, Y);
+    return B.CreateSelect(isUnordered, QNaN, Ret);
+  }
+  case PowKind::PowR: {
+    Value *YIsNeg = B.CreateFCmpOLT(Y, Zero);
+    Value *IZ = B.CreateSelect(YIsNeg, PInf, Zero);
+    Value *ZI = B.CreateSelect(YIsNeg, Zero, PInf);
+
+    Value *YEqZero = B.CreateFCmpOEQ(Y, Zero);
+    Value *SelZeroCase = B.CreateSelect(YEqZero, QNaN, IZ);
+    Value *XEqZero = B.CreateFCmpOEQ(X, Zero);
+    Value *Ret = B.CreateSelect(XEqZero, SelZeroCase, ExpYLnX);
+
+    Value *XEqInf = B.CreateFCmpOEQ(X, PInf);
+    Value *YNeZero = B.CreateFCmpUNE(Y, Zero);
+    Value *CondInfCase = B.CreateAnd(XEqInf, YNeZero);
+    Ret = B.CreateSelect(CondInfCase, ZI, Ret);
+
+    Value *IsInfY = emitIsInf(B, Y);
+    Value *XNeOne = B.CreateFCmpUNE(X, One);
+    Value *CondInfY = B.CreateAnd(IsInfY, XNeOne);
+    Value *XLtOne = B.CreateFCmpOLT(X, One);
+    Value *SelInfYCase = B.CreateSelect(XLtOne, IZ, ZI);
+    Ret = B.CreateSelect(CondInfY, SelInfYCase, Ret);
+
+    Value *IsUnordered = B.CreateFCmpUNO(X, Y);
+    return B.CreateSelect(IsUnordered, QNaN, Ret);
+  }
+  case PowKind::PowN: {
+    Constant *ZeroI = ConstantInt::get(Y->getType(), 0);
+
+    // is_odd_y = (ny & 1) != 0
+    Value *OneI = ConstantInt::get(Y->getType(), 1);
+    Value *YAnd1 = B.CreateAnd(Y, OneI);
+    Value *IsOddY = B.CreateICmpNE(YAnd1, ZeroI);
+
+    // ret = copysign(expylnx, is_odd_y ? x : 1.0f)
+    Value *SelSign = B.CreateSelect(IsOddY, X, One);
+    Value *Ret = B.CreateCopySign(ExpYLnX, SelSign);
+
+    // if (isinf(x) || x == 0.0f)
+    Value *FabsX = B.CreateUnaryIntrinsic(Intrinsic::fabs, X);
+    Value *XIsInf = B.CreateFCmpOEQ(FabsX, PInf);
+    Value *XEqZero = B.CreateFCmpOEQ(X, Zero);
+    Value *InfOrZero = B.CreateOr(XIsInf, XEqZero);
+
+    // (x == 0.0f) ^ (ny < 0) ? 0.0f : +inf
+    Value *YLtZero = B.CreateICmpSLT(Y, ZeroI);
+    Value *XorZeroInf = B.CreateXor(XEqZero, YLtZero);
+    Value *SelVal = B.CreateSelect(XorZeroInf, Zero, PInf);
+
+    // copysign(selVal, is_odd_y ? x : 0.0f)
+    Value *SelSign2 = B.CreateSelect(IsOddY, X, Zero);
+    Value *Copysign = B.CreateCopySign(SelVal, SelSign2);
+
+    return B.CreateSelect(InfOrZero, Copysign, Ret);
+  }
+  case PowKind::RootN: {
+    Constant *ZeroI = ConstantInt::get(Y->getType(), 0);
+
+    // is_odd_y = (ny & 1) != 0
+    Value *YAnd1 = B.CreateAnd(Y, ConstantInt::get(Y->getType(), 1));
+    Value *IsOddY = B.CreateICmpNE(YAnd1, ZeroI);
+
+    // ret = copysign(expylnx, is_odd_y ? x : 1.0f)
+    Value *SelSign = B.CreateSelect(IsOddY, X, One);
+    Value *Ret = B.CreateCopySign(ExpYLnX, SelSign);
+
+    // if (isinf(x) || x == 0.0f)
+    Value *FabsX = B.CreateUnaryIntrinsic(Intrinsic::fabs, X);
+    Value *IsInfX = B.CreateFCmpOEQ(FabsX, PInf);
+    Value *XEqZero = B.CreateFCmpOEQ(X, Zero);
+    Value *CondInfOrZero = B.CreateOr(IsInfX, XEqZero);
+
+    // (x == 0.0f) ^ (ny < 0) ? 0.0f : +inf
+    Value *YLtZero = B.CreateICmpSLT(Y, ZeroI);
+    Value *XorZeroInf = B.CreateXor(XEqZero, YLtZero);
+    Value *SelVal = B.CreateSelect(XorZeroInf, Zero, PInf);
+
+    // copysign(selVal, is_odd_y ? x : 0.0f)
+    Value *SelSign2 = B.CreateSelect(IsOddY, X, Zero);
+    Value *Copysign = B.CreateCopySign(SelVal, SelSign2);
+
+    Ret = B.CreateSelect(CondInfOrZero, Copysign, Ret);
+
+    // if ((x < 0.0f && !is_odd_y) || ny == 0) ret = QNAN
+    Value *XIsNeg = B.CreateFCmpOLT(X, Zero);
+    Value *NotOddY = B.CreateNot(IsOddY);
+    Value *CondNegAndNotOdd = B.CreateAnd(XIsNeg, NotOddY);
+    Value *YEqZero = B.CreateICmpEQ(Y, ZeroI);
+    Value *CondBad = B.CreateOr(CondNegAndNotOdd, YEqZero);
+    return B.CreateSelect(CondBad, QNaN, Ret);
+  }
+  }
+
+  llvm_unreachable("covered switch");
+}
+
+// TODO: Move the fold_pow folding to sqrt/fdiv here
+bool AMDGPULibCalls::expandFastPow(FPMathOperator *FPOp, IRBuilder<> &B,
+                                   PowKind Kind) {
+  Type *Ty = FPOp->getType();
+
+  // There's currently no reason to do this for half. The correct path is
+  // promote to float and use the fast float expansion.
+  //
+  // TODO: We could move this expansion to lowering to get half pow to work.
+  if (!Ty->getScalarType()->isFloatTy())
+    return false;
+
+  // TODO: Verify optimization for double and bfloat.
+  Value *X = FPOp->getOperand(0);
+  Value *Y = FPOp->getOperand(1);
+
+  switch (Kind) {
+  case PowKind::Pow: {
+    Constant *One = ConstantFP::get(X->getType(), 1.0);
+
+    // if (x == 1.0f) y = 1.0f;
+    Value *XEqOne = B.CreateFCmpOEQ(X, One);
+    Y = B.CreateSelect(XEqOne, One, Y);
+
+    // if (y == 0.0f) x = 1.0f;
+    Value *YEqZero = B.CreateFCmpOEQ(Y, ConstantFP::getZero(X->getType()));
+    X = B.CreateSelect(YEqZero, One, X);
+
+    Value *ExpYLnX = emitFastExpYLnx(B, X, Y);
+    Value *Fixed = emitPowFixup(B, X, Y, ExpYLnX, Kind);
+    replaceCall(FPOp, Fixed);
+    return true;
+  }
+  case PowKind::PowR: {
+    Value *NegX = B.CreateFCmpOLT(X, ConstantFP::getZero(X->getType()));
+    X = B.CreateSelect(NegX, ConstantFP::getQNaN(X->getType()), X);
+
+    Value *ExpYLnX = emitFastExpYLnx(B, X, Y);
+    Value *Fixed = emitPowFixup(B, X, Y, ExpYLnX, Kind);
+    replaceCall(FPOp, Fixed);
+    return true;
+  }
+  case PowKind::PowN: {
+    // ny == 0
+    Value *YEqZero = B.CreateICmpEQ(Y, ConstantInt::get(Y->getType(), 0));
+
+    // x = (ny == 0 ? 1.0f : x)
+    X = B.CreateSelect(YEqZero, ConstantFP::get(X->getType(), 1.0), X);
+
+    Value *CastY = B.CreateSIToFP(Y, X->getType());
+    Value *ExpYLnX = emitFastExpYLnx(B, X, CastY);
+    Value *Fixed = emitPowFixup(B, X, Y, ExpYLnX, Kind);
+    replaceCall(FPOp, Fixed);
+    return true;
+  }
+  case PowKind::RootN: {
+    Value *CastY = B.CreateSIToFP(Y, X->getType());
+    Value *RcpY = B.CreateUnaryIntrinsic(Intrinsic::amdgcn_rcp, CastY);
+    Value *ExpYLnX = emitFastExpYLnx(B, X, RcpY);
+    Value *Fixed = emitPowFixup(B, X, Y, ExpYLnX, Kind);
+    replaceCall(FPOp, Fixed);
+    return true;
+  }
+  }
+}
+
 // Get a scalar native builtin single argument FP function
 FunctionCallee AMDGPULibCalls::getNativeFunction(Module *M,
                                                  const FuncInfo &FInfo) {
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow-codegen.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow-codegen.ll
index 65053d00f9c90..5d08cef95810d 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow-codegen.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow-codegen.ll
@@ -33,10 +33,51 @@ define float @test_pow_fast_f32(float %x, float %y) {
 ; CHECK-LABEL: test_pow_fast_f32:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    s_getpc_b64 s[16:17]
-; CHECK-NEXT:    s_add_u32 s16, s16, _Z3powff at rel32@lo+4
-; CHECK-NEXT:    s_addc_u32 s17, s17, _Z3powff at rel32@hi+12
-; CHECK-NEXT:    s_setpc_b64 s[16:17]
+; CHECK-NEXT:    v_cmp_lg_f32_e32 vcc, 1.0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, 1.0, v1, vcc
+; CHECK-NEXT:    v_cmp_lg_f32_e32 vcc, 0, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, 1.0, v0, vcc
+; CHECK-NEXT:    s_mov_b32 s4, 0x800000
+; CHECK-NEXT:    v_cmp_lt_f32_e64 vcc, |v0|, s4
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, 0, 32, vcc
+; CHECK-NEXT:    v_ldexp_f32 v2, |v0|, v2
+; CHECK-NEXT:    v_log_f32_e32 v2, v2
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x42000000
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
+; CHECK-NEXT:    s_mov_b32 s4, 0xc2fc0000
+; CHECK-NEXT:    v_sub_f32_e32 v2, v2, v3
+; CHECK-NEXT:    v_mul_f32_e32 v3, v1, v2
+; CHECK-NEXT:    v_mov_b32_e32 v4, 0x42800000
+; CHECK-NEXT:    v_cmp_gt_f32_e32 vcc, s4, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, 0, v4, vcc
+; CHECK-NEXT:    v_fma_f32 v2, v1, v2, v3
+; CHECK-NEXT:    v_exp_f32_e32 v2, v2
+; CHECK-NEXT:    v_not_b32_e32 v3, 63
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
+; CHECK-NEXT:    v_mul_f32_e32 v4, 0.5, v1
+; CHECK-NEXT:    v_ldexp_f32 v2, v2, v3
+; CHECK-NEXT:    v_trunc_f32_e32 v3, v1
+; CHECK-NEXT:    v_trunc_f32_e32 v5, v4
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, v3, v1
+; CHECK-NEXT:    v_cmp_lg_f32_e64 s[4:5], v5, v4
+; CHECK-NEXT:    s_and_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, 1.0, v0, vcc
+; CHECK-NEXT:    s_brev_b32 s8, -2
+; CHECK-NEXT:    v_cmp_lg_f32_e64 s[4:5], v3, v1
+; CHECK-NEXT:    v_cmp_gt_f32_e64 s[6:7], 0, v0
+; CHECK-NEXT:    v_bfi_b32 v2, s8, v2, v4
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x7fc00000
+; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, v2, v3, s[4:5]
+; CHECK-NEXT:    v_cmp_eq_f32_e64 s[4:5], 0, v0
+; CHECK-NEXT:    v_cmp_gt_f32_e64 s[6:7], 0, v1
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7f800000
+; CHECK-NEXT:    s_xor_b64 s[6:7], s[4:5], s[6:7]
+; CHECK-NEXT:    v_cndmask_b32_e64 v1, v1, 0, s[6:7]
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, 0, v0, vcc
+; CHECK-NEXT:    v_bfi_b32 v0, s8, v1, v0
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v2, v0, s[4:5]
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %pow = tail call fast float @_Z3powff(float %x, float %y)
   ret float %pow
 }
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
index 193e3a740b92e..3bb84f0586875 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
@@ -31,8 +31,35 @@ declare float @llvm.roundeven.f32(float)
 define float @test_pow_fast_f32(float %x, float %y) {
 ; CHECK-LABEL: define float @test_pow_fast_f32
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call fast float @_Z3powff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp fast oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select fast i1 [[TMP1]], float 1.000000e+00, float [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp fast oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select fast i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call fast float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call fast float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul fast float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call fast float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call fast float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp fast oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul fast float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call fast float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp fast une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select fast i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call fast float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call fast float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp fast une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp fast olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select fast i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp fast oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp fast olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP24:%.*]] = xor i1 [[TMP22]], [[TMP23]]
+; CHECK-NEXT:    [[TMP25:%.*]] = select fast i1 [[TMP24]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP26:%.*]] = select fast i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP27:%.*]] = call fast float @llvm.copysign.f32(float [[TMP25]], float [[TMP26]])
+; CHECK-NEXT:    [[TMP28:%.*]] = select fast i1 [[TMP22]], float [[TMP27]], float [[TMP21]]
+; CHECK-NEXT:    ret float [[TMP28]]
 ;
   %pow = tail call fast float @_Z3powff(float %x, float %y)
   ret float %pow
@@ -41,8 +68,35 @@ define float @test_pow_fast_f32(float %x, float %y) {
 define <2 x float> @test_pow_fast_v2f32(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: define <2 x float> @test_pow_fast_v2f32
 ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call fast <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp fast oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select fast <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp fast oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = select fast <2 x i1> [[TMP3]], <2 x float> splat (float 1.000000e+00), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call fast <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call fast <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul fast <2 x float> [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call fast <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call fast <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp fast oeq <2 x float> [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul fast <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP12:%.*]] = call fast <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp fast une <2 x float> [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and <2 x i1> [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select fast <2 x i1> [[TMP14]], <2 x float> [[TMP4]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP16:%.*]] = call fast <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP8]], <2 x float> [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call fast <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp fast une <2 x float> [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp fast olt <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP20:%.*]] = and <2 x i1> [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select fast <2 x i1> [[TMP20]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp fast oeq <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp fast olt <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP24:%.*]] = xor <2 x i1> [[TMP22]], [[TMP23]]
+; CHECK-NEXT:    [[TMP25:%.*]] = select fast <2 x i1> [[TMP24]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP26:%.*]] = select fast <2 x i1> [[TMP14]], <2 x float> [[TMP4]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP27:%.*]] = call fast <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP25]], <2 x float> [[TMP26]])
+; CHECK-NEXT:    [[TMP28:%.*]] = select fast <2 x i1> [[TMP22]], <2 x float> [[TMP27]], <2 x float> [[TMP21]]
+; CHECK-NEXT:    ret <2 x float> [[TMP28]]
 ;
   %pow = tail call fast <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
   ret <2 x float> %pow
@@ -51,8 +105,49 @@ define <2 x float> @test_pow_fast_v2f32(<2 x float> %x, <2 x float> %y) {
 define float @test_pow_afn_f32_nnan(float %x, float %y) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn float @_Z3powff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan afn i1 [[TMP1]], float 1.000000e+00, float [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp nnan afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select nnan afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan afn float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul nnan afn float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan afn float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan afn oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul nnan afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan afn une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan afn une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp nnan afn olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan afn i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp nnan afn oeq float [[TMP22]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP24:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp nnan afn une float [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp nnan afn oeq float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp nnan afn olt float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP29:%.*]] = xor i1 [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select nnan afn i1 [[TMP29]], float 0.000000e+00, float [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select nnan afn i1 [[TMP27]], float 1.000000e+00, float [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select nnan afn i1 [[TMP23]], float [[TMP31]], float [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp nnan afn oeq float [[TMP33]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp nnan afn oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP36:%.*]] = or i1 [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp nnan afn olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP38:%.*]] = xor i1 [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select nnan afn i1 [[TMP38]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP40:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP41:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP39]], float [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select nnan afn i1 [[TMP36]], float [[TMP41]], float [[TMP32]]
+; CHECK-NEXT:    ret float [[TMP42]]
 ;
   %pow = tail call afn nnan float @_Z3powff(float %x, float %y)
   ret float %pow
@@ -61,8 +156,35 @@ define float @test_pow_afn_f32_nnan(float %x, float %y) {
 define float @test_pow_afn_f32_nnan_ninf(float %x, float %y) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan ninf afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan ninf afn i1 [[TMP1]], float 1.000000e+00, float [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp nnan ninf afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select nnan ninf afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul nnan ninf afn float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call nnan ninf afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan ninf afn oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul nnan ninf afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call nnan ninf afn float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan ninf afn une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan ninf afn i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call nnan ninf afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan ninf afn une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp nnan ninf afn olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan ninf afn i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp nnan ninf afn oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp nnan ninf afn olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP24:%.*]] = xor i1 [[TMP22]], [[TMP23]]
+; CHECK-NEXT:    [[TMP25:%.*]] = select nnan ninf afn i1 [[TMP24]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP26:%.*]] = select nnan ninf afn i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP27:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP25]], float [[TMP26]])
+; CHECK-NEXT:    [[TMP28:%.*]] = select nnan ninf afn i1 [[TMP22]], float [[TMP27]], float [[TMP21]]
+; CHECK-NEXT:    ret float [[TMP28]]
 ;
   %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y)
   ret float %pow
@@ -71,8 +193,49 @@ define float @test_pow_afn_f32_nnan_ninf(float %x, float %y) {
 define <2 x float> @test_pow_afn_v2f32_nnan(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan
 ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan afn oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan afn <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp nnan afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = select nnan afn <2 x i1> [[TMP3]], <2 x float> splat (float 1.000000e+00), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul nnan afn <2 x float> [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call nnan afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan afn oeq <2 x float> [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul nnan afn <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP12:%.*]] = call nnan afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan afn une <2 x float> [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and <2 x i1> [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan afn <2 x i1> [[TMP14]], <2 x float> [[TMP4]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP8]], <2 x float> [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call nnan afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan afn une <2 x float> [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp nnan afn olt <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP20:%.*]] = and <2 x i1> [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan afn <2 x i1> [[TMP20]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call nnan afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp nnan afn oeq <2 x float> [[TMP22]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP24:%.*]] = call nnan afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp nnan afn une <2 x float> [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call nnan afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp nnan afn oeq <2 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp nnan afn olt <2 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP29:%.*]] = xor <2 x i1> [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select nnan afn <2 x i1> [[TMP29]], <2 x float> zeroinitializer, <2 x float> [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select nnan afn <2 x i1> [[TMP27]], <2 x float> splat (float 1.000000e+00), <2 x float> [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select nnan afn <2 x i1> [[TMP23]], <2 x float> [[TMP31]], <2 x float> [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call nnan afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp nnan afn oeq <2 x float> [[TMP33]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp nnan afn oeq <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP36:%.*]] = or <2 x i1> [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp nnan afn olt <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP38:%.*]] = xor <2 x i1> [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select nnan afn <2 x i1> [[TMP38]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP40:%.*]] = select nnan afn <2 x i1> [[TMP14]], <2 x float> [[TMP4]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP41:%.*]] = call nnan afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP39]], <2 x float> [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select nnan afn <2 x i1> [[TMP36]], <2 x float> [[TMP41]], <2 x float> [[TMP32]]
+; CHECK-NEXT:    ret <2 x float> [[TMP42]]
 ;
   %pow = tail call afn nnan <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
   ret <2 x float> %pow
@@ -81,8 +244,35 @@ define <2 x float> @test_pow_afn_v2f32_nnan(<2 x float> %x, <2 x float> %y) {
 define <2 x float> @test_pow_afn_v2f32_nnan_ninf(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf
 ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan ninf afn <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = select nnan ninf afn <2 x i1> [[TMP3]], <2 x float> splat (float 1.000000e+00), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan ninf afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul nnan ninf afn <2 x float> [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call nnan ninf afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul nnan ninf afn <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP12:%.*]] = call nnan ninf afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan ninf afn une <2 x float> [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and <2 x i1> [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan ninf afn <2 x i1> [[TMP14]], <2 x float> [[TMP4]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP8]], <2 x float> [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call nnan ninf afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan ninf afn une <2 x float> [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp nnan ninf afn olt <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP20:%.*]] = and <2 x i1> [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan ninf afn <2 x i1> [[TMP20]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp nnan ninf afn olt <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP24:%.*]] = xor <2 x i1> [[TMP22]], [[TMP23]]
+; CHECK-NEXT:    [[TMP25:%.*]] = select nnan ninf afn <2 x i1> [[TMP24]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP26:%.*]] = select nnan ninf afn <2 x i1> [[TMP14]], <2 x float> [[TMP4]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP27:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP25]], <2 x float> [[TMP26]])
+; CHECK-NEXT:    [[TMP28:%.*]] = select nnan ninf afn <2 x i1> [[TMP22]], <2 x float> [[TMP27]], <2 x float> [[TMP21]]
+; CHECK-NEXT:    ret <2 x float> [[TMP28]]
 ;
   %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
   ret <2 x float> %pow
@@ -91,8 +281,51 @@ define <2 x float> @test_pow_afn_v2f32_nnan_ninf(<2 x float> %x, <2 x float> %y)
 define float @test_pow_afn_f32(float %x, float %y) {
 ; CHECK-LABEL: define float @test_pow_afn_f32
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 1.000000e+00, float [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul afn float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call afn float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn oeq float [[TMP22]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP24:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn une float [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp afn oeq float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn olt float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP29:%.*]] = xor i1 [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select afn i1 [[TMP29]], float 0.000000e+00, float [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn i1 [[TMP27]], float 1.000000e+00, float [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select afn i1 [[TMP23]], float [[TMP31]], float [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp afn oeq float [[TMP33]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp afn oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP36:%.*]] = or i1 [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp afn olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP38:%.*]] = xor i1 [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select afn i1 [[TMP38]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP40:%.*]] = select afn i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP41:%.*]] = call afn float @llvm.copysign.f32(float [[TMP39]], float [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select afn i1 [[TMP36]], float [[TMP41]], float [[TMP32]]
+; CHECK-NEXT:    [[TMP43:%.*]] = fcmp afn uno float [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP44:%.*]] = select afn i1 [[TMP43]], float 0x7FF8000000000000, float [[TMP42]]
+; CHECK-NEXT:    ret float [[TMP44]]
 ;
   %pow = tail call afn float @_Z3powff(float %x, float %y)
   ret float %pow
@@ -101,8 +334,51 @@ define float @test_pow_afn_f32(float %x, float %y) {
 define <2 x float> @test_pow_afn_v2f32(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32
 ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = select afn <2 x i1> [[TMP3]], <2 x float> splat (float 1.000000e+00), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul afn <2 x float> [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <2 x float> [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul afn <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP12:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une <2 x float> [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and <2 x i1> [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn <2 x i1> [[TMP14]], <2 x float> [[TMP4]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP8]], <2 x float> [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une <2 x float> [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP20:%.*]] = and <2 x i1> [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn <2 x i1> [[TMP20]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn oeq <2 x float> [[TMP22]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP24:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn une <2 x float> [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp afn oeq <2 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn olt <2 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP29:%.*]] = xor <2 x i1> [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select afn <2 x i1> [[TMP29]], <2 x float> zeroinitializer, <2 x float> [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn <2 x i1> [[TMP27]], <2 x float> splat (float 1.000000e+00), <2 x float> [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select afn <2 x i1> [[TMP23]], <2 x float> [[TMP31]], <2 x float> [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp afn oeq <2 x float> [[TMP33]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp afn oeq <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP36:%.*]] = or <2 x i1> [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp afn olt <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP38:%.*]] = xor <2 x i1> [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select afn <2 x i1> [[TMP38]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP40:%.*]] = select afn <2 x i1> [[TMP14]], <2 x float> [[TMP4]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP41:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP39]], <2 x float> [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select afn <2 x i1> [[TMP36]], <2 x float> [[TMP41]], <2 x float> [[TMP32]]
+; CHECK-NEXT:    [[TMP43:%.*]] = fcmp afn uno <2 x float> [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP44:%.*]] = select afn <2 x i1> [[TMP43]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP42]]
+; CHECK-NEXT:    ret <2 x float> [[TMP44]]
 ;
   %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
   ret <2 x float> %pow
@@ -111,8 +387,51 @@ define <2 x float> @test_pow_afn_v2f32(<2 x float> %x, <2 x float> %y) {
 define <3 x float> @test_pow_afn_v3f32(<3 x float> %x, <3 x float> %y) {
 ; CHECK-LABEL: define <3 x float> @test_pow_afn_v3f32
 ; CHECK-SAME: (<3 x float> [[X:%.*]], <3 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn <3 x float> @_Z3powDv3_fS_(<3 x float> [[X]], <3 x float> [[Y]])
-; CHECK-NEXT:    ret <3 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq <3 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <3 x i1> [[TMP1]], <3 x float> splat (float 1.000000e+00), <3 x float> [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp afn oeq <3 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = select afn <3 x i1> [[TMP3]], <3 x float> splat (float 1.000000e+00), <3 x float> [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn <3 x float> @llvm.fabs.v3f32(<3 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <3 x float> @llvm.log2.v3f32(<3 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul afn <3 x float> [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn <3 x float> @llvm.exp2.v3f32(<3 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn <3 x float> @llvm.trunc.v3f32(<3 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <3 x float> [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul afn <3 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP12:%.*]] = call afn <3 x float> @llvm.trunc.v3f32(<3 x float> [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une <3 x float> [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and <3 x i1> [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn <3 x i1> [[TMP14]], <3 x float> [[TMP4]], <3 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn <3 x float> @llvm.copysign.v3f32(<3 x float> [[TMP8]], <3 x float> [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn <3 x float> @llvm.trunc.v3f32(<3 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une <3 x float> [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt <3 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP20:%.*]] = and <3 x i1> [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn <3 x i1> [[TMP20]], <3 x float> splat (float 0x7FF8000000000000), <3 x float> [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call afn <3 x float> @llvm.fabs.v3f32(<3 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn oeq <3 x float> [[TMP22]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP24:%.*]] = call afn <3 x float> @llvm.fabs.v3f32(<3 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn une <3 x float> [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn <3 x float> @llvm.fabs.v3f32(<3 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp afn oeq <3 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn olt <3 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP29:%.*]] = xor <3 x i1> [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select afn <3 x i1> [[TMP29]], <3 x float> zeroinitializer, <3 x float> [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn <3 x i1> [[TMP27]], <3 x float> splat (float 1.000000e+00), <3 x float> [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select afn <3 x i1> [[TMP23]], <3 x float> [[TMP31]], <3 x float> [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call afn <3 x float> @llvm.fabs.v3f32(<3 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp afn oeq <3 x float> [[TMP33]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp afn oeq <3 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP36:%.*]] = or <3 x i1> [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp afn olt <3 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP38:%.*]] = xor <3 x i1> [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select afn <3 x i1> [[TMP38]], <3 x float> zeroinitializer, <3 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP40:%.*]] = select afn <3 x i1> [[TMP14]], <3 x float> [[TMP4]], <3 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP41:%.*]] = call afn <3 x float> @llvm.copysign.v3f32(<3 x float> [[TMP39]], <3 x float> [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select afn <3 x i1> [[TMP36]], <3 x float> [[TMP41]], <3 x float> [[TMP32]]
+; CHECK-NEXT:    [[TMP43:%.*]] = fcmp afn uno <3 x float> [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP44:%.*]] = select afn <3 x i1> [[TMP43]], <3 x float> splat (float 0x7FF8000000000000), <3 x float> [[TMP42]]
+; CHECK-NEXT:    ret <3 x float> [[TMP44]]
 ;
   %pow = tail call afn <3 x float> @_Z3powDv3_fS_(<3 x float> %x, <3 x float> %y)
   ret <3 x float> %pow
@@ -121,8 +440,51 @@ define <3 x float> @test_pow_afn_v3f32(<3 x float> %x, <3 x float> %y) {
 define <4 x float> @test_pow_afn_v4f32(<4 x float> %x, <4 x float> %y) {
 ; CHECK-LABEL: define <4 x float> @test_pow_afn_v4f32
 ; CHECK-SAME: (<4 x float> [[X:%.*]], <4 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn <4 x float> @_Z3powDv4_fS_(<4 x float> [[X]], <4 x float> [[Y]])
-; CHECK-NEXT:    ret <4 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq <4 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <4 x i1> [[TMP1]], <4 x float> splat (float 1.000000e+00), <4 x float> [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp afn oeq <4 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = select afn <4 x i1> [[TMP3]], <4 x float> splat (float 1.000000e+00), <4 x float> [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <4 x float> @llvm.log2.v4f32(<4 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul afn <4 x float> [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn <4 x float> @llvm.exp2.v4f32(<4 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <4 x float> [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul afn <4 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP12:%.*]] = call afn <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une <4 x float> [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and <4 x i1> [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn <4 x i1> [[TMP14]], <4 x float> [[TMP4]], <4 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn <4 x float> @llvm.copysign.v4f32(<4 x float> [[TMP8]], <4 x float> [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une <4 x float> [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt <4 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP20:%.*]] = and <4 x i1> [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn <4 x i1> [[TMP20]], <4 x float> splat (float 0x7FF8000000000000), <4 x float> [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call afn <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn oeq <4 x float> [[TMP22]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP24:%.*]] = call afn <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn une <4 x float> [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp afn oeq <4 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn olt <4 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP29:%.*]] = xor <4 x i1> [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select afn <4 x i1> [[TMP29]], <4 x float> zeroinitializer, <4 x float> [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn <4 x i1> [[TMP27]], <4 x float> splat (float 1.000000e+00), <4 x float> [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select afn <4 x i1> [[TMP23]], <4 x float> [[TMP31]], <4 x float> [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call afn <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp afn oeq <4 x float> [[TMP33]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp afn oeq <4 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP36:%.*]] = or <4 x i1> [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp afn olt <4 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP38:%.*]] = xor <4 x i1> [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select afn <4 x i1> [[TMP38]], <4 x float> zeroinitializer, <4 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP40:%.*]] = select afn <4 x i1> [[TMP14]], <4 x float> [[TMP4]], <4 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP41:%.*]] = call afn <4 x float> @llvm.copysign.v4f32(<4 x float> [[TMP39]], <4 x float> [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select afn <4 x i1> [[TMP36]], <4 x float> [[TMP41]], <4 x float> [[TMP32]]
+; CHECK-NEXT:    [[TMP43:%.*]] = fcmp afn uno <4 x float> [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP44:%.*]] = select afn <4 x i1> [[TMP43]], <4 x float> splat (float 0x7FF8000000000000), <4 x float> [[TMP42]]
+; CHECK-NEXT:    ret <4 x float> [[TMP44]]
 ;
   %pow = tail call afn <4 x float> @_Z3powDv4_fS_(<4 x float> %x, <4 x float> %y)
   ret <4 x float> %pow
@@ -131,8 +493,51 @@ define <4 x float> @test_pow_afn_v4f32(<4 x float> %x, <4 x float> %y) {
 define <8 x float> @test_pow_afn_v8f32(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: define <8 x float> @test_pow_afn_v8f32
 ; CHECK-SAME: (<8 x float> [[X:%.*]], <8 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn <8 x float> @_Z3powDv8_fS_(<8 x float> [[X]], <8 x float> [[Y]])
-; CHECK-NEXT:    ret <8 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq <8 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <8 x i1> [[TMP1]], <8 x float> splat (float 1.000000e+00), <8 x float> [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp afn oeq <8 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = select afn <8 x i1> [[TMP3]], <8 x float> splat (float 1.000000e+00), <8 x float> [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn <8 x float> @llvm.fabs.v8f32(<8 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <8 x float> @llvm.log2.v8f32(<8 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul afn <8 x float> [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn <8 x float> @llvm.exp2.v8f32(<8 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn <8 x float> @llvm.trunc.v8f32(<8 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <8 x float> [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul afn <8 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP12:%.*]] = call afn <8 x float> @llvm.trunc.v8f32(<8 x float> [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une <8 x float> [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and <8 x i1> [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn <8 x i1> [[TMP14]], <8 x float> [[TMP4]], <8 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn <8 x float> @llvm.copysign.v8f32(<8 x float> [[TMP8]], <8 x float> [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn <8 x float> @llvm.trunc.v8f32(<8 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une <8 x float> [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt <8 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP20:%.*]] = and <8 x i1> [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn <8 x i1> [[TMP20]], <8 x float> splat (float 0x7FF8000000000000), <8 x float> [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call afn <8 x float> @llvm.fabs.v8f32(<8 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn oeq <8 x float> [[TMP22]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP24:%.*]] = call afn <8 x float> @llvm.fabs.v8f32(<8 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn une <8 x float> [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn <8 x float> @llvm.fabs.v8f32(<8 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp afn oeq <8 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn olt <8 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP29:%.*]] = xor <8 x i1> [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select afn <8 x i1> [[TMP29]], <8 x float> zeroinitializer, <8 x float> [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn <8 x i1> [[TMP27]], <8 x float> splat (float 1.000000e+00), <8 x float> [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select afn <8 x i1> [[TMP23]], <8 x float> [[TMP31]], <8 x float> [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call afn <8 x float> @llvm.fabs.v8f32(<8 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp afn oeq <8 x float> [[TMP33]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp afn oeq <8 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP36:%.*]] = or <8 x i1> [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp afn olt <8 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP38:%.*]] = xor <8 x i1> [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select afn <8 x i1> [[TMP38]], <8 x float> zeroinitializer, <8 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP40:%.*]] = select afn <8 x i1> [[TMP14]], <8 x float> [[TMP4]], <8 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP41:%.*]] = call afn <8 x float> @llvm.copysign.v8f32(<8 x float> [[TMP39]], <8 x float> [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select afn <8 x i1> [[TMP36]], <8 x float> [[TMP41]], <8 x float> [[TMP32]]
+; CHECK-NEXT:    [[TMP43:%.*]] = fcmp afn uno <8 x float> [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP44:%.*]] = select afn <8 x i1> [[TMP43]], <8 x float> splat (float 0x7FF8000000000000), <8 x float> [[TMP42]]
+; CHECK-NEXT:    ret <8 x float> [[TMP44]]
 ;
   %pow = tail call afn <8 x float> @_Z3powDv8_fS_(<8 x float> %x, <8 x float> %y)
   ret <8 x float> %pow
@@ -141,8 +546,51 @@ define <8 x float> @test_pow_afn_v8f32(<8 x float> %x, <8 x float> %y) {
 define <16 x float> @test_pow_afn_v16f32(<16 x float> %x, <16 x float> %y) {
 ; CHECK-LABEL: define <16 x float> @test_pow_afn_v16f32
 ; CHECK-SAME: (<16 x float> [[X:%.*]], <16 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn <16 x float> @_Z3powDv16_fS_(<16 x float> [[X]], <16 x float> [[Y]])
-; CHECK-NEXT:    ret <16 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq <16 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <16 x i1> [[TMP1]], <16 x float> splat (float 1.000000e+00), <16 x float> [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp afn oeq <16 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = select afn <16 x i1> [[TMP3]], <16 x float> splat (float 1.000000e+00), <16 x float> [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn <16 x float> @llvm.fabs.v16f32(<16 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <16 x float> @llvm.log2.v16f32(<16 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul afn <16 x float> [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn <16 x float> @llvm.exp2.v16f32(<16 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn <16 x float> @llvm.trunc.v16f32(<16 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <16 x float> [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul afn <16 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP12:%.*]] = call afn <16 x float> @llvm.trunc.v16f32(<16 x float> [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une <16 x float> [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and <16 x i1> [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn <16 x i1> [[TMP14]], <16 x float> [[TMP4]], <16 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn <16 x float> @llvm.copysign.v16f32(<16 x float> [[TMP8]], <16 x float> [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn <16 x float> @llvm.trunc.v16f32(<16 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une <16 x float> [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt <16 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP20:%.*]] = and <16 x i1> [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn <16 x i1> [[TMP20]], <16 x float> splat (float 0x7FF8000000000000), <16 x float> [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call afn <16 x float> @llvm.fabs.v16f32(<16 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn oeq <16 x float> [[TMP22]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP24:%.*]] = call afn <16 x float> @llvm.fabs.v16f32(<16 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn une <16 x float> [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn <16 x float> @llvm.fabs.v16f32(<16 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp afn oeq <16 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn olt <16 x float> [[TMP26]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP29:%.*]] = xor <16 x i1> [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select afn <16 x i1> [[TMP29]], <16 x float> zeroinitializer, <16 x float> [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn <16 x i1> [[TMP27]], <16 x float> splat (float 1.000000e+00), <16 x float> [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select afn <16 x i1> [[TMP23]], <16 x float> [[TMP31]], <16 x float> [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call afn <16 x float> @llvm.fabs.v16f32(<16 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp afn oeq <16 x float> [[TMP33]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp afn oeq <16 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP36:%.*]] = or <16 x i1> [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp afn olt <16 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP38:%.*]] = xor <16 x i1> [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select afn <16 x i1> [[TMP38]], <16 x float> zeroinitializer, <16 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP40:%.*]] = select afn <16 x i1> [[TMP14]], <16 x float> [[TMP4]], <16 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP41:%.*]] = call afn <16 x float> @llvm.copysign.v16f32(<16 x float> [[TMP39]], <16 x float> [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select afn <16 x i1> [[TMP36]], <16 x float> [[TMP41]], <16 x float> [[TMP32]]
+; CHECK-NEXT:    [[TMP43:%.*]] = fcmp afn uno <16 x float> [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP44:%.*]] = select afn <16 x i1> [[TMP43]], <16 x float> splat (float 0x7FF8000000000000), <16 x float> [[TMP42]]
+; CHECK-NEXT:    ret <16 x float> [[TMP44]]
 ;
   %pow = tail call afn <16 x float> @_Z3powDv16_fS_(<16 x float> %x, <16 x float> %y)
   ret <16 x float> %pow
@@ -461,8 +909,51 @@ define <16 x half> @test_pow_v16f16(<16 x half> %x, <16 x half> %y) {
 define float @test_pow_afn_f32_minsize(float %x, float %y) #0 {
 ; CHECK-LABEL: define float @test_pow_afn_f32_minsize
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2:[0-9]+]] {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 1.000000e+00, float [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul afn float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call afn float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn oeq float [[TMP22]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP24:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn une float [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp afn oeq float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn olt float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP29:%.*]] = xor i1 [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select afn i1 [[TMP29]], float 0.000000e+00, float [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn i1 [[TMP27]], float 1.000000e+00, float [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select afn i1 [[TMP23]], float [[TMP31]], float [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp afn oeq float [[TMP33]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp afn oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP36:%.*]] = or i1 [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp afn olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP38:%.*]] = xor i1 [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select afn i1 [[TMP38]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP40:%.*]] = select afn i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP41:%.*]] = call afn float @llvm.copysign.f32(float [[TMP39]], float [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select afn i1 [[TMP36]], float [[TMP41]], float [[TMP32]]
+; CHECK-NEXT:    [[TMP43:%.*]] = fcmp afn uno float [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP44:%.*]] = select afn i1 [[TMP43]], float 0x7FF8000000000000, float [[TMP42]]
+; CHECK-NEXT:    ret float [[TMP44]]
 ;
   %pow = tail call afn float @_Z3powff(float %x, float %y)
   ret float %pow
@@ -471,8 +962,49 @@ define float @test_pow_afn_f32_minsize(float %x, float %y) #0 {
 define float @test_pow_afn_f32_nnan_minsize(float %x, float %y) #0 {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_minsize
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn float @_Z3powff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan afn i1 [[TMP1]], float 1.000000e+00, float [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp nnan afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select nnan afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan afn float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul nnan afn float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan afn float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan afn oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul nnan afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan afn une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan afn une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp nnan afn olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan afn i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp nnan afn oeq float [[TMP22]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP24:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp nnan afn une float [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp nnan afn oeq float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp nnan afn olt float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP29:%.*]] = xor i1 [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select nnan afn i1 [[TMP29]], float 0.000000e+00, float [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select nnan afn i1 [[TMP27]], float 1.000000e+00, float [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select nnan afn i1 [[TMP23]], float [[TMP31]], float [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp nnan afn oeq float [[TMP33]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp nnan afn oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP36:%.*]] = or i1 [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp nnan afn olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP38:%.*]] = xor i1 [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select nnan afn i1 [[TMP38]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP40:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP41:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP39]], float [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select nnan afn i1 [[TMP36]], float [[TMP41]], float [[TMP32]]
+; CHECK-NEXT:    ret float [[TMP42]]
 ;
   %pow = tail call afn nnan float @_Z3powff(float %x, float %y)
   ret float %pow
@@ -481,8 +1013,51 @@ define float @test_pow_afn_f32_nnan_minsize(float %x, float %y) #0 {
 define float @test_pow_afn_f32_noinline(float %x, float %y) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_noinline
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float [[Y]]) #[[ATTR5:[0-9]+]]
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 1.000000e+00, float [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul afn float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call afn float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn oeq float [[TMP22]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP24:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn une float [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp afn oeq float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn olt float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP29:%.*]] = xor i1 [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select afn i1 [[TMP29]], float 0.000000e+00, float [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn i1 [[TMP27]], float 1.000000e+00, float [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select afn i1 [[TMP23]], float [[TMP31]], float [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp afn oeq float [[TMP33]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp afn oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP36:%.*]] = or i1 [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp afn olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP38:%.*]] = xor i1 [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select afn i1 [[TMP38]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP40:%.*]] = select afn i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP41:%.*]] = call afn float @llvm.copysign.f32(float [[TMP39]], float [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select afn i1 [[TMP36]], float [[TMP41]], float [[TMP32]]
+; CHECK-NEXT:    [[TMP43:%.*]] = fcmp afn uno float [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP44:%.*]] = select afn i1 [[TMP43]], float 0x7FF8000000000000, float [[TMP42]]
+; CHECK-NEXT:    ret float [[TMP44]]
 ;
   %pow = tail call afn float @_Z3powff(float %x, float %y) #1
   ret float %pow
@@ -491,8 +1066,49 @@ define float @test_pow_afn_f32_noinline(float %x, float %y) {
 define float @test_pow_afn_f32_nnan_noinline(float %x, float %y) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_noinline
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn float @_Z3powff(float [[X]], float [[Y]]) #[[ATTR5]]
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan afn i1 [[TMP1]], float 1.000000e+00, float [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp nnan afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select nnan afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan afn float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul nnan afn float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan afn float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan afn oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul nnan afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan afn une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan afn une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp nnan afn olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan afn i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp nnan afn oeq float [[TMP22]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP24:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp nnan afn une float [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp nnan afn oeq float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp nnan afn olt float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP29:%.*]] = xor i1 [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select nnan afn i1 [[TMP29]], float 0.000000e+00, float [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select nnan afn i1 [[TMP27]], float 1.000000e+00, float [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select nnan afn i1 [[TMP23]], float [[TMP31]], float [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp nnan afn oeq float [[TMP33]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp nnan afn oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP36:%.*]] = or i1 [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp nnan afn olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP38:%.*]] = xor i1 [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select nnan afn i1 [[TMP38]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP40:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP41:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP39]], float [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select nnan afn i1 [[TMP36]], float [[TMP41]], float [[TMP32]]
+; CHECK-NEXT:    ret float [[TMP42]]
 ;
   %pow = tail call afn nnan float @_Z3powff(float %x, float %y) #1
   ret float %pow
@@ -501,8 +1117,53 @@ define float @test_pow_afn_f32_nnan_noinline(float %x, float %y) {
 define float @test_pow_afn_f32_strictfp(float %x, float %y) #2 {
 ; CHECK-LABEL: define float @test_pow_afn_f32_strictfp
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) #[[ATTR3:[0-9]+]] {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan nsz afn float @_Z3powff(float [[X]], float [[Y]]) #[[ATTR3]]
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[X]], float 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan nsz afn i1 [[TMP1]], float 1.000000e+00, float [[Y]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP2]], float 0.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP4:%.*]] = select nnan nsz afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan nsz afn float @llvm.fabs.f32(float [[TMP4]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan nsz afn float @llvm.log2.f32(float [[TMP5]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP7:%.*]] = call nnan nsz afn float @llvm.experimental.constrained.fmul.f32(float [[TMP2]], float [[TMP6]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan nsz afn float @llvm.exp2.f32(float [[TMP7]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP9:%.*]] = call nnan nsz afn float @llvm.trunc.f32(float [[TMP2]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP10:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP9]], float [[TMP2]], metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP11:%.*]] = call nnan nsz afn float @llvm.experimental.constrained.fmul.f32(float [[TMP2]], float 5.000000e-01, metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP12:%.*]] = call nnan nsz afn float @llvm.trunc.f32(float [[TMP11]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP13:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP12]], float [[TMP11]], metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP14:%.*]] = xor i1 [[TMP13]], true
+; CHECK-NEXT:    [[TMP15:%.*]] = and i1 [[TMP10]], [[TMP14]]
+; CHECK-NEXT:    [[TMP16:%.*]] = select nnan nsz afn i1 [[TMP15]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP17:%.*]] = call nnan nsz afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP16]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call nnan nsz afn float @llvm.trunc.f32(float [[TMP2]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP19:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP18]], float [[TMP2]], metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP20:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP4]], float 0.000000e+00, metadata !"olt", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP21:%.*]] = xor i1 [[TMP19]], true
+; CHECK-NEXT:    [[TMP22:%.*]] = and i1 [[TMP20]], [[TMP21]]
+; CHECK-NEXT:    [[TMP23:%.*]] = select nnan nsz afn i1 [[TMP22]], float 0x7FF8000000000000, float [[TMP17]]
+; CHECK-NEXT:    [[TMP24:%.*]] = call nnan nsz afn float @llvm.fabs.f32(float [[TMP2]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP25:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP24]], float 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call nnan nsz afn float @llvm.fabs.f32(float [[TMP2]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP27:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP2]], float [[TMP26]], metadata !"une", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP28:%.*]] = call nnan nsz afn float @llvm.fabs.f32(float [[TMP4]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP29:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP28]], float 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP30:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP28]], float 1.000000e+00, metadata !"olt", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP31:%.*]] = xor i1 [[TMP30]], [[TMP27]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select nnan nsz afn i1 [[TMP31]], float 0.000000e+00, float [[TMP26]]
+; CHECK-NEXT:    [[TMP33:%.*]] = select nnan nsz afn i1 [[TMP29]], float [[TMP28]], float [[TMP32]]
+; CHECK-NEXT:    [[TMP34:%.*]] = select nnan nsz afn i1 [[TMP25]], float [[TMP33]], float [[TMP23]]
+; CHECK-NEXT:    [[TMP35:%.*]] = call nnan nsz afn float @llvm.fabs.f32(float [[TMP4]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP36:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP35]], float 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP37:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP4]], float 0.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP38:%.*]] = or i1 [[TMP36]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP2]], float 0.000000e+00, metadata !"olt", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP40:%.*]] = xor i1 [[TMP37]], [[TMP39]]
+; CHECK-NEXT:    [[TMP41:%.*]] = select nnan nsz afn i1 [[TMP40]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP42:%.*]] = select nnan nsz afn i1 [[TMP15]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP43:%.*]] = call nnan nsz afn float @llvm.copysign.f32(float [[TMP41]], float [[TMP42]]) #[[ATTR3]]
+; CHECK-NEXT:    [[TMP44:%.*]] = select nnan nsz afn i1 [[TMP38]], float [[TMP43]], float [[TMP34]]
+; CHECK-NEXT:    [[TMP45:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP4]], float [[TMP2]], metadata !"uno", metadata !"fpexcept.strict") #[[ATTR3]]
+; CHECK-NEXT:    [[TMP46:%.*]] = select nnan nsz afn i1 [[TMP45]], float 0x7FF8000000000000, float [[TMP44]]
+; CHECK-NEXT:    ret float [[TMP46]]
 ;
   %pow = tail call afn nsz nnan float @_Z3powff(float %x, float %y) #2
   ret float %pow
@@ -624,8 +1285,38 @@ define <2 x float> @test_pow_afn_v2f32_neg0.5(<2 x float> %x) {
 define <2 x float> @test_pow_afn_v2f32_plus_minus_0.5(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_0.5
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 5.000000e-01, float -5.000000e-01>)
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> <float 5.000000e-01, float -5.000000e-01>
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp afn oeq <2 x float> [[TMP7]], [[TMP2]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul afn <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP10:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn une <2 x float> [[TMP10]], [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = and <2 x i1> [[TMP8]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP14:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP6]], <2 x float> [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp afn une <2 x float> [[TMP15]], [[TMP2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP18:%.*]] = and <2 x i1> [[TMP17]], [[TMP16]]
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn <2 x i1> [[TMP18]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP21:%.*]] = fcmp afn oeq <2 x float> [[TMP20]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP23:%.*]] = or <2 x i1> [[TMP21]], [[TMP22]]
+; CHECK-NEXT:    [[TMP24:%.*]] = fcmp afn olt <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP25:%.*]] = xor <2 x i1> [[TMP22]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn <2 x i1> [[TMP25]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP27:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP28:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP26]], <2 x float> [[TMP27]])
+; CHECK-NEXT:    [[TMP29:%.*]] = select afn <2 x i1> [[TMP23]], <2 x float> [[TMP28]], <2 x float> [[TMP19]]
+; CHECK-NEXT:    [[TMP30:%.*]] = fcmp afn uno <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn <2 x i1> [[TMP30]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP29]]
+; CHECK-NEXT:    ret <2 x float> [[TMP31]]
 ;
   %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 0.5, float -0.5>)
   ret <2 x float> %pow
@@ -821,8 +1512,36 @@ define <2 x float> @test_pow_afn_v2f32_plus_minus_3.0(<2 x float> %x) {
 define float @test_pow_afn_f32_3.99(float %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_3.99
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float 0x400FEB8520000000)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 1.000000e+00, float 0x400FEB8520000000
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp afn oeq float [[TMP7]], [[TMP2]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP10:%.*]] = call afn float @llvm.trunc.f32(float [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn une float [[TMP10]], [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = and i1 [[TMP8]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn i1 [[TMP12]], float [[X]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP14:%.*]] = call afn float @llvm.copysign.f32(float [[TMP6]], float [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp afn une float [[TMP15]], [[TMP2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP18:%.*]] = and i1 [[TMP17]], [[TMP16]]
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn i1 [[TMP18]], float 0x7FF8000000000000, float [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP21:%.*]] = fcmp afn oeq float [[TMP20]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP23:%.*]] = or i1 [[TMP21]], [[TMP22]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn i1 [[TMP22]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP25:%.*]] = select afn i1 [[TMP12]], float [[X]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn float @llvm.copysign.f32(float [[TMP24]], float [[TMP25]])
+; CHECK-NEXT:    [[TMP27:%.*]] = select afn i1 [[TMP23]], float [[TMP26]], float [[TMP19]]
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn uno float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP29:%.*]] = select afn i1 [[TMP28]], float 0x7FF8000000000000, float [[TMP27]]
+; CHECK-NEXT:    ret float [[TMP29]]
 ;
   %pow = tail call afn float @_Z3powff(float %x, float 0x400FEB8520000000)
   ret float %pow
@@ -831,8 +1550,38 @@ define float @test_pow_afn_f32_3.99(float %x) {
 define float @test_pow_afn_f32_neg3.99(float %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_neg3.99
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float 0xC00FEB8520000000)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 1.000000e+00, float 0xC00FEB8520000000
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp afn oeq float [[TMP7]], [[TMP2]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP10:%.*]] = call afn float @llvm.trunc.f32(float [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn une float [[TMP10]], [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = and i1 [[TMP8]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn i1 [[TMP12]], float [[X]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP14:%.*]] = call afn float @llvm.copysign.f32(float [[TMP6]], float [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = call afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp afn une float [[TMP15]], [[TMP2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP18:%.*]] = and i1 [[TMP17]], [[TMP16]]
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn i1 [[TMP18]], float 0x7FF8000000000000, float [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP21:%.*]] = fcmp afn oeq float [[TMP20]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP23:%.*]] = or i1 [[TMP21]], [[TMP22]]
+; CHECK-NEXT:    [[TMP24:%.*]] = fcmp afn olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP25:%.*]] = xor i1 [[TMP22]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn i1 [[TMP25]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP27:%.*]] = select afn i1 [[TMP12]], float [[X]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP28:%.*]] = call afn float @llvm.copysign.f32(float [[TMP26]], float [[TMP27]])
+; CHECK-NEXT:    [[TMP29:%.*]] = select afn i1 [[TMP23]], float [[TMP28]], float [[TMP19]]
+; CHECK-NEXT:    [[TMP30:%.*]] = fcmp afn uno float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn i1 [[TMP30]], float 0x7FF8000000000000, float [[TMP29]]
+; CHECK-NEXT:    ret float [[TMP31]]
 ;
   %pow = tail call afn float @_Z3powff(float %x, float 0xC00FEB8520000000)
   ret float %pow
@@ -841,8 +1590,36 @@ define float @test_pow_afn_f32_neg3.99(float %x) {
 define <2 x float> @test_pow_afn_v2f32_3.99(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_3.99
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 0x400FEB8520000000))
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> splat (float 0x400FEB8520000000)
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp afn oeq <2 x float> [[TMP7]], [[TMP2]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul afn <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP10:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn une <2 x float> [[TMP10]], [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = and <2 x i1> [[TMP8]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP14:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP6]], <2 x float> [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp afn une <2 x float> [[TMP15]], [[TMP2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP18:%.*]] = and <2 x i1> [[TMP17]], [[TMP16]]
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn <2 x i1> [[TMP18]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP21:%.*]] = fcmp afn oeq <2 x float> [[TMP20]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP23:%.*]] = or <2 x i1> [[TMP21]], [[TMP22]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn <2 x i1> [[TMP22]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP25:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP26:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP24]], <2 x float> [[TMP25]])
+; CHECK-NEXT:    [[TMP27:%.*]] = select afn <2 x i1> [[TMP23]], <2 x float> [[TMP26]], <2 x float> [[TMP19]]
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp afn uno <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP29:%.*]] = select afn <2 x i1> [[TMP28]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP27]]
+; CHECK-NEXT:    ret <2 x float> [[TMP29]]
 ;
   %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 0x400FEB8520000000, float 0x400FEB8520000000>)
   ret <2 x float> %pow
@@ -851,8 +1628,38 @@ define <2 x float> @test_pow_afn_v2f32_3.99(<2 x float> %x) {
 define <2 x float> @test_pow_afn_v2f32_neg3.99(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_neg3.99
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 0xC00FEB8520000000))
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> splat (float 0xC00FEB8520000000)
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp afn oeq <2 x float> [[TMP7]], [[TMP2]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul afn <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP10:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn une <2 x float> [[TMP10]], [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = and <2 x i1> [[TMP8]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP14:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP6]], <2 x float> [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp afn une <2 x float> [[TMP15]], [[TMP2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP18:%.*]] = and <2 x i1> [[TMP17]], [[TMP16]]
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn <2 x i1> [[TMP18]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP21:%.*]] = fcmp afn oeq <2 x float> [[TMP20]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP23:%.*]] = or <2 x i1> [[TMP21]], [[TMP22]]
+; CHECK-NEXT:    [[TMP24:%.*]] = fcmp afn olt <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP25:%.*]] = xor <2 x i1> [[TMP22]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn <2 x i1> [[TMP25]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP27:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP28:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP26]], <2 x float> [[TMP27]])
+; CHECK-NEXT:    [[TMP29:%.*]] = select afn <2 x i1> [[TMP23]], <2 x float> [[TMP28]], <2 x float> [[TMP19]]
+; CHECK-NEXT:    [[TMP30:%.*]] = fcmp afn uno <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn <2 x i1> [[TMP30]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP29]]
+; CHECK-NEXT:    ret <2 x float> [[TMP31]]
 ;
   %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 0xC00FEB8520000000, float 0xC00FEB8520000000>)
   ret <2 x float> %pow
@@ -861,8 +1668,38 @@ define <2 x float> @test_pow_afn_v2f32_neg3.99(<2 x float> %x) {
 define <2 x float> @test_pow_afn_v2f32_plus_minus_3.99(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_3.99
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 0x400FEB8520000000, float 0xC00FEB8520000000>)
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> <float 0x400FEB8520000000, float 0xC00FEB8520000000>
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp afn oeq <2 x float> [[TMP7]], [[TMP2]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul afn <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP10:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn une <2 x float> [[TMP10]], [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = and <2 x i1> [[TMP8]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP14:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP6]], <2 x float> [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = call afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp afn une <2 x float> [[TMP15]], [[TMP2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP18:%.*]] = and <2 x i1> [[TMP17]], [[TMP16]]
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn <2 x i1> [[TMP18]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP21:%.*]] = fcmp afn oeq <2 x float> [[TMP20]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP23:%.*]] = or <2 x i1> [[TMP21]], [[TMP22]]
+; CHECK-NEXT:    [[TMP24:%.*]] = fcmp afn olt <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP25:%.*]] = xor <2 x i1> [[TMP22]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn <2 x i1> [[TMP25]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP27:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP28:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP26]], <2 x float> [[TMP27]])
+; CHECK-NEXT:    [[TMP29:%.*]] = select afn <2 x i1> [[TMP23]], <2 x float> [[TMP28]], <2 x float> [[TMP19]]
+; CHECK-NEXT:    [[TMP30:%.*]] = fcmp afn uno <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP31:%.*]] = select afn <2 x i1> [[TMP30]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP29]]
+; CHECK-NEXT:    ret <2 x float> [[TMP31]]
 ;
   %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 0x400FEB8520000000, float 0xC00FEB8520000000>)
   ret <2 x float> %pow
@@ -1713,8 +2550,31 @@ define float @test_pow_afn_f32_nnan_ninf__y_4(float %x) {
 define float @test_pow_afn_f32_nnan_ninf__y_4_5(float %x) {
 ; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_4_5
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 4.500000e+00)
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan ninf afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan ninf afn i1 [[TMP1]], float 1.000000e+00, float 4.500000e+00
+; CHECK-NEXT:    [[TMP3:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul nnan ninf afn float [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = call nnan ninf afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp nnan ninf afn oeq float [[TMP7]], [[TMP2]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul nnan ninf afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP10:%.*]] = call nnan ninf afn float @llvm.trunc.f32(float [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp nnan ninf afn une float [[TMP10]], [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = and i1 [[TMP8]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = select nnan ninf afn i1 [[TMP12]], float [[X]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP14:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP6]], float [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = call nnan ninf afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp nnan ninf afn une float [[TMP15]], [[TMP2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp nnan ninf afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP18:%.*]] = and i1 [[TMP17]], [[TMP16]]
+; CHECK-NEXT:    [[TMP19:%.*]] = select nnan ninf afn i1 [[TMP18]], float 0x7FF8000000000000, float [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp nnan ninf afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan ninf afn i1 [[TMP20]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP22:%.*]] = select nnan ninf afn i1 [[TMP12]], float [[X]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP23:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP21]], float [[TMP22]])
+; CHECK-NEXT:    [[TMP24:%.*]] = select nnan ninf afn i1 [[TMP20]], float [[TMP23]], float [[TMP19]]
+; CHECK-NEXT:    ret float [[TMP24]]
 ;
   %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 4.5)
   ret float %pow
@@ -1812,8 +2672,31 @@ define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4(<2 x float> %x) {
 define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4_5(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4_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> splat (float 4.500000e+00))
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan ninf afn <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> splat (float 4.500000e+00)
+; CHECK-NEXT:    [[TMP3:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul nnan ninf afn <2 x float> [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan ninf afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = call nnan ninf afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[TMP7]], [[TMP2]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul nnan ninf afn <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP10:%.*]] = call nnan ninf afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp nnan ninf afn une <2 x float> [[TMP10]], [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = and <2 x i1> [[TMP8]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = select nnan ninf afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP14:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP6]], <2 x float> [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = call nnan ninf afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp nnan ninf afn une <2 x float> [[TMP15]], [[TMP2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp nnan ninf afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP18:%.*]] = and <2 x i1> [[TMP17]], [[TMP16]]
+; CHECK-NEXT:    [[TMP19:%.*]] = select nnan ninf afn <2 x i1> [[TMP18]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan ninf afn <2 x i1> [[TMP20]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP22:%.*]] = select nnan ninf afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP23:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP21]], <2 x float> [[TMP22]])
+; CHECK-NEXT:    [[TMP24:%.*]] = select nnan ninf afn <2 x i1> [[TMP20]], <2 x float> [[TMP23]], <2 x float> [[TMP19]]
+; CHECK-NEXT:    ret <2 x float> [[TMP24]]
 ;
   %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 4.5, float 4.5>)
   ret <2 x float> %pow
@@ -1822,8 +2705,31 @@ define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4_5(<2 x float> %x) {
 define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4_5_undef(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4_5_undef
 ; 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.500000e+00, float poison>)
-; CHECK-NEXT:    ret <2 x float> [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan ninf afn <2 x i1> [[TMP1]], <2 x float> splat (float 1.000000e+00), <2 x float> <float 4.500000e+00, float poison>
+; CHECK-NEXT:    [[TMP3:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul nnan ninf afn <2 x float> [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan ninf afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = call nnan ninf afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[TMP7]], [[TMP2]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul nnan ninf afn <2 x float> [[TMP2]], splat (float 5.000000e-01)
+; CHECK-NEXT:    [[TMP10:%.*]] = call nnan ninf afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp nnan ninf afn une <2 x float> [[TMP10]], [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = and <2 x i1> [[TMP8]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = select nnan ninf afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP14:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP6]], <2 x float> [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = call nnan ninf afn <2 x float> @llvm.trunc.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp nnan ninf afn une <2 x float> [[TMP15]], [[TMP2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp nnan ninf afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP18:%.*]] = and <2 x i1> [[TMP17]], [[TMP16]]
+; CHECK-NEXT:    [[TMP19:%.*]] = select nnan ninf afn <2 x i1> [[TMP18]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan ninf afn <2 x i1> [[TMP20]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP22:%.*]] = select nnan ninf afn <2 x i1> [[TMP12]], <2 x float> [[X]], <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP23:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP21]], <2 x float> [[TMP22]])
+; CHECK-NEXT:    [[TMP24:%.*]] = select nnan ninf afn <2 x i1> [[TMP20]], <2 x float> [[TMP23]], <2 x float> [[TMP19]]
+; CHECK-NEXT:    ret <2 x float> [[TMP24]]
 ;
   %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 4.5, float poison>)
   ret <2 x float> %pow
@@ -2314,8 +3220,43 @@ define float @test_pow_afn_nnan_f32_known_integral_uitofp_i256(float %x, i256 %y
 ; CHECK-LABEL: define float @test_pow_afn_nnan_f32_known_integral_uitofp_i256
 ; CHECK-SAME: (float [[X:%.*]], i256 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp i256 [[Y]] to float
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn float @_Z3powff(float [[X]], float [[Y_CAST]])
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan afn i1 [[TMP1]], float 1.000000e+00, float [[Y_CAST]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp nnan afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select nnan afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan afn float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul nnan afn float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan afn float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan afn oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul nnan afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan afn une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan afn une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp nnan afn olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan afn i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp nnan afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP23:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP24:%.*]] = fcmp nnan afn oeq float [[TMP23]], 1.000000e+00
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp nnan afn olt float [[TMP23]], 1.000000e+00
+; CHECK-NEXT:    [[TMP26:%.*]] = select nnan afn i1 [[TMP25]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP27:%.*]] = select nnan afn i1 [[TMP24]], float 1.000000e+00, float [[TMP26]]
+; CHECK-NEXT:    [[TMP28:%.*]] = select nnan afn i1 [[TMP22]], float [[TMP27]], float [[TMP21]]
+; CHECK-NEXT:    [[TMP29:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP30:%.*]] = fcmp nnan afn oeq float [[TMP29]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP31:%.*]] = fcmp nnan afn oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP32:%.*]] = or i1 [[TMP30]], [[TMP31]]
+; CHECK-NEXT:    [[TMP33:%.*]] = select nnan afn i1 [[TMP31]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP34:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP35:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP33]], float [[TMP34]])
+; CHECK-NEXT:    [[TMP36:%.*]] = select nnan afn i1 [[TMP32]], float [[TMP35]], float [[TMP28]]
+; CHECK-NEXT:    ret float [[TMP36]]
 ;
   %y.cast = uitofp i256 %y to float
   %pow = tail call afn nnan float @_Z3powff(float %x, float %y.cast)
@@ -2327,8 +3268,49 @@ define float @test_pow_afn_nnan_f32_known_integral_sitofp_i256(float %x, i256 %y
 ; CHECK-LABEL: define float @test_pow_afn_nnan_f32_known_integral_sitofp_i256
 ; CHECK-SAME: (float [[X:%.*]], i256 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i256 [[Y]] to float
-; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn float @_Z3powff(float [[X]], float [[Y_CAST]])
-; CHECK-NEXT:    ret float [[POW]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan afn oeq float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan afn i1 [[TMP1]], float 1.000000e+00, float [[Y_CAST]]
+; CHECK-NEXT:    [[TMP3:%.*]] = fcmp nnan afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = select nnan afn i1 [[TMP3]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan afn float @llvm.log2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fmul nnan afn float [[TMP2]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan afn float @llvm.exp2.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan afn oeq float [[TMP9]], [[TMP2]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul nnan afn float [[TMP2]], 5.000000e-01
+; CHECK-NEXT:    [[TMP12:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP11]])
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan afn une float [[TMP12]], [[TMP11]]
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP10]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 1.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP8]], float [[TMP15]])
+; CHECK-NEXT:    [[TMP17:%.*]] = call nnan afn float @llvm.trunc.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan afn une float [[TMP17]], [[TMP2]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp nnan afn olt float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[TMP18]]
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan afn i1 [[TMP20]], float 0x7FF8000000000000, float [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp nnan afn oeq float [[TMP22]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP24:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp nnan afn une float [[TMP2]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP27:%.*]] = fcmp nnan afn oeq float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP28:%.*]] = fcmp nnan afn olt float [[TMP26]], 1.000000e+00
+; CHECK-NEXT:    [[TMP29:%.*]] = xor i1 [[TMP28]], [[TMP25]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select nnan afn i1 [[TMP29]], float 0.000000e+00, float [[TMP24]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select nnan afn i1 [[TMP27]], float 1.000000e+00, float [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select nnan afn i1 [[TMP23]], float [[TMP31]], float [[TMP21]]
+; CHECK-NEXT:    [[TMP33:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP34:%.*]] = fcmp nnan afn oeq float [[TMP33]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP35:%.*]] = fcmp nnan afn oeq float [[TMP4]], 0.000000e+00
+; CHECK-NEXT:    [[TMP36:%.*]] = or i1 [[TMP34]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = fcmp nnan afn olt float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP38:%.*]] = xor i1 [[TMP35]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select nnan afn i1 [[TMP38]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP40:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP4]], float 0.000000e+00
+; CHECK-NEXT:    [[TMP41:%.*]] = call nnan afn float @llvm.copysign.f32(float [[TMP39]], float [[TMP40]])
+; CHECK-NEXT:    [[TMP42:%.*]] = select nnan afn i1 [[TMP36]], float [[TMP41]], float [[TMP32]]
+; CHECK-NEXT:    ret float [[TMP42]]
 ;
   %y.cast = sitofp i256 %y to float
   %pow = tail call afn nnan float @_Z3powff(float %x, float %y.cast)
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
index 2f0db29fc763b..f8c4b82ac2632 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
@@ -597,8 +597,28 @@ define float @test_pown_afn_f32(float %x, i32 %y) {
 ; CHECK-LABEL: define float @test_pown_afn_f32
 ; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call afn float @_Z4pownfi(float [[X]], i32 [[Y]])
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = select afn i1 [[TMP0]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP2:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = and i32 [[Y]], 1
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP7]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[DOTNOT]], float 1.000000e+00, float [[TMP1]]
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn float @llvm.copysign.f32(float [[TMP6]], float [[TMP8]])
+; CHECK-NEXT:    [[TMP10:%.*]] = call afn float @llvm.fabs.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn oeq float [[TMP10]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq float [[TMP1]], 0.000000e+00
+; CHECK-NEXT:    [[TMP13:%.*]] = or i1 [[TMP11]], [[TMP12]]
+; CHECK-NEXT:    [[TMP14:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP15:%.*]] = xor i1 [[TMP12]], [[TMP14]]
+; CHECK-NEXT:    [[TMP16:%.*]] = select afn i1 [[TMP15]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn i1 [[DOTNOT]], float 0.000000e+00, float [[TMP1]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call afn float @llvm.copysign.f32(float [[TMP16]], float [[TMP17]])
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn i1 [[TMP13]], float [[TMP18]], float [[TMP9]]
+; CHECK-NEXT:    ret float [[TMP19]]
 ;
 entry:
   %call = tail call afn float @_Z4pownfi(float %x, i32 %y)
@@ -609,8 +629,28 @@ define <2 x float> @test_pown_afn_v2f32(<2 x float> %x, <2 x i32> %y) {
 ; CHECK-LABEL: define <2 x float> @test_pown_afn_v2f32
 ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[CALL]]
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq <2 x i32> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP1:%.*]] = select afn <2 x i1> [[TMP0]], <2 x float> splat (float 1.000000e+00), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP2:%.*]] = sitofp <2 x i32> [[Y]] to <2 x float>
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP1]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = and <2 x i32> [[Y]], splat (i32 1)
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq <2 x i32> [[TMP7]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[DOTNOT]], <2 x float> splat (float 1.000000e+00), <2 x float> [[TMP1]]
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP6]], <2 x float> [[TMP8]])
+; CHECK-NEXT:    [[TMP10:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP1]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn oeq <2 x float> [[TMP10]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq <2 x float> [[TMP1]], zeroinitializer
+; CHECK-NEXT:    [[TMP13:%.*]] = or <2 x i1> [[TMP11]], [[TMP12]]
+; CHECK-NEXT:    [[TMP14:%.*]] = icmp slt <2 x i32> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP15:%.*]] = xor <2 x i1> [[TMP12]], [[TMP14]]
+; CHECK-NEXT:    [[TMP16:%.*]] = select afn <2 x i1> [[TMP15]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn <2 x i1> [[DOTNOT]], <2 x float> zeroinitializer, <2 x float> [[TMP1]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP16]], <2 x float> [[TMP17]])
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn <2 x i1> [[TMP13]], <2 x float> [[TMP18]], <2 x float> [[TMP9]]
+; CHECK-NEXT:    ret <2 x float> [[TMP19]]
 ;
 entry:
   %call = tail call afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> %y)
@@ -1044,8 +1084,28 @@ define float @test_pown_afn_f32__x_known_positive(float nofpclass(ninf nsub nnor
 ; CHECK-LABEL: define float @test_pown_afn_f32__x_known_positive
 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call afn float @_Z4pownfi(float [[X]], i32 [[Y]])
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = select afn i1 [[TMP0]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP2:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = and i32 [[Y]], 1
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP7]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[DOTNOT]], float 1.000000e+00, float [[TMP1]]
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn float @llvm.copysign.f32(float [[TMP6]], float [[TMP8]])
+; CHECK-NEXT:    [[TMP10:%.*]] = call afn float @llvm.fabs.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn oeq float [[TMP10]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq float [[TMP1]], 0.000000e+00
+; CHECK-NEXT:    [[TMP13:%.*]] = or i1 [[TMP11]], [[TMP12]]
+; CHECK-NEXT:    [[TMP14:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP15:%.*]] = xor i1 [[TMP12]], [[TMP14]]
+; CHECK-NEXT:    [[TMP16:%.*]] = select afn i1 [[TMP15]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn i1 [[DOTNOT]], float 0.000000e+00, float [[TMP1]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call afn float @llvm.copysign.f32(float [[TMP16]], float [[TMP17]])
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn i1 [[TMP13]], float [[TMP18]], float [[TMP9]]
+; CHECK-NEXT:    ret float [[TMP19]]
 ;
 entry:
   %call = tail call afn float @_Z4pownfi(float %x, i32 %y)
@@ -1077,8 +1137,17 @@ define float @test_pown_afn_f32__x_known_positive__y_4(float nofpclass(ninf nsub
 ; CHECK-LABEL: define float @test_pown_afn_f32__x_known_positive__y_4
 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call afn float @_Z4pownfi(float [[X]], i32 4)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    [[TMP0:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call afn float @llvm.log2.f32(float [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul afn float [[TMP1]], 4.000000e+00
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.exp2.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.fabs.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp afn oeq float [[TMP5]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select i1 [[TMP6]], float 0x7FF0000000000000, float [[TMP4]]
+; CHECK-NEXT:    [[TMP9:%.*]] = select i1 [[TMP7]], float 0.000000e+00, float [[TMP8]]
+; CHECK-NEXT:    ret float [[TMP9]]
 ;
 entry:
   %call = tail call afn float @_Z4pownfi(float %x, i32 4)
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll
index 6c4dd9dccbd4f..744b858309ed3 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll
@@ -47,8 +47,33 @@ define <2 x float> @test_powr_fast_v2f32(<2 x float> %x, <2 x float> %y) {
 define float @test_powr_afn_f32(float %x, float %y) {
 ; CHECK-LABEL: define float @test_powr_afn_f32
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[Y]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn olt float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0x7FF0000000000000, float 0.000000e+00
+; CHECK-NEXT:    [[TMP9:%.*]] = select afn i1 [[TMP7]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP11:%.*]] = select afn i1 [[TMP10]], float 0x7FF8000000000000, float [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn i1 [[TMP12]], float [[TMP11]], float [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP15:%.*]] = fcmp afn une float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = and i1 [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn i1 [[TMP16]], float [[TMP9]], float [[TMP13]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call afn float @llvm.fabs.f32(float [[Y]])
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn oeq float [[TMP18]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp afn une float [[TMP2]], 1.000000e+00
+; CHECK-NEXT:    [[TMP21:%.*]] = and i1 [[TMP19]], [[TMP20]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn olt float [[TMP2]], 1.000000e+00
+; CHECK-NEXT:    [[TMP23:%.*]] = select afn i1 [[TMP22]], float [[TMP8]], float [[TMP9]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn i1 [[TMP21]], float [[TMP23]], float [[TMP17]]
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn uno float [[TMP2]], [[Y]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn i1 [[TMP25]], float 0x7FF8000000000000, float [[TMP24]]
+; CHECK-NEXT:    ret float [[TMP26]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float %y)
   ret float %powr
@@ -57,8 +82,31 @@ define float @test_powr_afn_f32(float %x, float %y) {
 define float @test_powr_afn_f32_nnan(float %x, float %y) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_nnan
 ; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan afn float @_Z4powrff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp nnan afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select nnan afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call nnan afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul nnan afn float [[Y]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call nnan afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp nnan afn olt float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select nnan afn i1 [[TMP7]], float 0x7FF0000000000000, float 0.000000e+00
+; CHECK-NEXT:    [[TMP9:%.*]] = select nnan afn i1 [[TMP7]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan afn oeq float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP11:%.*]] = select nnan afn i1 [[TMP10]], float 0x7FF8000000000000, float [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp nnan afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP13:%.*]] = select nnan afn i1 [[TMP12]], float [[TMP11]], float [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = fcmp nnan afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP15:%.*]] = fcmp nnan afn une float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = and i1 [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = select nnan afn i1 [[TMP16]], float [[TMP9]], float [[TMP13]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call nnan afn float @llvm.fabs.f32(float [[Y]])
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp nnan afn oeq float [[TMP18]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp nnan afn une float [[TMP2]], 1.000000e+00
+; CHECK-NEXT:    [[TMP21:%.*]] = and i1 [[TMP19]], [[TMP20]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp nnan afn olt float [[TMP2]], 1.000000e+00
+; CHECK-NEXT:    [[TMP23:%.*]] = select nnan afn i1 [[TMP22]], float [[TMP8]], float [[TMP9]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select nnan afn i1 [[TMP21]], float [[TMP23]], float [[TMP17]]
+; CHECK-NEXT:    ret float [[TMP24]]
 ;
   %powr = tail call afn nnan float @_Z4powrff(float %x, float %y)
   ret float %powr
@@ -67,8 +115,33 @@ define float @test_powr_afn_f32_nnan(float %x, float %y) {
 define <2 x float> @test_powr_afn_v2f32(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32
 ; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[Y]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn olt <2 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP9:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <2 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = select afn <2 x i1> [[TMP10]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[TMP11]], <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP15:%.*]] = fcmp afn une <2 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP16:%.*]] = and <2 x i1> [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn <2 x i1> [[TMP16]], <2 x float> [[TMP9]], <2 x float> [[TMP13]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[Y]])
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn oeq <2 x float> [[TMP18]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp afn une <2 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP21:%.*]] = and <2 x i1> [[TMP19]], [[TMP20]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn olt <2 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP23:%.*]] = select afn <2 x i1> [[TMP22]], <2 x float> [[TMP8]], <2 x float> [[TMP9]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn <2 x i1> [[TMP21]], <2 x float> [[TMP23]], <2 x float> [[TMP17]]
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn uno <2 x float> [[TMP2]], [[Y]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn <2 x i1> [[TMP25]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP24]]
+; CHECK-NEXT:    ret <2 x float> [[TMP26]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
   ret <2 x float> %powr
@@ -77,8 +150,33 @@ define <2 x float> @test_powr_afn_v2f32(<2 x float> %x, <2 x float> %y) {
 define <3 x float> @test_powr_afn_v3f32(<3 x float> %x, <3 x float> %y) {
 ; CHECK-LABEL: define <3 x float> @test_powr_afn_v3f32
 ; CHECK-SAME: (<3 x float> [[X:%.*]], <3 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> [[X]], <3 x float> [[Y]])
-; CHECK-NEXT:    ret <3 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <3 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <3 x i1> [[TMP1]], <3 x float> splat (float 0x7FF8000000000000), <3 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <3 x float> @llvm.fabs.v3f32(<3 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <3 x float> @llvm.log2.v3f32(<3 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <3 x float> [[Y]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <3 x float> @llvm.exp2.v3f32(<3 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn olt <3 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <3 x i1> [[TMP7]], <3 x float> splat (float 0x7FF0000000000000), <3 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP9:%.*]] = select afn <3 x i1> [[TMP7]], <3 x float> zeroinitializer, <3 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <3 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = select afn <3 x i1> [[TMP10]], <3 x float> splat (float 0x7FF8000000000000), <3 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq <3 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn <3 x i1> [[TMP12]], <3 x float> [[TMP11]], <3 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = fcmp afn oeq <3 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP15:%.*]] = fcmp afn une <3 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP16:%.*]] = and <3 x i1> [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn <3 x i1> [[TMP16]], <3 x float> [[TMP9]], <3 x float> [[TMP13]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call afn <3 x float> @llvm.fabs.v3f32(<3 x float> [[Y]])
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn oeq <3 x float> [[TMP18]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp afn une <3 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP21:%.*]] = and <3 x i1> [[TMP19]], [[TMP20]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn olt <3 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP23:%.*]] = select afn <3 x i1> [[TMP22]], <3 x float> [[TMP8]], <3 x float> [[TMP9]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn <3 x i1> [[TMP21]], <3 x float> [[TMP23]], <3 x float> [[TMP17]]
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn uno <3 x float> [[TMP2]], [[Y]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn <3 x i1> [[TMP25]], <3 x float> splat (float 0x7FF8000000000000), <3 x float> [[TMP24]]
+; CHECK-NEXT:    ret <3 x float> [[TMP26]]
 ;
   %powr = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> %y)
   ret <3 x float> %powr
@@ -87,8 +185,33 @@ define <3 x float> @test_powr_afn_v3f32(<3 x float> %x, <3 x float> %y) {
 define <4 x float> @test_powr_afn_v4f32(<4 x float> %x, <4 x float> %y) {
 ; CHECK-LABEL: define <4 x float> @test_powr_afn_v4f32
 ; CHECK-SAME: (<4 x float> [[X:%.*]], <4 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <4 x float> @_Z4powrDv4_fS_(<4 x float> [[X]], <4 x float> [[Y]])
-; CHECK-NEXT:    ret <4 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <4 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <4 x i1> [[TMP1]], <4 x float> splat (float 0x7FF8000000000000), <4 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <4 x float> @llvm.log2.v4f32(<4 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <4 x float> [[Y]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <4 x float> @llvm.exp2.v4f32(<4 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn olt <4 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <4 x i1> [[TMP7]], <4 x float> splat (float 0x7FF0000000000000), <4 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP9:%.*]] = select afn <4 x i1> [[TMP7]], <4 x float> zeroinitializer, <4 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <4 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = select afn <4 x i1> [[TMP10]], <4 x float> splat (float 0x7FF8000000000000), <4 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq <4 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn <4 x i1> [[TMP12]], <4 x float> [[TMP11]], <4 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = fcmp afn oeq <4 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP15:%.*]] = fcmp afn une <4 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP16:%.*]] = and <4 x i1> [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn <4 x i1> [[TMP16]], <4 x float> [[TMP9]], <4 x float> [[TMP13]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call afn <4 x float> @llvm.fabs.v4f32(<4 x float> [[Y]])
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn oeq <4 x float> [[TMP18]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp afn une <4 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP21:%.*]] = and <4 x i1> [[TMP19]], [[TMP20]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn olt <4 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP23:%.*]] = select afn <4 x i1> [[TMP22]], <4 x float> [[TMP8]], <4 x float> [[TMP9]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn <4 x i1> [[TMP21]], <4 x float> [[TMP23]], <4 x float> [[TMP17]]
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn uno <4 x float> [[TMP2]], [[Y]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn <4 x i1> [[TMP25]], <4 x float> splat (float 0x7FF8000000000000), <4 x float> [[TMP24]]
+; CHECK-NEXT:    ret <4 x float> [[TMP26]]
 ;
   %powr = tail call afn <4 x float> @_Z4powrDv4_fS_(<4 x float> %x, <4 x float> %y)
   ret <4 x float> %powr
@@ -97,8 +220,33 @@ define <4 x float> @test_powr_afn_v4f32(<4 x float> %x, <4 x float> %y) {
 define <8 x float> @test_powr_afn_v8f32(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: define <8 x float> @test_powr_afn_v8f32
 ; CHECK-SAME: (<8 x float> [[X:%.*]], <8 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <8 x float> @_Z4powrDv8_fS_(<8 x float> [[X]], <8 x float> [[Y]])
-; CHECK-NEXT:    ret <8 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <8 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <8 x i1> [[TMP1]], <8 x float> splat (float 0x7FF8000000000000), <8 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <8 x float> @llvm.fabs.v8f32(<8 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <8 x float> @llvm.log2.v8f32(<8 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <8 x float> [[Y]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <8 x float> @llvm.exp2.v8f32(<8 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn olt <8 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <8 x i1> [[TMP7]], <8 x float> splat (float 0x7FF0000000000000), <8 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP9:%.*]] = select afn <8 x i1> [[TMP7]], <8 x float> zeroinitializer, <8 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <8 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = select afn <8 x i1> [[TMP10]], <8 x float> splat (float 0x7FF8000000000000), <8 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq <8 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn <8 x i1> [[TMP12]], <8 x float> [[TMP11]], <8 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = fcmp afn oeq <8 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP15:%.*]] = fcmp afn une <8 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP16:%.*]] = and <8 x i1> [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn <8 x i1> [[TMP16]], <8 x float> [[TMP9]], <8 x float> [[TMP13]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call afn <8 x float> @llvm.fabs.v8f32(<8 x float> [[Y]])
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn oeq <8 x float> [[TMP18]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp afn une <8 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP21:%.*]] = and <8 x i1> [[TMP19]], [[TMP20]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn olt <8 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP23:%.*]] = select afn <8 x i1> [[TMP22]], <8 x float> [[TMP8]], <8 x float> [[TMP9]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn <8 x i1> [[TMP21]], <8 x float> [[TMP23]], <8 x float> [[TMP17]]
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn uno <8 x float> [[TMP2]], [[Y]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn <8 x i1> [[TMP25]], <8 x float> splat (float 0x7FF8000000000000), <8 x float> [[TMP24]]
+; CHECK-NEXT:    ret <8 x float> [[TMP26]]
 ;
   %powr = tail call afn <8 x float> @_Z4powrDv8_fS_(<8 x float> %x, <8 x float> %y)
   ret <8 x float> %powr
@@ -107,8 +255,33 @@ define <8 x float> @test_powr_afn_v8f32(<8 x float> %x, <8 x float> %y) {
 define <16 x float> @test_powr_afn_v16f32(<16 x float> %x, <16 x float> %y) {
 ; CHECK-LABEL: define <16 x float> @test_powr_afn_v16f32
 ; CHECK-SAME: (<16 x float> [[X:%.*]], <16 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <16 x float> @_Z4powrDv16_fS_(<16 x float> [[X]], <16 x float> [[Y]])
-; CHECK-NEXT:    ret <16 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <16 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <16 x i1> [[TMP1]], <16 x float> splat (float 0x7FF8000000000000), <16 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <16 x float> @llvm.fabs.v16f32(<16 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <16 x float> @llvm.log2.v16f32(<16 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <16 x float> [[Y]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <16 x float> @llvm.exp2.v16f32(<16 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn olt <16 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <16 x i1> [[TMP7]], <16 x float> splat (float 0x7FF0000000000000), <16 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP9:%.*]] = select afn <16 x i1> [[TMP7]], <16 x float> zeroinitializer, <16 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <16 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = select afn <16 x i1> [[TMP10]], <16 x float> splat (float 0x7FF8000000000000), <16 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq <16 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn <16 x i1> [[TMP12]], <16 x float> [[TMP11]], <16 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = fcmp afn oeq <16 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP15:%.*]] = fcmp afn une <16 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP16:%.*]] = and <16 x i1> [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn <16 x i1> [[TMP16]], <16 x float> [[TMP9]], <16 x float> [[TMP13]]
+; CHECK-NEXT:    [[TMP18:%.*]] = call afn <16 x float> @llvm.fabs.v16f32(<16 x float> [[Y]])
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn oeq <16 x float> [[TMP18]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp afn une <16 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP21:%.*]] = and <16 x i1> [[TMP19]], [[TMP20]]
+; CHECK-NEXT:    [[TMP22:%.*]] = fcmp afn olt <16 x float> [[TMP2]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP23:%.*]] = select afn <16 x i1> [[TMP22]], <16 x float> [[TMP8]], <16 x float> [[TMP9]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn <16 x i1> [[TMP21]], <16 x float> [[TMP23]], <16 x float> [[TMP17]]
+; CHECK-NEXT:    [[TMP25:%.*]] = fcmp afn uno <16 x float> [[TMP2]], [[Y]]
+; CHECK-NEXT:    [[TMP26:%.*]] = select afn <16 x i1> [[TMP25]], <16 x float> splat (float 0x7FF8000000000000), <16 x float> [[TMP24]]
+; CHECK-NEXT:    ret <16 x float> [[TMP26]]
 ;
   %powr = tail call afn <16 x float> @_Z4powrDv16_fS_(<16 x float> %x, <16 x float> %y)
   ret <16 x float> %powr
@@ -487,8 +660,7 @@ define float @test_powr_fast_f32_nobuiltin(float %x, float %y) {
 define float @test_powr_afn_f32_poison(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_poison
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float poison)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    ret float poison
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float poison)
   ret float %powr
@@ -533,8 +705,15 @@ define <2 x float> @test_powr_afn_v2f32_neg0.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_plus_minus_0.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_plus_minus_0.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> <float 0.000000e+00, float -0.000000e+00>)
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], <float 0.000000e+00, float -0.000000e+00>
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn ueq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP6]]
+; CHECK-NEXT:    ret <2 x float> [[TMP8]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 0.0, float -0.0>)
   ret <2 x float> %powr
@@ -601,8 +780,19 @@ define <2 x float> @test_powr_afn_v2f32_neg0.5(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_plus_minus_0.5(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_plus_minus_0.5
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> <float 5.000000e-01, float -5.000000e-01>)
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], <float 5.000000e-01, float -5.000000e-01>
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> <float 0.000000e+00, float 0x7FF0000000000000>, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> <float 0x7FF0000000000000, float 0.000000e+00>, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 0.5, float -0.5>)
   ret <2 x float> %powr
@@ -669,8 +859,19 @@ define <2 x float> @test_powr_afn_v2f32_neg1.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_plus_minus_1.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_plus_minus_1.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> <float 1.000000e+00, float -1.000000e+00>)
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], <float 1.000000e+00, float -1.000000e+00>
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> <float 0.000000e+00, float 0x7FF0000000000000>, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> <float 0x7FF0000000000000, float 0.000000e+00>, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 1.0, float -1.0>)
   ret <2 x float> %powr
@@ -708,8 +909,19 @@ define float @test_powr_afn_f32_2.0(float %x) {
 define float @test_powr_afn_f32_neg2.0(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_neg2.0
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float -2.000000e+00)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], -2.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0x7FF0000000000000, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0.000000e+00, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float -2.0)
   ret float %powr
@@ -728,8 +940,19 @@ define <2 x float> @test_powr_afn_v2f32_2.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_neg2.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_neg2.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float -2.000000e+00))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float -2.000000e+00)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> zeroinitializer, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float -2.0, float -2.0>)
   ret <2 x float> %powr
@@ -738,8 +961,19 @@ define <2 x float> @test_powr_afn_v2f32_neg2.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_plus_minus_2.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_plus_minus_2.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> <float 2.000000e+00, float -2.000000e+00>)
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], <float 2.000000e+00, float -2.000000e+00>
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> <float 0.000000e+00, float 0x7FF0000000000000>, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> <float 0x7FF0000000000000, float 0.000000e+00>, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 2.0, float -2.0>)
   ret <2 x float> %powr
@@ -748,8 +982,19 @@ define <2 x float> @test_powr_afn_v2f32_plus_minus_2.0(<2 x float> %x) {
 define float @test_powr_afn_f32_3.0(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_3.0
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float 3.000000e+00)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], 3.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0.000000e+00, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0x7FF0000000000000, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float 3.0)
   ret float %powr
@@ -758,8 +1003,19 @@ define float @test_powr_afn_f32_3.0(float %x) {
 define float @test_powr_afn_f32_neg3.0(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_neg3.0
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float -3.000000e+00)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], -3.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0x7FF0000000000000, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0.000000e+00, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float -3.0)
   ret float %powr
@@ -768,8 +1024,19 @@ define float @test_powr_afn_f32_neg3.0(float %x) {
 define <2 x float> @test_powr_afn_v2f32_3.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_3.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 3.000000e+00))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float 3.000000e+00)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> zeroinitializer, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 3.0, float 3.0>)
   ret <2 x float> %powr
@@ -778,8 +1045,19 @@ define <2 x float> @test_powr_afn_v2f32_3.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_neg3.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_neg3.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float -3.000000e+00))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float -3.000000e+00)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> zeroinitializer, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float -3.0, float -3.0>)
   ret <2 x float> %powr
@@ -788,8 +1066,19 @@ define <2 x float> @test_powr_afn_v2f32_neg3.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_plus_minus_3.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_plus_minus_3.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> <float 3.000000e+00, float -3.000000e+00>)
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], <float 3.000000e+00, float -3.000000e+00>
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> <float 0.000000e+00, float 0x7FF0000000000000>, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> <float 0x7FF0000000000000, float 0.000000e+00>, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 3.0, float -3.0>)
   ret <2 x float> %powr
@@ -798,8 +1087,19 @@ define <2 x float> @test_powr_afn_v2f32_plus_minus_3.0(<2 x float> %x) {
 define float @test_powr_afn_f32_3.99(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_3.99
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float 0x400FEB8520000000)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], 0x400FEB8520000000
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0.000000e+00, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0x7FF0000000000000, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float 0x400FEB8520000000)
   ret float %powr
@@ -808,8 +1108,19 @@ define float @test_powr_afn_f32_3.99(float %x) {
 define float @test_powr_afn_f32_neg3.99(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_neg3.99
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float 0xC00FEB8520000000)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], 0xC00FEB8520000000
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0x7FF0000000000000, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0.000000e+00, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float 0xC00FEB8520000000)
   ret float %powr
@@ -818,8 +1129,19 @@ define float @test_powr_afn_f32_neg3.99(float %x) {
 define <2 x float> @test_powr_afn_v2f32_3.99(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_3.99
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 0x400FEB8520000000))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float 0x400FEB8520000000)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> zeroinitializer, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 0x400FEB8520000000, float 0x400FEB8520000000>)
   ret <2 x float> %powr
@@ -828,8 +1150,19 @@ define <2 x float> @test_powr_afn_v2f32_3.99(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_neg3.99(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_neg3.99
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 0xC00FEB8520000000))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float 0xC00FEB8520000000)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> zeroinitializer, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 0xC00FEB8520000000, float 0xC00FEB8520000000>)
   ret <2 x float> %powr
@@ -838,8 +1171,19 @@ define <2 x float> @test_powr_afn_v2f32_neg3.99(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_plus_minus_3.99(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_plus_minus_3.99
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> <float 0x400FEB8520000000, float 0xC00FEB8520000000>)
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], <float 0x400FEB8520000000, float 0xC00FEB8520000000>
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> <float 0.000000e+00, float 0x7FF0000000000000>, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> <float 0x7FF0000000000000, float 0.000000e+00>, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 0x400FEB8520000000, float 0xC00FEB8520000000>)
   ret <2 x float> %powr
@@ -848,8 +1192,19 @@ define <2 x float> @test_powr_afn_v2f32_plus_minus_3.99(<2 x float> %x) {
 define float @test_powr_afn_f32_8.0(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_8.0
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float 8.000000e+00)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], 8.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0.000000e+00, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0x7FF0000000000000, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float 8.0)
   ret float %powr
@@ -858,8 +1213,19 @@ define float @test_powr_afn_f32_8.0(float %x) {
 define float @test_powr_afn_f32_neg8.0(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_neg8.0
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float -8.000000e+00)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], -8.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0x7FF0000000000000, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0.000000e+00, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float -8.0)
   ret float %powr
@@ -868,8 +1234,19 @@ define float @test_powr_afn_f32_neg8.0(float %x) {
 define <2 x float> @test_powr_afn_v2f32_8.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_8.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 8.000000e+00))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float 8.000000e+00)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> zeroinitializer, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 8.0, float 8.0>)
   ret <2 x float> %powr
@@ -878,8 +1255,19 @@ define <2 x float> @test_powr_afn_v2f32_8.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_neg8.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_neg8.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float -8.000000e+00))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float -8.000000e+00)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> zeroinitializer, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float -8.0, float -8.0>)
   ret <2 x float> %powr
@@ -888,8 +1276,19 @@ define <2 x float> @test_powr_afn_v2f32_neg8.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_plus_minus_8.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_plus_minus_8.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> <float 8.000000e+00, float -8.000000e+00>)
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], <float 8.000000e+00, float -8.000000e+00>
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> <float 0.000000e+00, float 0x7FF0000000000000>, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> <float 0x7FF0000000000000, float 0.000000e+00>, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 8.0, float -8.0>)
   ret <2 x float> %powr
@@ -898,8 +1297,19 @@ define <2 x float> @test_powr_afn_v2f32_plus_minus_8.0(<2 x float> %x) {
 define float @test_powr_afn_f32_12.0(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_12.0
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float 1.200000e+01)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], 1.200000e+01
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0.000000e+00, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0x7FF0000000000000, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float 12.0)
   ret float %powr
@@ -908,8 +1318,19 @@ define float @test_powr_afn_f32_12.0(float %x) {
 define float @test_powr_afn_f32_neg12.0(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_neg12.0
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float -1.200000e+01)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], -1.200000e+01
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0x7FF0000000000000, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0.000000e+00, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float -12.0)
   ret float %powr
@@ -918,8 +1339,19 @@ define float @test_powr_afn_f32_neg12.0(float %x) {
 define <2 x float> @test_powr_afn_v2f32_12.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_12.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 1.200000e+01))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float 1.200000e+01)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> zeroinitializer, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 12.0, float 12.0>)
   ret <2 x float> %powr
@@ -928,8 +1360,19 @@ define <2 x float> @test_powr_afn_v2f32_12.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_neg12.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_neg12.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float -1.200000e+01))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float -1.200000e+01)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> zeroinitializer, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float -12.0, float -12.0>)
   ret <2 x float> %powr
@@ -938,8 +1381,19 @@ define <2 x float> @test_powr_afn_v2f32_neg12.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_plus_minus_12.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_plus_minus_12.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> <float 1.200000e+01, float -1.200000e+01>)
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], <float 1.200000e+01, float -1.200000e+01>
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> <float 0.000000e+00, float 0x7FF0000000000000>, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> <float 0x7FF0000000000000, float 0.000000e+00>, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 12.0, float -12.0>)
   ret <2 x float> %powr
@@ -948,8 +1402,19 @@ define <2 x float> @test_powr_afn_v2f32_plus_minus_12.0(<2 x float> %x) {
 define float @test_powr_afn_f32_13.0(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_13.0
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float 1.300000e+01)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], 1.300000e+01
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0.000000e+00, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0x7FF0000000000000, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float 13.0)
   ret float %powr
@@ -958,8 +1423,19 @@ define float @test_powr_afn_f32_13.0(float %x) {
 define float @test_powr_afn_f32_neg13.0(float %x) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_neg13.0
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float -1.300000e+01)
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], -1.300000e+01
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0x7FF0000000000000, float [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float 0.000000e+00, float [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
+; CHECK-NEXT:    ret float [[TMP12]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float -13.0)
   ret float %powr
@@ -968,8 +1444,19 @@ define float @test_powr_afn_f32_neg13.0(float %x) {
 define <2 x float> @test_powr_afn_v2f32_13.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_13.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 1.300000e+01))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float 1.300000e+01)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> zeroinitializer, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 13.0, float 13.0>)
   ret <2 x float> %powr
@@ -978,8 +1465,19 @@ define <2 x float> @test_powr_afn_v2f32_13.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_neg13.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_neg13.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> splat (float -1.300000e+01))
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], splat (float -1.300000e+01)
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> zeroinitializer, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float -13.0, float -13.0>)
   ret <2 x float> %powr
@@ -988,8 +1486,19 @@ define <2 x float> @test_powr_afn_v2f32_neg13.0(<2 x float> %x) {
 define <2 x float> @test_powr_afn_v2f32_plus_minus_13.0(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_plus_minus_13.0
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> <float 1.300000e+01, float -1.300000e+01>)
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], <float 1.300000e+01, float -1.300000e+01>
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> <float 0.000000e+00, float 0x7FF0000000000000>, <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> <float 0x7FF0000000000000, float 0.000000e+00>, <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = select afn <2 x i1> [[TMP11]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    ret <2 x float> [[TMP12]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> <float 13.0, float -13.0>)
   ret <2 x float> %powr
@@ -998,8 +1507,29 @@ define <2 x float> @test_powr_afn_v2f32_plus_minus_13.0(<2 x float> %x) {
 define float @test_powr_afn_f32_nnan_x_known_positive(float nofpclass(ninf nnorm nsub) %x, float %y) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_nnan_x_known_positive
 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan afn float @_Z4powrff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan afn float [[Y]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp nnan afn olt float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = select nnan afn i1 [[TMP5]], float 0x7FF0000000000000, float 0.000000e+00
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan afn i1 [[TMP5]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp nnan afn oeq float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP9:%.*]] = select nnan afn i1 [[TMP8]], float 0x7FF8000000000000, float [[TMP6]]
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP11:%.*]] = select nnan afn i1 [[TMP10]], float [[TMP9]], float [[TMP4]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp nnan afn oeq float [[X]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan afn une float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP12]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan afn i1 [[TMP14]], float [[TMP7]], float [[TMP11]]
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan afn float @llvm.fabs.f32(float [[Y]])
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp nnan afn oeq float [[TMP16]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan afn une float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP19:%.*]] = and i1 [[TMP17]], [[TMP18]]
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp nnan afn olt float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan afn i1 [[TMP20]], float [[TMP6]], float [[TMP7]]
+; CHECK-NEXT:    [[TMP22:%.*]] = select nnan afn i1 [[TMP19]], float [[TMP21]], float [[TMP15]]
+; CHECK-NEXT:    ret float [[TMP22]]
 ;
   %powr = tail call afn nnan float @_Z4powrff(float %x, float %y)
   ret float %powr
@@ -1020,8 +1550,29 @@ define float @test_powr_afn_f32_nnan_ninf_x_known_positive(float nofpclass(ninf
 define <2 x float> @test_powr_afn_v2f32_nnan_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_x_known_positive
 ; CHECK-SAME: (<2 x float> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan afn <2 x float> [[Y]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp nnan afn olt <2 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP6:%.*]] = select nnan afn <2 x i1> [[TMP5]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan afn <2 x i1> [[TMP5]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp nnan afn oeq <2 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP9:%.*]] = select nnan afn <2 x i1> [[TMP8]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp nnan afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = select nnan afn <2 x i1> [[TMP10]], <2 x float> [[TMP9]], <2 x float> [[TMP4]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp nnan afn oeq <2 x float> [[X]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp nnan afn une <2 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP14:%.*]] = and <2 x i1> [[TMP12]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan afn <2 x i1> [[TMP14]], <2 x float> [[TMP7]], <2 x float> [[TMP11]]
+; CHECK-NEXT:    [[TMP16:%.*]] = call nnan afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[Y]])
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp nnan afn oeq <2 x float> [[TMP16]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp nnan afn une <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP19:%.*]] = and <2 x i1> [[TMP17]], [[TMP18]]
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp nnan afn olt <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP21:%.*]] = select nnan afn <2 x i1> [[TMP20]], <2 x float> [[TMP6]], <2 x float> [[TMP7]]
+; CHECK-NEXT:    [[TMP22:%.*]] = select nnan afn <2 x i1> [[TMP19]], <2 x float> [[TMP21]], <2 x float> [[TMP15]]
+; CHECK-NEXT:    ret <2 x float> [[TMP22]]
 ;
   %powr = tail call afn nnan <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
   ret <2 x float> %powr
@@ -1052,8 +1603,31 @@ define float @test_powr_f32_x_known_positive(float nofpclass(ninf nnorm nsub) %x
 define float @test_powr_afn_f32_x_known_positive(float nofpclass(ninf nnorm nsub) %x, float %y) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_x_known_positive
 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float [[Y]])
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul afn float [[Y]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp afn olt float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = select afn i1 [[TMP5]], float 0x7FF0000000000000, float 0.000000e+00
+; CHECK-NEXT:    [[TMP7:%.*]] = select afn i1 [[TMP5]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp afn oeq float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP9:%.*]] = select afn i1 [[TMP8]], float 0x7FF8000000000000, float [[TMP6]]
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP11:%.*]] = select afn i1 [[TMP10]], float [[TMP9]], float [[TMP4]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq float [[X]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une float [[Y]], 0.000000e+00
+; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP12]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn i1 [[TMP14]], float [[TMP7]], float [[TMP11]]
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn float @llvm.fabs.f32(float [[Y]])
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp afn oeq float [[TMP16]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP19:%.*]] = and i1 [[TMP17]], [[TMP18]]
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp afn olt float [[X]], 1.000000e+00
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn i1 [[TMP20]], float [[TMP6]], float [[TMP7]]
+; CHECK-NEXT:    [[TMP22:%.*]] = select afn i1 [[TMP19]], float [[TMP21]], float [[TMP15]]
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn uno float [[X]], [[Y]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn i1 [[TMP23]], float 0x7FF8000000000000, float [[TMP22]]
+; CHECK-NEXT:    ret float [[TMP24]]
 ;
   %powr = tail call afn float @_Z4powrff(float %x, float %y)
   ret float %powr
@@ -1072,8 +1646,31 @@ define <2 x float> @test_powr_v2f32_x_known_positive(<2 x float> nofpclass(ninf
 define <2 x float> @test_powr_afn_v2f32_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_x_known_positive
 ; CHECK-SAME: (<2 x float> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x float> [[Y:%.*]]) {
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul afn <2 x float> [[Y]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp afn olt <2 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP6:%.*]] = select afn <2 x i1> [[TMP5]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP7:%.*]] = select afn <2 x i1> [[TMP5]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP8:%.*]] = fcmp afn oeq <2 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP9:%.*]] = select afn <2 x i1> [[TMP8]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = select afn <2 x i1> [[TMP10]], <2 x float> [[TMP9]], <2 x float> [[TMP4]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq <2 x float> [[X]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP13:%.*]] = fcmp afn une <2 x float> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP14:%.*]] = and <2 x i1> [[TMP12]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn <2 x i1> [[TMP14]], <2 x float> [[TMP7]], <2 x float> [[TMP11]]
+; CHECK-NEXT:    [[TMP16:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[Y]])
+; CHECK-NEXT:    [[TMP17:%.*]] = fcmp afn oeq <2 x float> [[TMP16]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn une <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP19:%.*]] = and <2 x i1> [[TMP17]], [[TMP18]]
+; CHECK-NEXT:    [[TMP20:%.*]] = fcmp afn olt <2 x float> [[X]], splat (float 1.000000e+00)
+; CHECK-NEXT:    [[TMP21:%.*]] = select afn <2 x i1> [[TMP20]], <2 x float> [[TMP6]], <2 x float> [[TMP7]]
+; CHECK-NEXT:    [[TMP22:%.*]] = select afn <2 x i1> [[TMP19]], <2 x float> [[TMP21]], <2 x float> [[TMP15]]
+; CHECK-NEXT:    [[TMP23:%.*]] = fcmp afn uno <2 x float> [[X]], [[Y]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select afn <2 x i1> [[TMP23]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP22]]
+; CHECK-NEXT:    ret <2 x float> [[TMP24]]
 ;
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
   ret <2 x float> %powr
@@ -1095,8 +1692,26 @@ define float @test_powr_afn_f32_known_integral_sitofp(float %x, i32 %y) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_known_integral_sitofp
 ; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float [[Y_CAST]])
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], [[Y_CAST]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0x7FF0000000000000, float 0.000000e+00
+; CHECK-NEXT:    [[TMP9:%.*]] = select afn i1 [[TMP7]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP11:%.*]] = select afn i1 [[TMP10]], float 0x7FF8000000000000, float [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP13:%.*]] = select afn i1 [[TMP12]], float [[TMP11]], float [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP15:%.*]] = icmp ne i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP16:%.*]] = and i1 [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = select afn i1 [[TMP16]], float [[TMP9]], float [[TMP13]]
+; CHECK-NEXT:    [[TMP18:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP19:%.*]] = select afn i1 [[TMP18]], float 0x7FF8000000000000, float [[TMP17]]
+; CHECK-NEXT:    ret float [[TMP19]]
 ;
   %y.cast = sitofp i32 %y to float
   %powr = tail call afn float @_Z4powrff(float %x, float %y.cast)
@@ -1133,8 +1748,23 @@ define float @test_powr_afn_f32_known_integral_uitofp(float %x, i32 %y) {
 ; CHECK-LABEL: define float @test_powr_afn_f32_known_integral_uitofp
 ; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp i32 [[Y]] to float
-; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float [[Y_CAST]])
-; CHECK-NEXT:    ret float [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn i1 [[TMP1]], float 0x7FF8000000000000, float [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn float [[TMP4]], [[Y_CAST]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn i1 [[TMP7]], float 0x7FF8000000000000, float 0.000000e+00
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float [[TMP8]], float [[TMP6]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn oeq float [[TMP2]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP12:%.*]] = icmp ne i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP13:%.*]] = and i1 [[TMP11]], [[TMP12]]
+; CHECK-NEXT:    [[TMP14:%.*]] = select afn i1 [[TMP13]], float 0x7FF0000000000000, float [[TMP10]]
+; CHECK-NEXT:    [[TMP15:%.*]] = fcmp afn uno float [[TMP2]], 0.000000e+00
+; CHECK-NEXT:    [[TMP16:%.*]] = select afn i1 [[TMP15]], float 0x7FF8000000000000, float [[TMP14]]
+; CHECK-NEXT:    ret float [[TMP16]]
 ;
   %y.cast = uitofp i32 %y to float
   %powr = tail call afn float @_Z4powrff(float %x, float %y.cast)
@@ -1185,8 +1815,23 @@ define <2 x float> @test_powr_afn_v2f32_known_integral_uitofp(<2 x float> %x, <2
 ; CHECK-LABEL: define <2 x float> @test_powr_afn_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 afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
-; CHECK-NEXT:    ret <2 x float> [[POWR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = select afn <2 x i1> [[TMP1]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], [[Y_CAST]]
+; CHECK-NEXT:    [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]])
+; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq <2 x i32> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = select afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> zeroinitializer
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP10:%.*]] = select afn <2 x i1> [[TMP9]], <2 x float> [[TMP8]], <2 x float> [[TMP6]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn oeq <2 x float> [[TMP2]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP12:%.*]] = icmp ne <2 x i32> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP13:%.*]] = and <2 x i1> [[TMP11]], [[TMP12]]
+; CHECK-NEXT:    [[TMP14:%.*]] = select afn <2 x i1> [[TMP13]], <2 x float> splat (float 0x7FF0000000000000), <2 x float> [[TMP10]]
+; CHECK-NEXT:    [[TMP15:%.*]] = fcmp afn uno <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP16:%.*]] = select afn <2 x i1> [[TMP15]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP14]]
+; CHECK-NEXT:    ret <2 x float> [[TMP16]]
 ;
   %y.cast = uitofp <2 x i32> %y to <2 x float>
   %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y.cast)
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
index 89d039406f375..e3bcad94f1db7 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
@@ -903,7 +903,7 @@ define float @test_rootn_f32__y_neg2__noinline(float %x) {
 ; CHECK-LABEL: define float @test_rootn_f32__y_neg2__noinline(
 ; CHECK-SAME: float [[X:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[__ROOTN2RSQRT:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR3:[0-9]+]]
+; CHECK-NEXT:    [[__ROOTN2RSQRT:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR4:[0-9]+]]
 ; CHECK-NEXT:    ret float [[__ROOTN2RSQRT]]
 ;
 entry:
@@ -915,7 +915,7 @@ define float @test_rootn_f32__y_neg2__nobuiltin(float %x) {
 ; CHECK-LABEL: define float @test_rootn_f32__y_neg2__nobuiltin(
 ; CHECK-SAME: float [[X:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR4:[0-9]+]]
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR5:[0-9]+]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -985,7 +985,31 @@ define float @test_rootn_afn_f32(float %x, i32 %y) {
 ; CHECK-LABEL: define float @test_rootn_afn_f32(
 ; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call afn float @_Z5rootnfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[TMP0:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[TMP1:%.*]] = call afn float @llvm.amdgcn.rcp.f32(float [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.log2.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = fmul afn float [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn float @llvm.exp2.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = and i32 [[Y]], 1
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP6]], 0
+; CHECK-NEXT:    [[TMP7:%.*]] = select afn i1 [[DOTNOT]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn float @llvm.copysign.f32(float [[TMP5]], float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq float [[TMP9]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = or i1 [[TMP10]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP14:%.*]] = xor i1 [[TMP11]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn i1 [[TMP14]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP16:%.*]] = select afn i1 [[DOTNOT]], float 0.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn float @llvm.copysign.f32(float [[TMP15]], float [[TMP16]])
+; CHECK-NEXT:    [[TMP18:%.*]] = select afn i1 [[TMP12]], float [[TMP17]], float [[TMP8]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[DOTNOT]]
+; CHECK-NEXT:    [[TMP21:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP22:%.*]] = or i1 [[TMP20]], [[TMP21]]
+; CHECK-NEXT:    [[CALL:%.*]] = select afn i1 [[TMP22]], float 0x7FF8000000000000, float [[TMP18]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -997,7 +1021,31 @@ define <2 x float> @test_rootn_afn_v2f32(<2 x float> %x, <2 x i32> %y) {
 ; CHECK-LABEL: define <2 x float> @test_rootn_afn_v2f32(
 ; CHECK-SAME: <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    [[TMP0:%.*]] = sitofp <2 x i32> [[Y]] to <2 x float>
+; CHECK-NEXT:    [[TMP1:%.*]] = call afn <2 x float> @llvm.amdgcn.rcp.v2f32(<2 x float> [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = fmul afn <2 x float> [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = and <2 x i32> [[Y]], splat (i32 1)
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq <2 x i32> [[TMP6]], zeroinitializer
+; CHECK-NEXT:    [[TMP7:%.*]] = select afn <2 x i1> [[DOTNOT]], <2 x float> splat (float 1.000000e+00), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP5]], <2 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq <2 x float> [[TMP9]], splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP12:%.*]] = or <2 x i1> [[TMP10]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = icmp slt <2 x i32> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP14:%.*]] = xor <2 x i1> [[TMP11]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn <2 x i1> [[TMP14]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP16:%.*]] = select afn <2 x i1> [[DOTNOT]], <2 x float> zeroinitializer, <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP15]], <2 x float> [[TMP16]])
+; CHECK-NEXT:    [[TMP18:%.*]] = select afn <2 x i1> [[TMP12]], <2 x float> [[TMP17]], <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP19:%.*]] = fcmp afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP20:%.*]] = and <2 x i1> [[TMP19]], [[DOTNOT]]
+; CHECK-NEXT:    [[TMP21:%.*]] = icmp eq <2 x i32> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP22:%.*]] = or <2 x i1> [[TMP20]], [[TMP21]]
+; CHECK-NEXT:    [[CALL:%.*]] = select afn <2 x i1> [[TMP22]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP18]]
 ; CHECK-NEXT:    ret <2 x float> [[CALL]]
 ;
 entry:
@@ -1057,7 +1105,28 @@ define float @test_rootn_afn_nnan_ninf_f32(float %x, i32 %y) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32(
 ; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[TMP0:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.amdgcn.rcp.f32(float [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = fmul nnan ninf afn float [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = and i32 [[Y]], 1
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP6]], 0
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[DOTNOT]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP5]], float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp nnan ninf afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP10:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP11:%.*]] = xor i1 [[TMP9]], [[TMP10]]
+; CHECK-NEXT:    [[TMP12:%.*]] = select nnan ninf afn i1 [[TMP11]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP13:%.*]] = select nnan ninf afn i1 [[DOTNOT]], float 0.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP14:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP12]], float [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan ninf afn i1 [[TMP9]], float [[TMP14]], float [[TMP8]]
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp nnan ninf afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP17:%.*]] = and i1 [[TMP16]], [[DOTNOT]]
+; CHECK-NEXT:    [[TMP18:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP19:%.*]] = or i1 [[TMP17]], [[TMP18]]
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP19]], float 0x7FF8000000000000, float [[TMP15]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -1069,7 +1138,28 @@ define <2 x float> @test_rootn_afn_nnan_ninf_v2f32(<2 x float> %x, <2 x i32> %y)
 ; CHECK-LABEL: define <2 x float> @test_rootn_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> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    [[TMP0:%.*]] = sitofp <2 x i32> [[Y]] to <2 x float>
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn <2 x float> @llvm.amdgcn.rcp.v2f32(<2 x float> [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call nnan ninf afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = fmul nnan ninf afn <2 x float> [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = and <2 x i32> [[Y]], splat (i32 1)
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq <2 x i32> [[TMP6]], zeroinitializer
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn <2 x i1> [[DOTNOT]], <2 x float> splat (float 1.000000e+00), <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP5]], <2 x float> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP10:%.*]] = icmp slt <2 x i32> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = xor <2 x i1> [[TMP9]], [[TMP10]]
+; CHECK-NEXT:    [[TMP12:%.*]] = select nnan ninf afn <2 x i1> [[TMP11]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP13:%.*]] = select nnan ninf afn <2 x i1> [[DOTNOT]], <2 x float> zeroinitializer, <2 x float> [[X]]
+; CHECK-NEXT:    [[TMP14:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP12]], <2 x float> [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan ninf afn <2 x i1> [[TMP9]], <2 x float> [[TMP14]], <2 x float> [[TMP8]]
+; CHECK-NEXT:    [[TMP16:%.*]] = fcmp nnan ninf afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP17:%.*]] = and <2 x i1> [[TMP16]], [[DOTNOT]]
+; CHECK-NEXT:    [[TMP18:%.*]] = icmp eq <2 x i32> [[Y]], zeroinitializer
+; CHECK-NEXT:    [[TMP19:%.*]] = or <2 x i1> [[TMP17]], [[TMP18]]
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn <2 x i1> [[TMP19]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP15]]
 ; CHECK-NEXT:    ret <2 x float> [[CALL]]
 ;
 entry:
@@ -1129,7 +1219,7 @@ define float @test_rootn_fast_f32_nobuiltin(float %x, i32 %y) {
 ; CHECK-LABEL: define float @test_rootn_fast_f32_nobuiltin(
 ; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 [[Y]]) #[[ATTR4]]
+; CHECK-NEXT:    [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 [[Y]]) #[[ATTR5]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -1141,7 +1231,31 @@ define float @test_rootn_fast_f32_strictfp(float %x, i32 %y) #1 {
 ; CHECK-LABEL: define float @test_rootn_fast_f32_strictfp(
 ; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0]] {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 [[Y]]) #[[ATTR0]]
+; CHECK-NEXT:    [[TMP0:%.*]] = call fast float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP0]]) #[[ATTR0]]
+; CHECK-NEXT:    [[TMP2:%.*]] = call fast float @llvm.fabs.f32(float [[X]]) #[[ATTR0]]
+; CHECK-NEXT:    [[TMP3:%.*]] = call fast float @llvm.log2.f32(float [[TMP2]]) #[[ATTR0]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call fast float @llvm.experimental.constrained.fmul.f32(float [[TMP1]], float [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call fast float @llvm.exp2.f32(float [[TMP4]]) #[[ATTR0]]
+; CHECK-NEXT:    [[TMP6:%.*]] = and i32 [[Y]], 1
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP6]], 0
+; CHECK-NEXT:    [[TMP7:%.*]] = select fast i1 [[DOTNOT]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call fast float @llvm.copysign.f32(float [[TMP5]], float [[TMP7]]) #[[ATTR0]]
+; CHECK-NEXT:    [[TMP9:%.*]] = call fast float @llvm.fabs.f32(float [[X]]) #[[ATTR0]]
+; CHECK-NEXT:    [[TMP10:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP9]], float 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
+; CHECK-NEXT:    [[TMP11:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[X]], float 0.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
+; CHECK-NEXT:    [[TMP12:%.*]] = or i1 [[TMP10]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP14:%.*]] = xor i1 [[TMP11]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select fast i1 [[TMP14]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP16:%.*]] = select fast i1 [[DOTNOT]], float 0.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP17:%.*]] = call fast float @llvm.copysign.f32(float [[TMP15]], float [[TMP16]]) #[[ATTR0]]
+; CHECK-NEXT:    [[TMP18:%.*]] = select fast i1 [[TMP12]], float [[TMP17]], float [[TMP8]]
+; CHECK-NEXT:    [[TMP19:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[X]], float 0.000000e+00, metadata !"olt", metadata !"fpexcept.strict") #[[ATTR0]]
+; CHECK-NEXT:    [[TMP20:%.*]] = and i1 [[TMP19]], [[DOTNOT]]
+; CHECK-NEXT:    [[TMP21:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP22:%.*]] = or i1 [[TMP20]], [[TMP21]]
+; CHECK-NEXT:    [[CALL:%.*]] = select fast i1 [[TMP22]], float 0x7FF8000000000000, float [[TMP18]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -1152,8 +1266,7 @@ entry:
 define float @test_rootn_fast_f32__y_poison(float %x) {
 ; CHECK-LABEL: define float @test_rootn_fast_f32__y_poison(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 poison)
-; CHECK-NEXT:    ret float [[CALL]]
+; CHECK-NEXT:    ret float poison
 ;
   %call = tail call fast float @_Z5rootnfi(float %x, i32 poison)
   ret float %call
@@ -1172,7 +1285,15 @@ define float @test_rootn_afn_nnan_ninf_f32__y_3(float %x) {
 define float @test_rootn_afn_nnan_ninf_f32__y_neg3(float %x) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg3(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -3)
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 0xBFD5555560000000
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP4]], float [[X]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn une float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP7]], float [[X]])
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP6]], float [[TMP5]], float [[TMP8]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -3)
@@ -1182,7 +1303,14 @@ define float @test_rootn_afn_nnan_ninf_f32__y_neg3(float %x) {
 define float @test_rootn_afn_nnan_ninf_f32__y_4(float %x) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_4(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 4)
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 2.500000e-01
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp nnan ninf afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = select nnan ninf afn i1 [[TMP5]], float 0.000000e+00, float [[TMP4]]
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp nnan ninf afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP7]], float 0x7FF8000000000000, float [[TMP6]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 4)
@@ -1192,7 +1320,14 @@ define float @test_rootn_afn_nnan_ninf_f32__y_4(float %x) {
 define float @test_rootn_afn_nnan_ninf_f32__y_neg4(float %x) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg4(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -4)
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], -2.500000e-01
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp nnan ninf afn une float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = select nnan ninf afn i1 [[TMP5]], float [[TMP4]], float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp nnan ninf afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP7]], float 0x7FF8000000000000, float [[TMP6]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -4)
@@ -1202,7 +1337,15 @@ define float @test_rootn_afn_nnan_ninf_f32__y_neg4(float %x) {
 define float @test_rootn_afn_nnan_ninf_f32__y_5(float %x) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_5(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 5)
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 0x3FC99999A0000000
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP4]], float [[X]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP7]], float [[X]])
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP6]], float [[TMP8]], float [[TMP5]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 5)
@@ -1212,7 +1355,15 @@ define float @test_rootn_afn_nnan_ninf_f32__y_5(float %x) {
 define float @test_rootn_afn_nnan_ninf_f32__y_neg5(float %x) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg5(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -5)
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 0xBFC99999A0000000
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP4]], float [[X]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn une float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP7]], float [[X]])
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP6]], float [[TMP5]], float [[TMP8]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -5)
@@ -1222,7 +1373,15 @@ define float @test_rootn_afn_nnan_ninf_f32__y_neg5(float %x) {
 define float @test_rootn_afn_nnan_ninf_f32__y_7(float %x) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_7(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 7)
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 0x3FC24924A0000000
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP4]], float [[X]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP7]], float [[X]])
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP6]], float [[TMP8]], float [[TMP5]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 7)
@@ -1232,7 +1391,15 @@ define float @test_rootn_afn_nnan_ninf_f32__y_7(float %x) {
 define float @test_rootn_afn_nnan_ninf_f32__y_neg7(float %x) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg7(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -7)
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 0xBFC24924A0000000
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP4]], float [[X]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn une float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP7]], float [[X]])
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP6]], float [[TMP5]], float [[TMP8]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -7)
@@ -1242,7 +1409,14 @@ define float @test_rootn_afn_nnan_ninf_f32__y_neg7(float %x) {
 define float @test_rootn_afn_nnan_ninf_f32__y_8(float %x) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_8(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 8)
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 1.250000e-01
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp nnan ninf afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = select nnan ninf afn i1 [[TMP5]], float 0.000000e+00, float [[TMP4]]
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp nnan ninf afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP7]], float 0x7FF8000000000000, float [[TMP6]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 8)
@@ -1252,7 +1426,14 @@ define float @test_rootn_afn_nnan_ninf_f32__y_8(float %x) {
 define float @test_rootn_afn_nnan_ninf_f32__y_neg8(float %x) {
 ; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg8(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -8)
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], -1.250000e-01
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp nnan ninf afn une float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP6:%.*]] = select nnan ninf afn i1 [[TMP5]], float [[TMP4]], float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp nnan ninf afn olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP7]], float 0x7FF8000000000000, float [[TMP6]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -8)
@@ -1275,7 +1456,15 @@ define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_4(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_rootn_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> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> splat (i32 4))
+; CHECK-NEXT:    [[TMP0:%.*]] = call nnan ninf afn <2 x float> @llvm.amdgcn.rcp.v2f32(<2 x float> splat (float 4.000000e+00))
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn <2 x float> [[TMP0]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP6:%.*]] = select nnan ninf afn <2 x i1> [[TMP5]], <2 x float> zeroinitializer, <2 x float> [[TMP4]]
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp nnan ninf afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP6]]
 ; CHECK-NEXT:    ret <2 x float> [[CALL]]
 ;
 entry:
@@ -1287,7 +1476,16 @@ define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_neg3(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_rootn_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> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> splat (i32 -3))
+; CHECK-NEXT:    [[TMP0:%.*]] = call nnan ninf afn <2 x float> @llvm.amdgcn.rcp.v2f32(<2 x float> splat (float -3.000000e+00))
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn <2 x float> [[TMP0]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP4]], <2 x float> [[X]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn une <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP7]], <2 x float> [[X]])
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 x float> [[TMP5]], <2 x float> [[TMP8]]
 ; CHECK-NEXT:    ret <2 x float> [[CALL]]
 ;
 entry:
@@ -1299,7 +1497,15 @@ define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_neg4(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_rootn_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> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> splat (i32 -4))
+; CHECK-NEXT:    [[TMP0:%.*]] = call nnan ninf afn <2 x float> @llvm.amdgcn.rcp.v2f32(<2 x float> splat (float -4.000000e+00))
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn <2 x float> [[TMP0]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fcmp nnan ninf afn une <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP6:%.*]] = select nnan ninf afn <2 x i1> [[TMP5]], <2 x float> [[TMP4]], <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp nnan ninf afn olt <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn <2 x i1> [[TMP7]], <2 x float> splat (float 0x7FF8000000000000), <2 x float> [[TMP6]]
 ; CHECK-NEXT:    ret <2 x float> [[CALL]]
 ;
 entry:
@@ -1311,7 +1517,16 @@ define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_5(<2 x float> %x) {
 ; CHECK-LABEL: define <2 x float> @test_rootn_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> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> splat (i32 5))
+; CHECK-NEXT:    [[TMP0:%.*]] = call nnan ninf afn <2 x float> @llvm.amdgcn.rcp.v2f32(<2 x float> splat (float 5.000000e+00))
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn <2 x float> [[TMP0]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP4]], <2 x float> [[X]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], zeroinitializer
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 x float> zeroinitializer, <2 x float> splat (float 0x7FF0000000000000)
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP7]], <2 x float> [[X]])
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 x float> [[TMP8]], <2 x float> [[TMP5]]
 ; CHECK-NEXT:    ret <2 x float> [[CALL]]
 ;
 entry:
@@ -1335,7 +1550,28 @@ define float @test_rootn_afn_f32__x_known_positive(float nofpclass(ninf nsub nno
 ; CHECK-LABEL: define float @test_rootn_afn_f32__x_known_positive(
 ; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call afn float @_Z5rootnfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[TMP0:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[TMP1:%.*]] = call afn float @llvm.amdgcn.rcp.f32(float [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.log2.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = fmul afn float [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn float @llvm.exp2.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = and i32 [[Y]], 1
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP6]], 0
+; CHECK-NEXT:    [[TMP7:%.*]] = select afn i1 [[DOTNOT]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call afn float @llvm.copysign.f32(float [[TMP5]], float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fcmp afn oeq float [[TMP9]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = or i1 [[TMP10]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP14:%.*]] = xor i1 [[TMP11]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = select afn i1 [[TMP14]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP16:%.*]] = select afn i1 [[DOTNOT]], float 0.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP17:%.*]] = call afn float @llvm.copysign.f32(float [[TMP15]], float [[TMP16]])
+; CHECK-NEXT:    [[TMP18:%.*]] = select afn i1 [[TMP12]], float [[TMP17]], float [[TMP8]]
+; CHECK-NEXT:    [[TMP19:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = select afn i1 [[TMP19]], float 0x7FF8000000000000, float [[TMP18]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -1347,7 +1583,25 @@ define float @test_rootn_afn_ninf_nnan_f32__x_known_positive(float nofpclass(nin
 ; CHECK-LABEL: define float @test_rootn_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 @_Z5rootnfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[TMP0:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf afn float @llvm.amdgcn.rcp.f32(float [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = fmul nnan ninf afn float [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float @llvm.exp2.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = and i32 [[Y]], 1
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP6]], 0
+; CHECK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[DOTNOT]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP5]], float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = fcmp nnan ninf afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP10:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP11:%.*]] = xor i1 [[TMP9]], [[TMP10]]
+; CHECK-NEXT:    [[TMP12:%.*]] = select nnan ninf afn i1 [[TMP11]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP13:%.*]] = select nnan ninf afn i1 [[DOTNOT]], float 0.000000e+00, float [[X]]
+; CHECK-NEXT:    [[TMP14:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[TMP12]], float [[TMP13]])
+; CHECK-NEXT:    [[TMP15:%.*]] = select nnan ninf afn i1 [[TMP9]], float [[TMP14]], float [[TMP8]]
+; CHECK-NEXT:    [[TMP16:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = select nnan ninf afn i1 [[TMP16]], float 0x7FF8000000000000, float [[TMP15]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -1359,7 +1613,16 @@ define float @test_rootn_afn_f32__x_known_positive__y_4(float nofpclass(ninf nsu
 ; CHECK-LABEL: define float @test_rootn_afn_f32__x_known_positive__y_4(
 ; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = tail call afn float @_Z5rootnfi(float [[X]], i32 4)
+; CHECK-NEXT:    [[TMP0:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call afn float @llvm.log2.f32(float [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul afn float [[TMP1]], 2.500000e-01
+; CHECK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.exp2.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.fabs.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp afn oeq float [[TMP5]], 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP8:%.*]] = select i1 [[TMP6]], float 0x7FF0000000000000, float [[TMP4]]
+; CHECK-NEXT:    [[CALL:%.*]] = select i1 [[TMP7]], float 0.000000e+00, float [[TMP8]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -1398,7 +1661,21 @@ define float @test_fast_rootn_f32_y_known_even(float %x, i32 %y.arg) {
 ; CHECK-SAME: float [[X:%.*]], i32 [[Y_ARG:%.*]]) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[Y_ARG]], 1
-; CHECK-NEXT:    [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[TMP0:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[TMP1:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call fast float @llvm.log2.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = fmul fast float [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call fast float @llvm.exp2.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp fast oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = xor i1 [[TMP6]], [[TMP7]]
+; CHECK-NEXT:    [[TMP9:%.*]] = select fast i1 [[TMP8]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select fast i1 [[TMP6]], float [[TMP9]], float [[TMP5]]
+; CHECK-NEXT:    [[TMP11:%.*]] = fcmp fast olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP12:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP13:%.*]] = or i1 [[TMP11]], [[TMP12]]
+; CHECK-NEXT:    [[CALL:%.*]] = select fast i1 [[TMP13]], float 0x7FF8000000000000, float [[TMP10]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -1412,7 +1689,19 @@ define float @test_fast_rootn_f32_known_positive_y_known_even(float nofpclass(ni
 ; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y_ARG:%.*]]) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[Y_ARG]], 1
-; CHECK-NEXT:    [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[TMP0:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[TMP1:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP0]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call fast float @llvm.log2.f32(float [[TMP2]])
+; CHECK-NEXT:    [[TMP4:%.*]] = fmul fast float [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call fast float @llvm.exp2.f32(float [[TMP4]])
+; CHECK-NEXT:    [[TMP6:%.*]] = fcmp fast oeq float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT:    [[TMP8:%.*]] = xor i1 [[TMP6]], [[TMP7]]
+; CHECK-NEXT:    [[TMP9:%.*]] = select fast i1 [[TMP8]], float 0.000000e+00, float 0x7FF0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = select fast i1 [[TMP6]], float [[TMP9]], float [[TMP5]]
+; CHECK-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[Y]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = select fast i1 [[TMP11]], float 0x7FF8000000000000, float [[TMP10]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
 entry:
@@ -1424,7 +1713,7 @@ entry:
 define float @test_rootn_f32__y_0_nobuiltin(float %x) {
 ; CHECK-LABEL: define float @test_rootn_f32__y_0_nobuiltin(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 0) #[[ATTR4]]
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 0) #[[ATTR5]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call float @_Z5rootnfi(float %x, i32 0) #0
@@ -1434,7 +1723,7 @@ define float @test_rootn_f32__y_0_nobuiltin(float %x) {
 define float @test_rootn_f32__y_1_nobuiltin(float %x) {
 ; CHECK-LABEL: define float @test_rootn_f32__y_1_nobuiltin(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 1) #[[ATTR4]]
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 1) #[[ATTR5]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call float @_Z5rootnfi(float %x, i32 1) #0
@@ -1444,7 +1733,7 @@ define float @test_rootn_f32__y_1_nobuiltin(float %x) {
 define float @test_rootn_f32__y_2_nobuiltin(float %x) {
 ; CHECK-LABEL: define float @test_rootn_f32__y_2_nobuiltin(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 2) #[[ATTR4]]
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 2) #[[ATTR5]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call float @_Z5rootnfi(float %x, i32 2) #0
@@ -1454,7 +1743,7 @@ define float @test_rootn_f32__y_2_nobuiltin(float %x) {
 define float @test_rootn_f32__y_3_nobuiltin(float %x) {
 ; CHECK-LABEL: define float @test_rootn_f32__y_3_nobuiltin(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 3) #[[ATTR4]]
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 3) #[[ATTR5]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call float @_Z5rootnfi(float %x, i32 3) #0
@@ -1464,7 +1753,7 @@ define float @test_rootn_f32__y_3_nobuiltin(float %x) {
 define float @test_rootn_f32__y_neg1_nobuiltin(float %x) {
 ; CHECK-LABEL: define float @test_rootn_f32__y_neg1_nobuiltin(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -1) #[[ATTR4]]
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -1) #[[ATTR5]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call float @_Z5rootnfi(float %x, i32 -1) #0
@@ -1474,7 +1763,7 @@ define float @test_rootn_f32__y_neg1_nobuiltin(float %x) {
 define float @test_rootn_f32__y_neg2_nobuiltin(float %x) {
 ; CHECK-LABEL: define float @test_rootn_f32__y_neg2_nobuiltin(
 ; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR4]]
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR5]]
 ; CHECK-NEXT:    ret float [[CALL]]
 ;
   %call = tail call float @_Z5rootnfi(float %x, i32 -2) #0
@@ -1491,8 +1780,9 @@ attributes #2 = { noinline }
 ; CHECK: attributes #[[ATTR0]] = { strictfp }
 ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
 ; CHECK: attributes #[[ATTR2:[0-9]+]] = { nounwind memory(read) }
-; CHECK: attributes #[[ATTR3]] = { noinline }
-; CHECK: attributes #[[ATTR4]] = { nobuiltin }
+; CHECK: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) }
+; CHECK: attributes #[[ATTR4]] = { noinline }
+; CHECK: attributes #[[ATTR5]] = { nobuiltin }
 ;.
 ; CHECK: [[META0]] = !{float 2.000000e+00}
 ; CHECK: [[META1]] = !{float 3.000000e+00}
diff --git a/llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll b/llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll
index 36a7ee057d24b..2d07963d7f95d 100644
--- a/llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll
+++ b/llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll
@@ -277,7 +277,11 @@ entry:
 }
 
 ; GCN-LABEL: {{^}}define amdgpu_kernel void @test_pow_half
-; GCN-POSTLINK: call fast float @_Z3powff(float %tmp, float 5.000000e-01)
+; GCN-POSTLINK: call fast float @llvm.fabs.f32
+; GCN-POSTLINK: call fast float @llvm.log2.f32
+; GCN-POSTLINK: fmul fast float
+; GCN-POSTLINK: call fast float @llvm.exp2.f32
+
 ; GCN-PRELINK: %__pow2sqrt = tail call fast float @llvm.sqrt.f32(float %tmp)
 define amdgpu_kernel void @test_pow_half(ptr addrspace(1) nocapture %a) {
 entry:
@@ -289,7 +293,10 @@ entry:
 }
 
 ; GCN-LABEL: {{^}}define amdgpu_kernel void @test_pow_mhalf
-; GCN-POSTLINK: call fast float @_Z3powff(float %tmp, float -5.000000e-01)
+; GCN-POSTLINK: call fast float @llvm.fabs.f32
+; GCN-POSTLINK: call fast float @llvm.log2.f32
+; GCN-POSTLINK: fmul fast float
+; GCN-POSTLINK: call fast float @llvm.exp2.f32
 ; GCN-PRELINK: %__pow2rsqrt = tail call fast float @_Z5rsqrtf(float %tmp)
 define amdgpu_kernel void @test_pow_mhalf(ptr addrspace(1) nocapture %a) {
 entry:
@@ -473,7 +480,12 @@ entry:
 }
 
 ; GCN-LABEL: {{^}}define amdgpu_kernel void @test_rootn_3
-; GCN-POSTLINK: call fast float @_Z5rootnfi(float %tmp, i32 3)
+; GCN-POSTLINK: call fast float @llvm.log2.f32
+; GCN-POSTLINK: fmul
+; GCN-POSTLINK: call fast float @llvm.exp2.f32
+; GCN-POSTLINK: select fast i1
+; GCN-POSTLINK: call fast float @llvm.copysign.f32
+
 ; GCN-PRELINK: %__rootn2cbrt = tail call fast float @_Z4cbrtf(float %tmp)
 define amdgpu_kernel void @test_rootn_3(ptr addrspace(1) nocapture %a) {
 entry:



More information about the llvm-commits mailing list