[llvm] aa539b1 - AMDGPU: Add baseline tests for libcall recognition of pow/powr/pown

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 30 07:19:51 PDT 2023


Author: Matt Arsenault
Date: 2023-08-30T10:10:03-04:00
New Revision: aa539b128f02fdd3a0c1469da3ff943cc4a8c425

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

LOG: AMDGPU: Add baseline tests for libcall recognition of pow/powr/pown

Added: 
    llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow-codegen.ll
    llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
    llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
    llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow-codegen.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow-codegen.ll
new file mode 100644
index 00000000000000..b58161c9c3419e
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow-codegen.ll
@@ -0,0 +1,1223 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes=amdgpu-simplifylib,instcombine -amdgpu-prelink < %s | llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -amdgpu-prelink | FileCheck %s
+
+declare hidden float @_Z3powff(float, float)
+declare hidden double @_Z3powdd(double, double)
+declare hidden half @_Z3powDhDh(half, half)
+
+declare hidden float @_Z4powrff(float, float)
+declare hidden double @_Z4powrdd(double, double)
+declare hidden half @_Z4powrDhDh(half, half)
+
+declare hidden float @_Z4pownfi(float, i32)
+declare hidden double @_Z4powndi(double, i32)
+declare hidden half @_Z4pownDhi(half, i32)
+
+; --------------------------------------------------------------------
+; test pow
+; --------------------------------------------------------------------
+
+define half @test_pow_fast_f16(half %x, half %y) {
+; CHECK-LABEL: test_pow_fast_f16:
+; 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, _Z3powDhDh at rel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s17, s17, _Z3powDhDh at rel32@hi+12
+; CHECK-NEXT:    s_setpc_b64 s[16:17]
+  %pow = tail call fast half @_Z3powDhDh(half %x, half %y)
+  ret half %pow
+}
+
+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]
+  %pow = tail call fast float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define double @test_pow_fast_f64(double %x, double %y) {
+; CHECK-LABEL: test_pow_fast_f64:
+; 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, _Z3powdd at rel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s17, s17, _Z3powdd at rel32@hi+12
+; CHECK-NEXT:    s_setpc_b64 s[16:17]
+  %pow = tail call fast double @_Z3powdd(double %x, double %y)
+  ret double %pow
+}
+
+define half @test_pow_fast_f16__integral_y(half %x, i32 %y.i) {
+; CHECK-LABEL: test_pow_fast_f16__integral_y:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_cvt_f32_i32_e32 v1, v1
+; CHECK-NEXT:    s_getpc_b64 s[16:17]
+; CHECK-NEXT:    s_add_u32 s16, s16, _Z3powDhDh at rel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s17, s17, _Z3powDhDh at rel32@hi+12
+; CHECK-NEXT:    v_cvt_f16_f32_e32 v1, v1
+; CHECK-NEXT:    s_setpc_b64 s[16:17]
+  %y = sitofp i32 %y.i to half
+  %pow = tail call fast half @_Z3powDhDh(half %x, half %y)
+  ret half %pow
+}
+
+define float @test_pow_fast_f32__integral_y(float %x, i32 %y.i) {
+; CHECK-LABEL: test_pow_fast_f32__integral_y:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_cvt_f32_i32_e32 v1, v1
+; 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]
+  %y = sitofp i32 %y.i to float
+  %pow = tail call fast float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define double @test_pow_fast_f64__integral_y(double %x, i32 %y.i) {
+; CHECK-LABEL: test_pow_fast_f64__integral_y:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_cvt_f64_i32_e32 v[2:3], v2
+; CHECK-NEXT:    s_getpc_b64 s[16:17]
+; CHECK-NEXT:    s_add_u32 s16, s16, _Z3powdd at rel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s17, s17, _Z3powdd at rel32@hi+12
+; CHECK-NEXT:    s_setpc_b64 s[16:17]
+  %y = sitofp i32 %y.i to double
+  %pow = tail call fast double @_Z3powdd(double %x, double %y)
+  ret double %pow
+}
+
+; --------------------------------------------------------------------
+; test powr
+; --------------------------------------------------------------------
+
+define half @test_powr_fast_f16(half %x, half %y) {
+; CHECK-LABEL: test_powr_fast_f16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x400
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2Dh at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2Dh at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_mov_b32_e32 v42, v1
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2Dh at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2Dh at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_mul_f16_e32 v0, v0, v42
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xfc00
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %powr = tail call fast half @_Z4powrDhDh(half %x, half %y)
+  ret half %powr
+}
+
+define float @test_powr_fast_f32(float %x, float %y) {
+; CHECK-LABEL: test_powr_fast_f32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x400
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2f at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2f at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_mov_b32_e32 v42, v1
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2f at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2f at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_mul_f32_e32 v0, v0, v42
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xfc00
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %powr = tail call fast float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+define double @test_powr_fast_f64(double %x, double %y) {
+; CHECK-LABEL: test_powr_fast_f64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x800
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2d at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2d at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v43, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v43, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_mov_b32_e32 v42, v3
+; CHECK-NEXT:    v_mov_b32_e32 v41, v2
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_mul_f64 v[0:1], v[0:1], v[41:42]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2d at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2d at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v43
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    buffer_load_dword v43, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xf800
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %powr = tail call fast double @_Z4powrdd(double %x, double %y)
+  ret double %powr
+}
+
+; --------------------------------------------------------------------
+; test pown
+; --------------------------------------------------------------------
+
+define half @test_pown_fast_f16(half %x, i32 %y) {
+; CHECK-LABEL: test_pown_fast_f16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x800
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2Dh at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2Dh at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v43, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_mov_b32_e32 v43, v0
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    v_and_b32_e32 v0, 0x7fff, v43
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_mov_b32_e32 v42, v1
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_cvt_f32_i32_e32 v1, v42
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2Dh at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2Dh at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_cvt_f16_f32_e32 v1, v1
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    v_mul_f16_e32 v0, v0, v1
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_lshlrev_b16_e32 v1, 15, v42
+; CHECK-NEXT:    v_and_b32_e32 v1, v1, v43
+; CHECK-NEXT:    buffer_load_dword v43, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_or_b32_e32 v0, v1, v0
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xf800
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %call = tail call fast half @_Z4pownDhi(half %x, i32 %y)
+  ret half %call
+}
+
+define float @test_pown_fast_f32(float %x, i32 %y) {
+; CHECK-LABEL: test_pown_fast_f32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x800
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2f at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2f at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v43, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_mov_b32_e32 v43, v0
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    v_and_b32_e32 v0, 0x7fffffff, v43
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_mov_b32_e32 v42, v1
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2f at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2f at gotpcrel32@hi+12
+; CHECK-NEXT:    v_cvt_f32_i32_e32 v1, v42
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    v_mul_f32_e32 v0, v0, v1
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v1, 31, v42
+; CHECK-NEXT:    v_and_or_b32 v0, v1, v43, v0
+; CHECK-NEXT:    buffer_load_dword v43, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xf800
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %call = tail call fast float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define double @test_pown_fast_f64(double %x, i32 %y) {
+; CHECK-LABEL: test_pown_fast_f64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x800
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2d at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2d at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v43, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_mov_b32_e32 v43, v1
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    v_and_b32_e32 v1, 0x7fffffff, v43
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_mov_b32_e32 v42, v2
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_cvt_f64_i32_e32 v[2:3], v42
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2d at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2d at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_mul_f64 v[0:1], v[0:1], v[2:3]
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v2, 31, v42
+; CHECK-NEXT:    v_and_b32_e32 v2, v2, v43
+; CHECK-NEXT:    buffer_load_dword v43, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_or_b32_e32 v1, v2, v1
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xf800
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %call = tail call fast double @_Z4powndi(double %x, i32 %y)
+  ret double %call
+}
+
+define half @test_pown_fast_f16_known_even(half %x, i32 %y.arg) {
+; CHECK-LABEL: test_pown_fast_f16_known_even:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x400
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2Dh at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2Dh at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v42, 1, v1
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_cvt_f32_i32_e32 v1, v42
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2Dh at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2Dh at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_cvt_f16_f32_e32 v1, v1
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    v_mul_f16_e32 v0, v0, v1
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xfc00
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %y = shl i32 %y.arg, 1
+  %call = tail call fast half @_Z4pownDhi(half %x, i32 %y)
+  ret half %call
+}
+
+define float @test_pown_fast_f32_known_even(float %x, i32 %y.arg) {
+; CHECK-LABEL: test_pown_fast_f32_known_even:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x400
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2f at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2f at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    v_and_b32_e32 v0, 0x7fffffff, v0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v42, 1, v1
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2f at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2f at gotpcrel32@hi+12
+; CHECK-NEXT:    v_cvt_f32_i32_e32 v1, v42
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    v_mul_f32_e32 v0, v0, v1
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xfc00
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %y = shl i32 %y.arg, 1
+  %call = tail call fast float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define double @test_pown_fast_f64_known_even(double %x, i32 %y.arg) {
+; CHECK-LABEL: test_pown_fast_f64_known_even:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x400
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2d at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2d at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    v_and_b32_e32 v1, 0x7fffffff, v1
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v42, 1, v2
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_cvt_f64_i32_e32 v[2:3], v42
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2d at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2d at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_mul_f64 v[0:1], v[0:1], v[2:3]
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xfc00
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %y = shl i32 %y.arg, 1
+  %call = tail call fast double @_Z4powndi(double %x, i32 %y)
+  ret double %call
+}
+
+define half @test_pown_fast_f16_known_odd(half %x, i32 %y.arg) {
+; CHECK-LABEL: test_pown_fast_f16_known_odd:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x800
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2Dh at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2Dh at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v43, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_mov_b32_e32 v42, v0
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    v_and_b32_e32 v0, 0x7fff, v42
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v43, 1, v1
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_cvt_f32_i32_e32 v1, v43
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2Dh at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2Dh at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_cvt_f16_f32_e32 v1, v1
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    v_mul_f16_e32 v0, v0, v1
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_and_b32_e32 v1, 0xffff8000, v42
+; CHECK-NEXT:    buffer_load_dword v43, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_or_b32_e32 v0, v1, v0
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xf800
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %y = or i32 %y.arg, 1
+  %call = tail call fast half @_Z4pownDhi(half %x, i32 %y)
+  ret half %call
+}
+
+define float @test_pown_fast_f32_known_odd(float %x, i32 %y.arg) {
+; CHECK-LABEL: test_pown_fast_f32_known_odd:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x800
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2f at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2f at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v43, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_mov_b32_e32 v42, v0
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    v_and_b32_e32 v0, 0x7fffffff, v42
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v43, 1, v1
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2f at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2f at gotpcrel32@hi+12
+; CHECK-NEXT:    v_cvt_f32_i32_e32 v1, v43
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    v_mul_f32_e32 v0, v0, v1
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    s_brev_b32 s4, 1
+; CHECK-NEXT:    v_and_or_b32 v0, v42, s4, v0
+; CHECK-NEXT:    buffer_load_dword v43, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xf800
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %y = or i32 %y.arg, 1
+  %call = tail call fast float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define double @test_pown_fast_f64_known_odd(double %x, i32 %y.arg) {
+; CHECK-LABEL: test_pown_fast_f64_known_odd:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    s_mov_b32 s16, s33
+; CHECK-NEXT:    s_mov_b32 s33, s32
+; CHECK-NEXT:    s_or_saveexec_b64 s[18:19], -1
+; CHECK-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Spill
+; CHECK-NEXT:    s_mov_b64 exec, s[18:19]
+; CHECK-NEXT:    v_writelane_b32 v40, s16, 14
+; CHECK-NEXT:    v_writelane_b32 v40, s30, 0
+; CHECK-NEXT:    v_writelane_b32 v40, s31, 1
+; CHECK-NEXT:    v_writelane_b32 v40, s34, 2
+; CHECK-NEXT:    v_writelane_b32 v40, s35, 3
+; CHECK-NEXT:    v_writelane_b32 v40, s36, 4
+; CHECK-NEXT:    v_writelane_b32 v40, s37, 5
+; CHECK-NEXT:    v_writelane_b32 v40, s38, 6
+; CHECK-NEXT:    v_writelane_b32 v40, s39, 7
+; CHECK-NEXT:    s_addk_i32 s32, 0x800
+; CHECK-NEXT:    v_writelane_b32 v40, s40, 8
+; CHECK-NEXT:    v_writelane_b32 v40, s41, 9
+; CHECK-NEXT:    s_mov_b64 s[40:41], s[4:5]
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4log2d at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4log2d at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    v_writelane_b32 v40, s42, 10
+; CHECK-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; CHECK-NEXT:    buffer_store_dword v43, off, s[0:3], s33 ; 4-byte Folded Spill
+; CHECK-NEXT:    v_writelane_b32 v40, s43, 11
+; CHECK-NEXT:    v_mov_b32_e32 v42, v1
+; CHECK-NEXT:    v_writelane_b32 v40, s44, 12
+; CHECK-NEXT:    v_and_b32_e32 v1, 0x7fffffff, v42
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_writelane_b32 v40, s45, 13
+; CHECK-NEXT:    v_mov_b32_e32 v41, v31
+; CHECK-NEXT:    s_mov_b32 s42, s15
+; CHECK-NEXT:    s_mov_b32 s43, s14
+; CHECK-NEXT:    s_mov_b32 s44, s13
+; CHECK-NEXT:    s_mov_b32 s45, s12
+; CHECK-NEXT:    s_mov_b64 s[34:35], s[10:11]
+; CHECK-NEXT:    s_mov_b64 s[36:37], s[8:9]
+; CHECK-NEXT:    s_mov_b64 s[38:39], s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v43, 1, v2
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_cvt_f64_i32_e32 v[2:3], v43
+; CHECK-NEXT:    s_getpc_b64 s[4:5]
+; CHECK-NEXT:    s_add_u32 s4, s4, _Z4exp2d at gotpcrel32@lo+4
+; CHECK-NEXT:    s_addc_u32 s5, s5, _Z4exp2d at gotpcrel32@hi+12
+; CHECK-NEXT:    s_load_dwordx2 s[16:17], s[4:5], 0x0
+; CHECK-NEXT:    s_mov_b64 s[4:5], s[40:41]
+; CHECK-NEXT:    v_mul_f64 v[0:1], v[0:1], v[2:3]
+; CHECK-NEXT:    s_mov_b64 s[6:7], s[38:39]
+; CHECK-NEXT:    s_mov_b64 s[8:9], s[36:37]
+; CHECK-NEXT:    s_mov_b64 s[10:11], s[34:35]
+; CHECK-NEXT:    s_mov_b32 s12, s45
+; CHECK-NEXT:    s_mov_b32 s13, s44
+; CHECK-NEXT:    s_mov_b32 s14, s43
+; CHECK-NEXT:    s_mov_b32 s15, s42
+; CHECK-NEXT:    v_mov_b32_e32 v31, v41
+; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
+; CHECK-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; CHECK-NEXT:    v_and_b32_e32 v2, 0x80000000, v42
+; CHECK-NEXT:    buffer_load_dword v43, off, s[0:3], s33 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v42, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; CHECK-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; CHECK-NEXT:    v_or_b32_e32 v1, v2, v1
+; CHECK-NEXT:    v_readlane_b32 s45, v40, 13
+; CHECK-NEXT:    v_readlane_b32 s44, v40, 12
+; CHECK-NEXT:    v_readlane_b32 s43, v40, 11
+; CHECK-NEXT:    v_readlane_b32 s42, v40, 10
+; CHECK-NEXT:    v_readlane_b32 s41, v40, 9
+; CHECK-NEXT:    v_readlane_b32 s40, v40, 8
+; CHECK-NEXT:    v_readlane_b32 s39, v40, 7
+; CHECK-NEXT:    v_readlane_b32 s38, v40, 6
+; CHECK-NEXT:    v_readlane_b32 s37, v40, 5
+; CHECK-NEXT:    v_readlane_b32 s36, v40, 4
+; CHECK-NEXT:    v_readlane_b32 s35, v40, 3
+; CHECK-NEXT:    v_readlane_b32 s34, v40, 2
+; CHECK-NEXT:    v_readlane_b32 s31, v40, 1
+; CHECK-NEXT:    v_readlane_b32 s30, v40, 0
+; CHECK-NEXT:    v_readlane_b32 s4, v40, 14
+; CHECK-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; CHECK-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:12 ; 4-byte Folded Reload
+; CHECK-NEXT:    s_mov_b64 exec, s[6:7]
+; CHECK-NEXT:    s_addk_i32 s32, 0xf800
+; CHECK-NEXT:    s_mov_b32 s33, s4
+; CHECK-NEXT:    s_waitcnt vmcnt(0)
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %y = or i32 %y.arg, 1
+  %call = tail call fast double @_Z4powndi(double %x, i32 %y)
+  ret double %call
+}

diff  --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
new file mode 100644
index 00000000000000..5eb990d35f07c3
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
@@ -0,0 +1,2530 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=amdgpu-simplifylib,instcombine -amdgpu-prelink %s | FileCheck %s
+
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8"
+
+declare float @_Z3powff(float, float)
+declare <2 x float> @_Z3powDv2_fS_(<2 x float>, <2 x float>)
+declare <3 x float> @_Z3powDv3_fS_(<3 x float>, <3 x float>)
+declare <4 x float> @_Z3powDv4_fS_(<4 x float>, <4 x float>)
+declare <8 x float> @_Z3powDv8_fS_(<8 x float>, <8 x float>)
+declare <16 x float> @_Z3powDv16_fS_(<16 x float>, <16 x float>)
+declare double @_Z3powdd(double, double)
+declare <2 x double> @_Z3powDv2_dS_(<2 x double>, <2 x double>)
+declare <3 x double> @_Z3powDv3_dS_(<3 x double>, <3 x double>)
+declare <4 x double> @_Z3powDv4_dS_(<4 x double>, <4 x double>)
+declare <8 x double> @_Z3powDv8_dS_(<8 x double>, <8 x double>)
+declare <16 x double> @_Z3powDv16_dS_(<16 x double>, <16 x double>)
+declare half @_Z3powDhDh(half, half)
+declare <2 x half> @_Z3powDv2_DhS_(<2 x half>, <2 x half>)
+declare <3 x half> @_Z3powDv3_DhS_(<3 x half>, <3 x half>)
+declare <4 x half> @_Z3powDv4_DhS_(<4 x half>, <4 x half>)
+declare <8 x half> @_Z3powDv8_DhS_(<8 x half>, <8 x half>)
+declare <16 x half> @_Z3powDv16_DhS_(<16 x half>, <16 x half>)
+declare void @llvm.assume(i1 noundef)
+declare float @llvm.floor.f32(float)
+declare float @llvm.ceil.f32(float)
+declare float @llvm.trunc.f32(float)
+declare float @llvm.rint.f32(float)
+declare float @llvm.nearbyint.f32(float)
+declare float @llvm.round.f32(float)
+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]]
+;
+  %pow = tail call fast float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call fast <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %pow
+}
+
+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]]
+;
+  %pow = tail call afn nnan float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call afn nnan <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %pow
+}
+
+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]]
+;
+  %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %pow
+}
+
+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]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %pow
+}
+
+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]]
+;
+  %pow = tail call afn <3 x float> @_Z3powDv3_fS_(<3 x float> %x, <3 x float> %y)
+  ret <3 x float> %pow
+}
+
+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]]
+;
+  %pow = tail call afn <4 x float> @_Z3powDv4_fS_(<4 x float> %x, <4 x float> %y)
+  ret <4 x float> %pow
+}
+
+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]]
+;
+  %pow = tail call afn <8 x float> @_Z3powDv8_fS_(<8 x float> %x, <8 x float> %y)
+  ret <8 x float> %pow
+}
+
+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]]
+;
+  %pow = tail call afn <16 x float> @_Z3powDv16_fS_(<16 x float> %x, <16 x float> %y)
+  ret <16 x float> %pow
+}
+
+define double @test_pow_afn_f64(double %x, double %y) {
+; CHECK-LABEL: define double @test_pow_afn_f64
+; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn double @_Z3powdd(double [[X]], double [[Y]])
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn double @_Z3powdd(double %x, double %y)
+  ret double %pow
+}
+
+define <2 x double> @test_pow_afn_v2f64(<2 x double> %x, <2 x double> %y) {
+; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]], <2 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call afn <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> %y)
+  ret <2 x double> %pow
+}
+
+define <3 x double> @test_pow_afn_v3f64(<3 x double> %x, <3 x double> %y) {
+; CHECK-LABEL: define <3 x double> @test_pow_afn_v3f64
+; CHECK-SAME: (<3 x double> [[X:%.*]], <3 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <3 x double> @_Z3powDv3_dS_(<3 x double> [[X]], <3 x double> [[Y]])
+; CHECK-NEXT:    ret <3 x double> [[POW]]
+;
+  %pow = tail call afn <3 x double> @_Z3powDv3_dS_(<3 x double> %x, <3 x double> %y)
+  ret <3 x double> %pow
+}
+
+define <4 x double> @test_pow_afn_v4f64(<4 x double> %x, <4 x double> %y) {
+; CHECK-LABEL: define <4 x double> @test_pow_afn_v4f64
+; CHECK-SAME: (<4 x double> [[X:%.*]], <4 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <4 x double> @_Z3powDv4_dS_(<4 x double> [[X]], <4 x double> [[Y]])
+; CHECK-NEXT:    ret <4 x double> [[POW]]
+;
+  %pow = tail call afn <4 x double> @_Z3powDv4_dS_(<4 x double> %x, <4 x double> %y)
+  ret <4 x double> %pow
+}
+
+define <8 x double> @test_pow_afn_v8f64(<8 x double> %x, <8 x double> %y) {
+; CHECK-LABEL: define <8 x double> @test_pow_afn_v8f64
+; CHECK-SAME: (<8 x double> [[X:%.*]], <8 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <8 x double> @_Z3powDv8_dS_(<8 x double> [[X]], <8 x double> [[Y]])
+; CHECK-NEXT:    ret <8 x double> [[POW]]
+;
+  %pow = tail call afn <8 x double> @_Z3powDv8_dS_(<8 x double> %x, <8 x double> %y)
+  ret <8 x double> %pow
+}
+
+define <16 x double> @test_pow_afn_v16f64(<16 x double> %x, <16 x double> %y) {
+; CHECK-LABEL: define <16 x double> @test_pow_afn_v16f64
+; CHECK-SAME: (<16 x double> [[X:%.*]], <16 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <16 x double> @_Z3powDv16_dS_(<16 x double> [[X]], <16 x double> [[Y]])
+; CHECK-NEXT:    ret <16 x double> [[POW]]
+;
+  %pow = tail call afn <16 x double> @_Z3powDv16_dS_(<16 x double> %x, <16 x double> %y)
+  ret <16 x double> %pow
+}
+
+define half @test_pow_afn_f16(half %x, half %y) {
+; CHECK-LABEL: define half @test_pow_afn_f16
+; CHECK-SAME: (half [[X:%.*]], half [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn half @_Z3powDhDh(half [[X]], half [[Y]])
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn half @_Z3powDhDh(half %x, half %y)
+  ret half %pow
+}
+
+define <2 x half> @test_pow_afn_v2f16(<2 x half> %x, <2 x half> %y) {
+; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]], <2 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call afn <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> %y)
+  ret <2 x half> %pow
+}
+
+define <3 x half> @test_pow_afn_v3f16(<3 x half> %x, <3 x half> %y) {
+; CHECK-LABEL: define <3 x half> @test_pow_afn_v3f16
+; CHECK-SAME: (<3 x half> [[X:%.*]], <3 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <3 x half> @_Z3powDv3_DhS_(<3 x half> [[X]], <3 x half> [[Y]])
+; CHECK-NEXT:    ret <3 x half> [[POW]]
+;
+  %pow = tail call afn <3 x half> @_Z3powDv3_DhS_(<3 x half> %x, <3 x half> %y)
+  ret <3 x half> %pow
+}
+
+define <4 x half> @test_pow_afn_v4f16(<4 x half> %x, <4 x half> %y) {
+; CHECK-LABEL: define <4 x half> @test_pow_afn_v4f16
+; CHECK-SAME: (<4 x half> [[X:%.*]], <4 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <4 x half> @_Z3powDv4_DhS_(<4 x half> [[X]], <4 x half> [[Y]])
+; CHECK-NEXT:    ret <4 x half> [[POW]]
+;
+  %pow = tail call afn <4 x half> @_Z3powDv4_DhS_(<4 x half> %x, <4 x half> %y)
+  ret <4 x half> %pow
+}
+
+define <8 x half> @test_pow_afn_v8f16(<8 x half> %x, <8 x half> %y) {
+; CHECK-LABEL: define <8 x half> @test_pow_afn_v8f16
+; CHECK-SAME: (<8 x half> [[X:%.*]], <8 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <8 x half> @_Z3powDv8_DhS_(<8 x half> [[X]], <8 x half> [[Y]])
+; CHECK-NEXT:    ret <8 x half> [[POW]]
+;
+  %pow = tail call afn <8 x half> @_Z3powDv8_DhS_(<8 x half> %x, <8 x half> %y)
+  ret <8 x half> %pow
+}
+
+define <16 x half> @test_pow_afn_v16f16(<16 x half> %x, <16 x half> %y) {
+; CHECK-LABEL: define <16 x half> @test_pow_afn_v16f16
+; CHECK-SAME: (<16 x half> [[X:%.*]], <16 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <16 x half> @_Z3powDv16_DhS_(<16 x half> [[X]], <16 x half> [[Y]])
+; CHECK-NEXT:    ret <16 x half> [[POW]]
+;
+  %pow = tail call afn <16 x half> @_Z3powDv16_DhS_(<16 x half> %x, <16 x half> %y)
+  ret <16 x half> %pow
+}
+
+define float @test_pow_f32(float %x, float %y) {
+; CHECK-LABEL: define float @test_pow_f32
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32_nnan(float %x, float %y) {
+; CHECK-LABEL: define float @test_pow_f32_nnan
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call nnan float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_v2f32(<2 x float> %x, <2 x float> %y) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32
+; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %pow
+}
+
+define <3 x float> @test_pow_v3f32(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_pow_v3f32
+; CHECK-SAME: (<3 x float> [[X:%.*]], <3 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <3 x float> @_Z3powDv3_fS_(<3 x float> [[X]], <3 x float> [[Y]])
+; CHECK-NEXT:    ret <3 x float> [[POW]]
+;
+  %pow = tail call <3 x float> @_Z3powDv3_fS_(<3 x float> %x, <3 x float> %y)
+  ret <3 x float> %pow
+}
+
+define <4 x float> @test_pow_v4f32(<4 x float> %x, <4 x float> %y) {
+; CHECK-LABEL: define <4 x float> @test_pow_v4f32
+; CHECK-SAME: (<4 x float> [[X:%.*]], <4 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <4 x float> @_Z3powDv4_fS_(<4 x float> [[X]], <4 x float> [[Y]])
+; CHECK-NEXT:    ret <4 x float> [[POW]]
+;
+  %pow = tail call <4 x float> @_Z3powDv4_fS_(<4 x float> %x, <4 x float> %y)
+  ret <4 x float> %pow
+}
+
+define <8 x float> @test_pow_v8f32(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: define <8 x float> @test_pow_v8f32
+; CHECK-SAME: (<8 x float> [[X:%.*]], <8 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <8 x float> @_Z3powDv8_fS_(<8 x float> [[X]], <8 x float> [[Y]])
+; CHECK-NEXT:    ret <8 x float> [[POW]]
+;
+  %pow = tail call <8 x float> @_Z3powDv8_fS_(<8 x float> %x, <8 x float> %y)
+  ret <8 x float> %pow
+}
+
+define <16 x float> @test_pow_v16f32(<16 x float> %x, <16 x float> %y) {
+; CHECK-LABEL: define <16 x float> @test_pow_v16f32
+; CHECK-SAME: (<16 x float> [[X:%.*]], <16 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <16 x float> @_Z3powDv16_fS_(<16 x float> [[X]], <16 x float> [[Y]])
+; CHECK-NEXT:    ret <16 x float> [[POW]]
+;
+  %pow = tail call <16 x float> @_Z3powDv16_fS_(<16 x float> %x, <16 x float> %y)
+  ret <16 x float> %pow
+}
+
+define double @test_pow_f64(double %x, double %y) {
+; CHECK-LABEL: define double @test_pow_f64
+; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call double @_Z3powdd(double [[X]], double [[Y]])
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call double @_Z3powdd(double %x, double %y)
+  ret double %pow
+}
+
+define <2 x double> @test_pow_v2f64(<2 x double> %x, <2 x double> %y) {
+; CHECK-LABEL: define <2 x double> @test_pow_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]], <2 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> %y)
+  ret <2 x double> %pow
+}
+
+define <3 x double> @test_pow_v3f64(<3 x double> %x, <3 x double> %y) {
+; CHECK-LABEL: define <3 x double> @test_pow_v3f64
+; CHECK-SAME: (<3 x double> [[X:%.*]], <3 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <3 x double> @_Z3powDv3_dS_(<3 x double> [[X]], <3 x double> [[Y]])
+; CHECK-NEXT:    ret <3 x double> [[POW]]
+;
+  %pow = tail call <3 x double> @_Z3powDv3_dS_(<3 x double> %x, <3 x double> %y)
+  ret <3 x double> %pow
+}
+
+define <4 x double> @test_pow_v4f64(<4 x double> %x, <4 x double> %y) {
+; CHECK-LABEL: define <4 x double> @test_pow_v4f64
+; CHECK-SAME: (<4 x double> [[X:%.*]], <4 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <4 x double> @_Z3powDv4_dS_(<4 x double> [[X]], <4 x double> [[Y]])
+; CHECK-NEXT:    ret <4 x double> [[POW]]
+;
+  %pow = tail call <4 x double> @_Z3powDv4_dS_(<4 x double> %x, <4 x double> %y)
+  ret <4 x double> %pow
+}
+
+define <8 x double> @test_pow_v8f64(<8 x double> %x, <8 x double> %y) {
+; CHECK-LABEL: define <8 x double> @test_pow_v8f64
+; CHECK-SAME: (<8 x double> [[X:%.*]], <8 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <8 x double> @_Z3powDv8_dS_(<8 x double> [[X]], <8 x double> [[Y]])
+; CHECK-NEXT:    ret <8 x double> [[POW]]
+;
+  %pow = tail call <8 x double> @_Z3powDv8_dS_(<8 x double> %x, <8 x double> %y)
+  ret <8 x double> %pow
+}
+
+define <16 x double> @test_pow_v16f64(<16 x double> %x, <16 x double> %y) {
+; CHECK-LABEL: define <16 x double> @test_pow_v16f64
+; CHECK-SAME: (<16 x double> [[X:%.*]], <16 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <16 x double> @_Z3powDv16_dS_(<16 x double> [[X]], <16 x double> [[Y]])
+; CHECK-NEXT:    ret <16 x double> [[POW]]
+;
+  %pow = tail call <16 x double> @_Z3powDv16_dS_(<16 x double> %x, <16 x double> %y)
+  ret <16 x double> %pow
+}
+
+define half @test_pow_f16(half %x, half %y) {
+; CHECK-LABEL: define half @test_pow_f16
+; CHECK-SAME: (half [[X:%.*]], half [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call half @_Z3powDhDh(half [[X]], half [[Y]])
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call half @_Z3powDhDh(half %x, half %y)
+  ret half %pow
+}
+
+define <2 x half> @test_pow_v2f16(<2 x half> %x, <2 x half> %y) {
+; CHECK-LABEL: define <2 x half> @test_pow_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]], <2 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> %y)
+  ret <2 x half> %pow
+}
+
+define <3 x half> @test_pow_v3f16(<3 x half> %x, <3 x half> %y) {
+; CHECK-LABEL: define <3 x half> @test_pow_v3f16
+; CHECK-SAME: (<3 x half> [[X:%.*]], <3 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <3 x half> @_Z3powDv3_DhS_(<3 x half> [[X]], <3 x half> [[Y]])
+; CHECK-NEXT:    ret <3 x half> [[POW]]
+;
+  %pow = tail call <3 x half> @_Z3powDv3_DhS_(<3 x half> %x, <3 x half> %y)
+  ret <3 x half> %pow
+}
+
+define <4 x half> @test_pow_v4f16(<4 x half> %x, <4 x half> %y) {
+; CHECK-LABEL: define <4 x half> @test_pow_v4f16
+; CHECK-SAME: (<4 x half> [[X:%.*]], <4 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <4 x half> @_Z3powDv4_DhS_(<4 x half> [[X]], <4 x half> [[Y]])
+; CHECK-NEXT:    ret <4 x half> [[POW]]
+;
+  %pow = tail call <4 x half> @_Z3powDv4_DhS_(<4 x half> %x, <4 x half> %y)
+  ret <4 x half> %pow
+}
+
+define <8 x half> @test_pow_v8f16(<8 x half> %x, <8 x half> %y) {
+; CHECK-LABEL: define <8 x half> @test_pow_v8f16
+; CHECK-SAME: (<8 x half> [[X:%.*]], <8 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <8 x half> @_Z3powDv8_DhS_(<8 x half> [[X]], <8 x half> [[Y]])
+; CHECK-NEXT:    ret <8 x half> [[POW]]
+;
+  %pow = tail call <8 x half> @_Z3powDv8_DhS_(<8 x half> %x, <8 x half> %y)
+  ret <8 x half> %pow
+}
+
+define <16 x half> @test_pow_v16f16(<16 x half> %x, <16 x half> %y) {
+; CHECK-LABEL: define <16 x half> @test_pow_v16f16
+; CHECK-SAME: (<16 x half> [[X:%.*]], <16 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <16 x half> @_Z3powDv16_DhS_(<16 x half> [[X]], <16 x half> [[Y]])
+; CHECK-NEXT:    ret <16 x half> [[POW]]
+;
+  %pow = tail call <16 x half> @_Z3powDv16_DhS_(<16 x half> %x, <16 x half> %y)
+  ret <16 x half> %pow
+}
+
+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]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call afn nnan float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float %y) #1
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call afn nnan float @_Z3powff(float %x, float %y) #1
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call afn nsz nnan float @_Z3powff(float %x, float %y) #2
+  ret float %pow
+}
+
+define float @test_pow_fast_f32_nobuiltin(float %x, float %y) {
+; CHECK-LABEL: define float @test_pow_fast_f32_nobuiltin
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call fast float @_Z3powff(float [[X]], float [[Y]]) #[[ATTR6:[0-9]+]]
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call fast float @_Z3powff(float %x, float %y) #3
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_0.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_0.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 0.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_neg0.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_neg0.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+  %pow = tail call afn float @_Z3powff(float %x, float -0.0)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_0.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_0.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 0.0, float 0.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_neg0.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_neg0.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -0.0, float -0.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_plus_minus_0.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_0.0
+; 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 0.000000e+00, float -0.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 0.0, float -0.0>)
+  ret <2 x float> %pow
+}
+
+define <3 x float> @test_pow_afn_v3f32_0.0_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_pow_afn_v3f32_0.0_splat_undef
+; 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> <float 0.000000e+00, float poison, float 0.000000e+00>)
+; CHECK-NEXT:    ret <3 x float> [[POW]]
+;
+  %pow = tail call afn <3 x float> @_Z3powDv3_fS_(<3 x float> %x, <3 x float> <float 0.0, float poison, float 0.0>)
+  ret <3 x float> %pow
+}
+
+define <3 x float> @test_pow_afn_v3f32_neg0.0_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_pow_afn_v3f32_neg0.0_splat_undef
+; 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> <float -0.000000e+00, float poison, float -0.000000e+00>)
+; CHECK-NEXT:    ret <3 x float> [[POW]]
+;
+  %pow = tail call afn <3 x float> @_Z3powDv3_fS_(<3 x float> %x, <3 x float> <float -0.0, float poison, float -0.0>)
+  ret <3 x float> %pow
+}
+
+define float @test_pow_afn_f32_0.5(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_0.5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2SQRT:%.*]] = call afn float @_Z4sqrtf(float [[X]])
+; CHECK-NEXT:    ret float [[__POW2SQRT]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 0.5)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_neg0.5(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_neg0.5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2RSQRT:%.*]] = call afn float @_Z5rsqrtf(float [[X]])
+; CHECK-NEXT:    ret float [[__POW2RSQRT]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float -0.5)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_0.5(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_0.5
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2SQRT:%.*]] = call afn <2 x float> @_Z4sqrtDv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    ret <2 x float> [[__POW2SQRT]]
+;
+  %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
+}
+
+define <2 x float> @test_pow_afn_v2f32_neg0.5(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_neg0.5
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2RSQRT:%.*]] = call afn <2 x float> @_Z5rsqrtDv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    ret <2 x float> [[__POW2RSQRT]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+define <3 x float> @test_pow_afn_v3f32_0.5_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_pow_afn_v3f32_0.5_splat_undef
+; 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> <float 5.000000e-01, float poison, float 5.000000e-01>)
+; CHECK-NEXT:    ret <3 x float> [[POW]]
+;
+  %pow = tail call afn <3 x float> @_Z3powDv3_fS_(<3 x float> %x, <3 x float> <float 0.5, float poison, float 0.5>)
+  ret <3 x float> %pow
+}
+
+define <3 x float> @test_pow_afn_v3f32_neg0.5_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_pow_afn_v3f32_neg0.5_splat_undef
+; 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> <float -5.000000e-01, float poison, float -5.000000e-01>)
+; CHECK-NEXT:    ret <3 x float> [[POW]]
+;
+  %pow = tail call afn <3 x float> @_Z3powDv3_fS_(<3 x float> %x, <3 x float> <float -0.5, float poison, float -0.5>)
+  ret <3 x float> %pow
+}
+
+define float @test_pow_afn_f32_1.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_1.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    ret float [[X]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 1.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_neg1.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_neg1.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv afn float 1.000000e+00, [[X]]
+; CHECK-NEXT:    ret float [[__POWRECIP]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float -1.0)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_1.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_1.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    ret <2 x float> [[X]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 1.0, float 1.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_neg1.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_neg1.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv afn <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POWRECIP]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -1.0, float -1.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_plus_minus_1.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_1.0
+; 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 1.000000e+00, float -1.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 1.0, float -1.0>)
+  ret <2 x float> %pow
+}
+
+define <3 x float> @test_pow_afn_v3f32_1.0_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_pow_afn_v3f32_1.0_splat_undef
+; 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> <float 1.000000e+00, float poison, float 1.000000e+00>)
+; CHECK-NEXT:    ret <3 x float> [[POW]]
+;
+  %pow = tail call afn <3 x float> @_Z3powDv3_fS_(<3 x float> %x, <3 x float> <float 1.0, float poison, float 1.0>)
+  ret <3 x float> %pow
+}
+
+define <3 x float> @test_pow_afn_v3f32_neg1.0_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_pow_afn_v3f32_neg1.0_splat_undef
+; 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> <float -1.000000e+00, float poison, float -1.000000e+00>)
+; CHECK-NEXT:    ret <3 x float> [[POW]]
+;
+  %pow = tail call afn <3 x float> @_Z3powDv3_fS_(<3 x float> %x, <3 x float> <float -1.0, float poison, float -1.0>)
+  ret <3 x float> %pow
+}
+
+define float @test_pow_afn_f32_2.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_2.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul afn float [[X]], [[X]]
+; CHECK-NEXT:    ret float [[__POW2]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 2.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_neg2.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_neg2.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float -2.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float -2.0)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_2.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_2.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POW2]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 2.0, float 2.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_neg2.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_neg2.0
+; 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 -2.000000e+00, float -2.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -2.0, float -2.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_plus_minus_2.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_2.0
+; 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 2.000000e+00, float -2.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 2.0, float -2.0>)
+  ret <2 x float> %pow
+}
+
+define float @test_pow_afn_f32_3.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_3.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float 3.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 3.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_neg3.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_neg3.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float -3.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float -3.0)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_3.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_3.0
+; 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 3.000000e+00, float 3.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 3.0, float 3.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_neg3.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_neg3.0
+; 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 -3.000000e+00, float -3.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -3.0, float -3.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_plus_minus_3.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_3.0
+; 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 3.000000e+00, float -3.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 3.0, float -3.0>)
+  ret <2 x float> %pow
+}
+
+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]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 0x400FEB8520000000)
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 0xC00FEB8520000000)
+  ret float %pow
+}
+
+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> <float 0x400FEB8520000000, float 0x400FEB8520000000>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %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
+}
+
+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> <float 0xC00FEB8520000000, float 0xC00FEB8520000000>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+define float @test_pow_afn_f32_8.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_8.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float 8.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 8.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_neg8.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_neg8.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float -8.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float -8.0)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_8.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_8.0
+; 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 8.000000e+00, float 8.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 8.0, float 8.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_neg8.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_neg8.0
+; 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 -8.000000e+00, float -8.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -8.0, float -8.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_plus_minus_8.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_8.0
+; 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 8.000000e+00, float -8.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 8.0, float -8.0>)
+  ret <2 x float> %pow
+}
+
+define float @test_pow_afn_f32_12.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_12.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float 1.200000e+01)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 12.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_neg12.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_neg12.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float -1.200000e+01)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float -12.0)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_12.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_12.0
+; 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 1.200000e+01, float 1.200000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 12.0, float 12.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_neg12.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_neg12.0
+; 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 -1.200000e+01, float -1.200000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -12.0, float -12.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_plus_minus_12.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_12.0
+; 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 1.200000e+01, float -1.200000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 12.0, float -12.0>)
+  ret <2 x float> %pow
+}
+
+define float @test_pow_afn_f32_13.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_13.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float 1.300000e+01)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 13.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_neg13.0(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_neg13.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float -1.300000e+01)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float -13.0)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_13.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_13.0
+; 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 1.300000e+01, float 1.300000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 13.0, float 13.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_neg13.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_neg13.0
+; 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 -1.300000e+01, float -1.300000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -13.0, float -13.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_13.0_15.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_13.0_15.0
+; 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 1.300000e+01, float 1.500000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 13.0, float 15.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_13.0_14.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_13.0_14.0
+; 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 1.300000e+01, float 1.400000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 13.0, float 14.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_14.0_16.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_14.0_16.0
+; 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 1.400000e+01, float 1.600000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 14.0, float 16.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_plus_minus_13.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_13.0
+; 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 1.300000e+01, float -1.300000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 13.0, float -13.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_plus_minus_13.0_minus_14.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_plus_minus_13.0_minus_14.0
+; 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 -1.300000e+01, float -1.400000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -13.0, float -14.0>)
+  ret <2 x float> %pow
+}
+
+define float @test_pow_afn_f32_nnan_x_known_positive(float nofpclass(ninf nnorm nsub) %x, float %y) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_x_known_positive
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn nnan float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_nnan_ninf_x_known_positive(float nofpclass(ninf nnorm nsub) %x, float %y) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf_x_known_positive
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_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_pow_afn_v2f32_nnan_x_known_positive
+; CHECK-SAME: (<2 x float> nofpclass(ninf nsub nnorm) [[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]]
+;
+  %pow = tail call afn nnan <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_nnan_ninf_x_known_positive(<2 x float> nofpclass(ninf nnorm nsub) %x, <2 x float> %y) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf_x_known_positive
+; CHECK-SAME: (<2 x float> nofpclass(ninf nsub nnorm) [[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]]
+;
+  %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %pow
+}
+
+define float @test_pow_f32_x_known_positive(float nofpclass(ninf nnorm nsub) %x, float %y) {
+; CHECK-LABEL: define float @test_pow_f32_x_known_positive
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_x_known_positive(float nofpclass(ninf nnorm nsub) %x, float %y) {
+; CHECK-LABEL: define float @test_pow_afn_f32_x_known_positive
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_v2f32_x_known_positive(<2 x float> nofpclass(ninf nnorm nsub) %x, <2 x float> %y) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32_x_known_positive
+; CHECK-SAME: (<2 x float> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_x_known_positive(<2 x float> nofpclass(ninf nnorm nsub) %x, <2 x float> %y) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_x_known_positive
+; CHECK-SAME: (<2 x float> nofpclass(ninf nsub nnorm) [[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]]
+;
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %pow
+}
+
+define double @test_pow_afn_f64_nnan_x_known_positive(double nofpclass(ninf nnorm nsub) %x, double %y) {
+; CHECK-LABEL: define double @test_pow_afn_f64_nnan_x_known_positive
+; CHECK-SAME: (double nofpclass(ninf nsub nnorm) [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn double @_Z3powdd(double [[X]], double [[Y]])
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn nnan double @_Z3powdd(double %x, double %y)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64_nnan_ninf_x_known_positive(double nofpclass(ninf nnorm nsub) %x, double %y) {
+; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf_x_known_positive
+; CHECK-SAME: (double nofpclass(ninf nsub nnorm) [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double [[Y]])
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double %y)
+  ret double %pow
+}
+
+define <2 x double> @test_pow_afn_v2f64_nnan_x_known_positive(<2 x double> nofpclass(ninf nnorm nsub) %x, <2 x double> %y) {
+; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_nnan_x_known_positive
+; CHECK-SAME: (<2 x double> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call afn nnan <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> %y)
+  ret <2 x double> %pow
+}
+
+define <2 x double> @test_pow_afn_v2f64_nnan_ninf_x_known_positive(<2 x double> nofpclass(ninf nnorm nsub) %x, <2 x double> %y) {
+; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_nnan_ninf_x_known_positive
+; CHECK-SAME: (<2 x double> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> %y)
+  ret <2 x double> %pow
+}
+
+define double @test_pow_f64_x_known_positive(double nofpclass(ninf nnorm nsub) %x, double %y) {
+; CHECK-LABEL: define double @test_pow_f64_x_known_positive
+; CHECK-SAME: (double nofpclass(ninf nsub nnorm) [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call double @_Z3powdd(double [[X]], double [[Y]])
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call double @_Z3powdd(double %x, double %y)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64_x_known_positive(double nofpclass(ninf nnorm nsub) %x, double %y) {
+; CHECK-LABEL: define double @test_pow_afn_f64_x_known_positive
+; CHECK-SAME: (double nofpclass(ninf nsub nnorm) [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn double @_Z3powdd(double [[X]], double [[Y]])
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn double @_Z3powdd(double %x, double %y)
+  ret double %pow
+}
+
+define <2 x double> @test_pow_v2f64_x_known_positive(<2 x double> nofpclass(ninf nnorm nsub) %x, <2 x double> %y) {
+; CHECK-LABEL: define <2 x double> @test_pow_v2f64_x_known_positive
+; CHECK-SAME: (<2 x double> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> %y)
+  ret <2 x double> %pow
+}
+
+define <2 x double> @test_pow_afn_v2f64_x_known_positive(<2 x double> nofpclass(ninf nnorm nsub) %x, <2 x double> %y) {
+; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_x_known_positive
+; CHECK-SAME: (<2 x double> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call afn <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> %y)
+  ret <2 x double> %pow
+}
+
+define half @test_pow_afn_f16_nnan_x_known_positive(half nofpclass(ninf nnorm nsub) %x, half %y) {
+; CHECK-LABEL: define half @test_pow_afn_f16_nnan_x_known_positive
+; CHECK-SAME: (half nofpclass(ninf nsub nnorm) [[X:%.*]], half [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn half @_Z3powDhDh(half [[X]], half [[Y]])
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn nnan half @_Z3powDhDh(half %x, half %y)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16_nnan_ninf_x_known_positive(half nofpclass(ninf nnorm nsub) %x, half %y) {
+; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf_x_known_positive
+; CHECK-SAME: (half nofpclass(ninf nsub nnorm) [[X:%.*]], half [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half [[Y]])
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half %y)
+  ret half %pow
+}
+
+define <2 x half> @test_pow_afn_v2f16_nnan_x_known_positive(<2 x half> nofpclass(ninf nnorm nsub) %x, <2 x half> %y) {
+; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_nnan_x_known_positive
+; CHECK-SAME: (<2 x half> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call afn nnan <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> %y)
+  ret <2 x half> %pow
+}
+
+define <2 x half> @test_pow_afn_v2f16_nnan_ninf_x_known_positive(<2 x half> nofpclass(ninf nnorm nsub) %x, <2 x half> %y) {
+; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_nnan_ninf_x_known_positive
+; CHECK-SAME: (<2 x half> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> %y)
+  ret <2 x half> %pow
+}
+
+define half @test_pow_f16_x_known_positive(half nofpclass(ninf nnorm nsub) %x, half %y) {
+; CHECK-LABEL: define half @test_pow_f16_x_known_positive
+; CHECK-SAME: (half nofpclass(ninf nsub nnorm) [[X:%.*]], half [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call half @_Z3powDhDh(half [[X]], half [[Y]])
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call half @_Z3powDhDh(half %x, half %y)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16_x_known_positive(half nofpclass(ninf nnorm nsub) %x, half %y) {
+; CHECK-LABEL: define half @test_pow_afn_f16_x_known_positive
+; CHECK-SAME: (half nofpclass(ninf nsub nnorm) [[X:%.*]], half [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn half @_Z3powDhDh(half [[X]], half [[Y]])
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn half @_Z3powDhDh(half %x, half %y)
+  ret half %pow
+}
+
+define <2 x half> @test_pow_v2f16_x_known_positive(<2 x half> nofpclass(ninf nnorm nsub) %x, <2 x half> %y) {
+; CHECK-LABEL: define <2 x half> @test_pow_v2f16_x_known_positive
+; CHECK-SAME: (<2 x half> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> %y)
+  ret <2 x half> %pow
+}
+
+define <2 x half> @test_pow_afn_v2f16_x_known_positive(<2 x half> nofpclass(ninf nnorm nsub) %x, <2 x half> %y) {
+; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_x_known_positive
+; CHECK-SAME: (<2 x half> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call afn <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> %y)
+  ret <2 x half> %pow
+}
+
+define float @test_pow_f32__y_0(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+  %pow = tail call float @_Z3powff(float %x, float 0.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_n0(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_n0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+  %pow = tail call float @_Z3powff(float %x, float -0.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_1(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_1
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    ret float [[X]]
+;
+  %pow = tail call float @_Z3powff(float %x, float 1.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_n1(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_n1
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv float 1.000000e+00, [[X]]
+; CHECK-NEXT:    ret float [[__POWRECIP]]
+;
+  %pow = tail call float @_Z3powff(float %x, float -1.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_2(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_2
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul float [[X]], [[X]]
+; CHECK-NEXT:    ret float [[__POW2]]
+;
+  %pow = tail call float @_Z3powff(float %x, float 2.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_n2(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_n2
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float -2.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call float @_Z3powff(float %x, float -2.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_half(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_half
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2SQRT:%.*]] = call float @_Z4sqrtf(float [[X]])
+; CHECK-NEXT:    ret float [[__POW2SQRT]]
+;
+  %pow = tail call float @_Z3powff(float %x, float 0.5)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_neg_half(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_neg_half
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2RSQRT:%.*]] = call float @_Z5rsqrtf(float [[X]])
+; CHECK-NEXT:    ret float [[__POW2RSQRT]]
+;
+  %pow = tail call float @_Z3powff(float %x, float -0.5)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_3(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_3
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float 3.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call float @_Z3powff(float %x, float 3.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_n3(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_n3
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float -3.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call float @_Z3powff(float %x, float -3.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_2_5(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_2_5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float 2.500000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call float @_Z3powff(float %x, float 2.5)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_n_2_5(float %x) {
+; CHECK-LABEL: define float @test_pow_f32__y_n_2_5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float -2.500000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call float @_Z3powff(float %x, float -2.5)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> zeroinitializer)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_n0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_n0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -0.0, float -0.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_1(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_1
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    ret <2 x float> [[X]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 1.0,float 1.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_n1(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_n1
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POWRECIP]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -1.0, float -1.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_2(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_2
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POW2]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 2.0, float 2.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_n2(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_n2
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float -2.000000e+00, float -2.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -2.0, float -2.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_half(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_half
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2SQRT:%.*]] = call <2 x float> @_Z4sqrtDv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    ret <2 x float> [[__POW2SQRT]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 0.5, float 0.5>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_neg_half(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_neg_half
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2RSQRT:%.*]] = call <2 x float> @_Z5rsqrtDv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    ret <2 x float> [[__POW2RSQRT]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -0.5, float -0.5>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_3(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_3
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 3.000000e+00, float 3.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 3.0, float 3.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_n3(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_n3
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float -3.000000e+00, float -3.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -3.0,float -3.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_2_5(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_2_5
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 2.500000e+00, float 2.500000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 2.5, float 2.5>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32__y_n_2_5(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_v2f32__y_n_2_5
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float -2.500000e+00, float -2.500000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float -2.5, float -2.5>)
+  ret <2 x float> %pow
+}
+
+define float @test_pow_f32__known_positive__y_0(float nofpclass(ninf nnorm nsub) %x) {
+; CHECK-LABEL: define float @test_pow_f32__known_positive__y_0
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+  %pow = tail call float @_Z3powff(float %x, float 0.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__known_positive__y_1(float nofpclass(ninf nnorm nsub) %x) {
+; CHECK-LABEL: define float @test_pow_f32__known_positive__y_1
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT:    ret float [[X]]
+;
+  %pow = tail call float @_Z3powff(float %x, float 1.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__known_positive__y_neg1(float nofpclass(ninf nnorm nsub) %x) {
+; CHECK-LABEL: define float @test_pow_f32__known_positive__y_neg1
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv float 1.000000e+00, [[X]]
+; CHECK-NEXT:    ret float [[__POWRECIP]]
+;
+  %pow = tail call float @_Z3powff(float %x, float -1.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__known_positive__y_2(float nofpclass(ninf nnorm nsub) %x) {
+; CHECK-LABEL: define float @test_pow_f32__known_positive__y_2
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul float [[X]], [[X]]
+; CHECK-NEXT:    ret float [[__POW2]]
+;
+  %pow = tail call float @_Z3powff(float %x, float 2.0)
+  ret float %pow
+}
+
+define float @test_pow_f32__known_positive__y_half(float nofpclass(ninf nnorm nsub) %x) {
+; CHECK-LABEL: define float @test_pow_f32__known_positive__y_half
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2SQRT:%.*]] = call float @_Z4sqrtf(float [[X]])
+; CHECK-NEXT:    ret float [[__POW2SQRT]]
+;
+  %pow = tail call float @_Z3powff(float %x, float 0.5)
+  ret float %pow
+}
+
+define float @test_pow_f32__known_positive__y_neghalf(float nofpclass(ninf nnorm nsub) %x) {
+; CHECK-LABEL: define float @test_pow_f32__known_positive__y_neghalf
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2RSQRT:%.*]] = call float @_Z5rsqrtf(float [[X]])
+; CHECK-NEXT:    ret float [[__POW2RSQRT]]
+;
+  %pow = tail call float @_Z3powff(float %x, float -0.5)
+  ret float %pow
+}
+
+define float @test_pow_f32_x_assumed_oge_0(float %x, float %y) {
+; CHECK-LABEL: define float @test_pow_f32_x_assumed_oge_0
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[X_OGE_ZERO:%.*]] = fcmp oge float [[X]], 0.000000e+00
+; CHECK-NEXT:    call void @llvm.assume(i1 [[X_OGE_ZERO]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %x.oge.zero = fcmp oge float %x, 0.0
+  call void @llvm.assume(i1 %x.oge.zero)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32_x_assumed_ogt_0(float %x, float %y) {
+; CHECK-LABEL: define float @test_pow_f32_x_assumed_ogt_0
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[X_OGE_ZERO:%.*]] = fcmp ogt float [[X]], 0.000000e+00
+; CHECK-NEXT:    call void @llvm.assume(i1 [[X_OGE_ZERO]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %x.oge.zero = fcmp ogt float %x, 0.0
+  call void @llvm.assume(i1 %x.oge.zero)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32_x_assumed_uge_0(float %x, float %y) {
+; CHECK-LABEL: define float @test_pow_f32_x_assumed_uge_0
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[X_UGE_ZERO:%.*]] = fcmp uge float [[X]], 0.000000e+00
+; CHECK-NEXT:    call void @llvm.assume(i1 [[X_UGE_ZERO]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %x.uge.zero = fcmp uge float %x, 0.0
+  call void @llvm.assume(i1 %x.uge.zero)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32_x_assumed_ugt_0(float %x, float %y) {
+; CHECK-LABEL: define float @test_pow_f32_x_assumed_ugt_0
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[X_UGT_ZERO:%.*]] = fcmp ugt float [[X]], 0.000000e+00
+; CHECK-NEXT:    call void @llvm.assume(i1 [[X_UGT_ZERO]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %x.ugt.zero = fcmp ugt float %x, 0.0
+  call void @llvm.assume(i1 %x.ugt.zero)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32__y_poison(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32__y_poison
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float poison)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float poison)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32__y_3(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32__y_3
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float 3.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 3.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_nnan_ninf__y_3(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_3
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 3.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 3.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32__y_4(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32__y_4
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float 4.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 4.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_nnan_ninf__y_4(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_4
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 4.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 4.0)
+  ret float %pow
+}
+
+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]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 4.5)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32__y_5(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32__y_5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float 5.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float 5.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_nnan_ninf__y_5(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 5.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 5.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32__y_neg5(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32__y_neg5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float -5.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn float @_Z3powff(float %x, float -5.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_nnan_ninf__y_neg5(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_neg5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float -5.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float -5.0)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_nnan_ninf__y_10(float %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_10
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 1.000000e+01)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 10.0)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_poison(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_poison
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> poison)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> poison)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_3(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_3
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 3.000000e+00, float 3.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 3.0, float 3.0>)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_4
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 4.000000e+00, float 4.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 4.0, float 4.0>)
+  ret <2 x float> %pow
+}
+
+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> <float 4.500000e+00, float 4.500000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_5(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_v2f32_nnan_ninf__y_5
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> <float 5.000000e+00, float 5.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> <float 5.0, float 5.0>)
+  ret <2 x float> %pow
+}
+
+define float @test_pow_afn_f32_nnan_ninf__y_5_known_positive(float nofpclass(ninf nsub nnorm) %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_5_known_positive
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 5.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 5.0)
+  ret float %pow
+}
+
+; we know we can ignore missing ninf on the input from the flag on the call
+define float @test_pow_afn_f32_nnan_ninf__y_5_known_positive_with_ninf_flag(float nofpclass(nsub nnorm) %x) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_5_known_positive_with_ninf_flag
+; CHECK-SAME: (float nofpclass(nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float 5.000000e+00)
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float 5.0)
+  ret float %pow
+}
+
+define double @test_pow_afn_f64__y_3(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64__y_3
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn double @_Z3powdd(double [[X]], double 3.000000e+00)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn double @_Z3powdd(double %x, double 3.0)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64_nnan_ninf__y_3(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_3
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double 3.000000e+00)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double 3.0)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64__y_4(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64__y_4
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn double @_Z3powdd(double [[X]], double 4.000000e+00)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn double @_Z3powdd(double %x, double 4.0)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64_nnan_ninf__y_4(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_4
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double 4.000000e+00)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double 4.0)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64_nnan_ninf__y_4_5(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_4_5
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double 4.500000e+00)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double 4.5)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64__y_5(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64__y_5
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn double @_Z3powdd(double [[X]], double 5.000000e+00)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn double @_Z3powdd(double %x, double 5.0)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64_nnan_ninf__y_5(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_5
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double 5.000000e+00)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double 5.0)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64__y_neg5(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64__y_neg5
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn double @_Z3powdd(double [[X]], double -5.000000e+00)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn double @_Z3powdd(double %x, double -5.0)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64_nnan_ninf__y_neg5(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_neg5
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double -5.000000e+00)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double -5.0)
+  ret double %pow
+}
+
+define double @test_pow_afn_f64_nnan_ninf__y_10(double %x) {
+; CHECK-LABEL: define double @test_pow_afn_f64_nnan_ninf__y_10
+; CHECK-SAME: (double [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn double @_Z3powdd(double [[X]], double 1.000000e+01)
+; CHECK-NEXT:    ret double [[POW]]
+;
+  %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double 10.0)
+  ret double %pow
+}
+
+define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_3(<2 x double> %x) {
+; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_3
+; CHECK-SAME: (<2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> <double 3.000000e+00, double 3.000000e+00>)
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> <double 3.0, double 3.0>)
+  ret <2 x double> %pow
+}
+
+define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_4(<2 x double> %x) {
+; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_4
+; CHECK-SAME: (<2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> <double 4.000000e+00, double 4.000000e+00>)
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> <double 4.0, double 4.0>)
+  ret <2 x double> %pow
+}
+
+define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_4_5(<2 x double> %x) {
+; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_4_5
+; CHECK-SAME: (<2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> <double 4.500000e+00, double 4.500000e+00>)
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> <double 4.5, double 4.5>)
+  ret <2 x double> %pow
+}
+
+define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_5(<2 x double> %x) {
+; CHECK-LABEL: define <2 x double> @test_pow_afn_v2f64_nnan_ninf__y_5
+; CHECK-SAME: (<2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x double> @_Z3powDv2_dS_(<2 x double> [[X]], <2 x double> <double 5.000000e+00, double 5.000000e+00>)
+; CHECK-NEXT:    ret <2 x double> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x double> @_Z3powDv2_dS_(<2 x double> %x, <2 x double> <double 5.0, double 5.0>)
+  ret <2 x double> %pow
+}
+
+define half @test_pow_afn_f16__y_3(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16__y_3
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn half @_Z3powDhDh(half [[X]], half 0xH4200)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn half @_Z3powDhDh(half %x, half 3.0)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16_nnan_ninf__y_3(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_3
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xH4200)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half 3.0)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16__y_4(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16__y_4
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn half @_Z3powDhDh(half [[X]], half 0xH4400)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn half @_Z3powDhDh(half %x, half 4.0)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16_nnan_ninf__y_4(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_4
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xH4400)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half 4.0)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16_nnan_ninf__y_4_5(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_4_5
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xH4480)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half 4.5)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16__y_5(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16__y_5
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn half @_Z3powDhDh(half [[X]], half 0xH4500)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn half @_Z3powDhDh(half %x, half 5.0)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16_nnan_ninf__y_5(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_5
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xH4500)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half 5.0)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16__y_neg5(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16__y_neg5
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn half @_Z3powDhDh(half [[X]], half 0xHC500)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn half @_Z3powDhDh(half %x, half -5.0)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16_nnan_ninf__y_neg5(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_neg5
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xHC500)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half -5.0)
+  ret half %pow
+}
+
+define half @test_pow_afn_f16_nnan_ninf__y_10(half %x) {
+; CHECK-LABEL: define half @test_pow_afn_f16_nnan_ninf__y_10
+; CHECK-SAME: (half [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn half @_Z3powDhDh(half [[X]], half 0xH4900)
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half 10.0)
+  ret half %pow
+}
+
+define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_3(<2 x half> %x) {
+; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_3
+; CHECK-SAME: (<2 x half> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> <half 0xH4200, half 0xH4200>)
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> <half 3.0, half 3.0>)
+  ret <2 x half> %pow
+}
+
+define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_4(<2 x half> %x) {
+; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_4
+; CHECK-SAME: (<2 x half> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> <half 0xH4400, half 0xH4400>)
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> <half 4.0, half 4.0>)
+  ret <2 x half> %pow
+}
+
+define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_4_5(<2 x half> %x) {
+; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_4_5
+; CHECK-SAME: (<2 x half> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> <half 0xH4480, half 0xH4480>)
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> <half 4.5, half 4.5>)
+  ret <2 x half> %pow
+}
+
+define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_5(<2 x half> %x) {
+; CHECK-LABEL: define <2 x half> @test_pow_afn_v2f16_nnan_ninf__y_5
+; CHECK-SAME: (<2 x half> [[X:%.*]]) {
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x half> @_Z3powDv2_DhS_(<2 x half> [[X]], <2 x half> <half 0xH4500, half 0xH4500>)
+; CHECK-NEXT:    ret <2 x half> [[POW]]
+;
+  %pow = tail call afn nnan ninf <2 x half> @_Z3powDv2_DhS_(<2 x half> %x, <2 x half> <half 5.0, half 5.0>)
+  ret <2 x half> %pow
+}
+
+define float @test_pow_f32_known_integral_sitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_f32_known_integral_sitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i32 %y to float
+  %pow = tail call float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_known_integral_sitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_afn_f32_known_integral_sitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i32 %y to float
+  %pow = tail call afn float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_nnan_ninf_f32_known_integral_sitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_afn_nnan_ninf_f32_known_integral_sitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i32 %y to float
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_nnan_f32_known_integral_sitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_afn_nnan_f32_known_integral_sitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i32 %y to float
+  %pow = tail call afn nnan float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_ninf_f32_known_integral_sitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_afn_ninf_f32_known_integral_sitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call ninf afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i32 %y to float
+  %pow = tail call afn ninf float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_known_integral_sitofp_finite_argument(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_afn_f32_known_integral_sitofp_finite_argument
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float nofpclass(nan inf) [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i32 %y to float
+  %pow = tail call float @_Z3powff(float %x, float nofpclass(inf nan) %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_f32_known_integral_uitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_f32_known_integral_uitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = uitofp i32 %y to float
+  %pow = tail call float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_known_integral_uitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_afn_f32_known_integral_uitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = uitofp i32 %y to float
+  %pow = tail call afn float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_nnan_ninf_f32_known_integral_uitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_afn_nnan_ninf_f32_known_integral_uitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = uitofp i32 %y to float
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+; cast from i256 may produce infinity so can't assume integer without ninf
+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]]
+;
+  %y.cast = uitofp i256 %y to float
+  %pow = tail call afn nnan float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+; cast from i256 may produce infinity so can't assume integer without ninf
+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]]
+;
+  %y.cast = sitofp i256 %y to float
+  %pow = tail call afn nnan float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_nnan_ninf_f32_known_integral_uitofp_i256(float %x, i256 %y) {
+; CHECK-LABEL: define float @test_pow_afn_nnan_ninf_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 ninf afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = uitofp i256 %y to float
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_nnan_ninf_f32_known_integral_sitofp_i256(float %x, i256 %y) {
+; CHECK-LABEL: define float @test_pow_afn_nnan_ninf_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 ninf afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i256 %y to float
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define <2 x float> @test_pow_afn_nnan_ninf_v2f32_known_integral_sitofp(<2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_nnan_ninf_v2f32_known_integral_sitofp
+; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp <2 x i32> [[Y]] to <2 x float>
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %y.cast = sitofp <2 x i32> %y to <2 x float>
+  %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y.cast)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_v2f32_known_integral_uitofp(<2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @test_pow_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:    [[POW:%.*]] = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %y.cast = uitofp <2 x i32> %y to <2 x float>
+  %pow = tail call <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y.cast)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_v2f32_known_integral_uitofp(<2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @test_pow_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:    [[POW:%.*]] = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %y.cast = uitofp <2 x i32> %y to <2 x float>
+  %pow = tail call afn <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y.cast)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @test_pow_afn_nnan_ninf_v2f32_known_integral_uitofp(<2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @test_pow_afn_nnan_ninf_v2f32_known_integral_uitofp
+; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp <2 x i32> [[Y]] to <2 x float>
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z3powDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %y.cast = uitofp <2 x i32> %y to <2 x float>
+  %pow = tail call afn nnan ninf <2 x float> @_Z3powDv2_fS_(<2 x float> %x, <2 x float> %y.cast)
+  ret <2 x float> %pow
+}
+
+; Could fold to powr or pown
+define float @test_pow_f32_known_positive_x__known_integral_sitofp(float nofpclass(ninf nsub nnorm) %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_f32_known_positive_x__known_integral_sitofp
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i32 %y to float
+  %pow = tail call float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_known_positive_x__known_integral_sitofp(float nofpclass(ninf nsub nnorm) %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_afn_f32_known_positive_x__known_integral_sitofp
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i32 %y to float
+  %pow = tail call afn float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_afn_nnan_ninf_f32__known_positive_x__known_integral_sitofp(float nofpclass(ninf nsub nnorm) %x, i32 %y) {
+; CHECK-LABEL: define float @test_pow_afn_nnan_ninf_f32__known_positive_x__known_integral_sitofp
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y.cast = sitofp i32 %y to float
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y.cast)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_known_integral_trunc_maybe_inf(float %x, float nofpclass(nan) %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_trunc_maybe_inf
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(nan) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.trunc.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.trunc.f32(float %y.arg)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_known_integral_trunc_maybe_nan(float %x, float nofpclass(inf) %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_trunc_maybe_nan
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(inf) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.trunc.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.trunc.f32(float %y.arg)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+; Cannot fold to pown, may still be inf
+define float @test_pow_f32__y_known_integral_trunc_nnan_use(float %x, float %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_trunc_nnan_use
+; CHECK-SAME: (float [[X:%.*]], float [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.trunc.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.trunc.f32(float %y.arg)
+  %pow = tail call nnan float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+; Cannot fold to pown, may still be nan
+define float @test_pow_f32__y_known_integral_trunc_ninf_use(float %x, float %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_trunc_ninf_use
+; CHECK-SAME: (float [[X:%.*]], float [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.trunc.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call ninf float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.trunc.f32(float %y.arg)
+  %pow = tail call ninf float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32_nnan_ninf__y_known_integral_trunc(float %x, float %y.arg) {
+; CHECK-LABEL: define float @test_pow_afn_f32_nnan_ninf__y_known_integral_trunc
+; CHECK-SAME: (float [[X:%.*]], float [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.trunc.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call nnan ninf afn float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.trunc.f32(float %y.arg)
+  %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_afn_f32__y_known_integral_trunc(float %x, float nofpclass(inf nan) %y.arg) {
+; CHECK-LABEL: define float @test_pow_afn_f32__y_known_integral_trunc
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(nan inf) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.trunc.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call afn float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.trunc.f32(float %y.arg)
+  %pow = tail call afn float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_known_integral_floor(float %x, float nofpclass(inf nan) %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_floor
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(nan inf) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.floor.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.floor.f32(float %y.arg)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_known_integral_ceil(float %x, float nofpclass(inf nan) %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_ceil
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(nan inf) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.floor.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.floor.f32(float %y.arg)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_known_integral_trunc(float %x, float nofpclass(inf nan) %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_trunc
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(nan inf) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.trunc.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.trunc.f32(float %y.arg)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_known_integral_rint(float %x, float nofpclass(inf nan) %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_rint
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(nan inf) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.rint.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.rint.f32(float %y.arg)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_known_integral_nearbyint(float %x, float nofpclass(inf nan) %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_nearbyint
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(nan inf) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.nearbyint.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.nearbyint.f32(float %y.arg)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_known_integral_round(float %x, float nofpclass(inf nan) %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_round
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(nan inf) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.round.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.round.f32(float %y.arg)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+define float @test_pow_f32__y_known_integral_roundeven(float %x, float nofpclass(inf nan) %y.arg) {
+; CHECK-LABEL: define float @test_pow_f32__y_known_integral_roundeven
+; CHECK-SAME: (float [[X:%.*]], float nofpclass(nan inf) [[Y_ARG:%.*]]) {
+; CHECK-NEXT:    [[Y:%.*]] = call float @llvm.roundeven.f32(float [[Y_ARG]])
+; CHECK-NEXT:    [[POW:%.*]] = tail call float @_Z3powff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POW]]
+;
+  %y = call float @llvm.roundeven.f32(float %y.arg)
+  %pow = tail call float @_Z3powff(float %x, float %y)
+  ret float %pow
+}
+
+attributes #0 = { minsize }
+attributes #1 = { noinline }
+attributes #2 = { strictfp }
+attributes #3 = { nobuiltin }

diff  --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
new file mode 100644
index 00000000000000..b2aca1bf9d0956
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pown.ll
@@ -0,0 +1,1062 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=amdgpu-simplifylib,instcombine -amdgpu-prelink %s | FileCheck %s
+
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8"
+
+declare float @_Z4pownfi(float, i32)
+declare <2 x float> @_Z4pownDv2_fDv2_i(<2 x float>, <2 x i32>)
+declare <3 x float> @_Z4pownDv3_fDv3_i(<3 x float>, <3 x i32>)
+declare <4 x float> @_Z4pownDv4_fDv4_i(<4 x float>, <4 x i32>)
+declare <8 x float> @_Z4pownDv8_fDv8_i(<8 x float>, <8 x i32>)
+declare <16 x float> @_Z4pownDv16_fDv16_i(<16 x float>, <16 x i32>)
+declare double @_Z4powndi(double, i32)
+declare <2 x double> @_Z4pownDv2_dDv2_i(<2 x double>, <2 x i32>)
+declare <3 x double> @_Z4pownDv3_dDv3_i(<3 x double>, <3 x i32>)
+declare <4 x double> @_Z4pownDv4_dDv4_i(<4 x double>, <4 x i32>)
+declare <8 x double> @_Z4pownDv8_dDv8_i(<8 x double>, <8 x i32>)
+declare <16 x double> @_Z4pownDv16_dDv16_i(<16 x double>, <16 x i32>)
+declare half @_Z4pownDhi(half, i32)
+declare <2 x half> @_Z4pownDv2_DhDv2_i(<2 x half>, <2 x i32>)
+declare <3 x half> @_Z4pownDv3_DhDv3_i(<3 x half>, <3 x i32>)
+declare <4 x half> @_Z4pownDv4_DhDv4_i(<4 x half>, <4 x i32>)
+declare <8 x half> @_Z4pownDv8_DhDv8_i(<8 x half>, <8 x i32>)
+declare <16 x half> @_Z4pownDv16_DhDv16_i(<16 x half>, <16 x i32>)
+
+define float @test_pown_f32(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pown_f32
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z4pownfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret float [[CALL]]
+;
+entry:
+  %call = tail call float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define <2 x float> @test_pown_v2f32(<2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @test_pown_v2f32
+; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> %y)
+  ret <2 x float> %call
+}
+
+define <3 x float> @test_pown_v3f32(<3 x float> %x, <3 x i32> %y) {
+; CHECK-LABEL: define <3 x float> @test_pown_v3f32
+; CHECK-SAME: (<3 x float> [[X:%.*]], <3 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> [[X]], <3 x i32> [[Y]])
+; CHECK-NEXT:    ret <3 x float> [[CALL]]
+;
+entry:
+  %call = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> %x, <3 x i32> %y)
+  ret <3 x float> %call
+}
+
+define <4 x float> @test_pown_v4f32(<4 x float> %x, <4 x i32> %y) {
+; CHECK-LABEL: define <4 x float> @test_pown_v4f32
+; CHECK-SAME: (<4 x float> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <4 x float> @_Z4pownDv4_fDv4_i(<4 x float> [[X]], <4 x i32> [[Y]])
+; CHECK-NEXT:    ret <4 x float> [[CALL]]
+;
+entry:
+  %call = tail call <4 x float> @_Z4pownDv4_fDv4_i(<4 x float> %x, <4 x i32> %y)
+  ret <4 x float> %call
+}
+
+define <8 x float> @test_pown_v8f32(<8 x float> %x, <8 x i32> %y) {
+; CHECK-LABEL: define <8 x float> @test_pown_v8f32
+; CHECK-SAME: (<8 x float> [[X:%.*]], <8 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <8 x float> @_Z4pownDv8_fDv8_i(<8 x float> [[X]], <8 x i32> [[Y]])
+; CHECK-NEXT:    ret <8 x float> [[CALL]]
+;
+entry:
+  %call = tail call <8 x float> @_Z4pownDv8_fDv8_i(<8 x float> %x, <8 x i32> %y)
+  ret <8 x float> %call
+}
+
+define <16 x float> @test_pown_v16f32(<16 x float> %x, <16 x i32> %y) {
+; CHECK-LABEL: define <16 x float> @test_pown_v16f32
+; CHECK-SAME: (<16 x float> [[X:%.*]], <16 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <16 x float> @_Z4pownDv16_fDv16_i(<16 x float> [[X]], <16 x i32> [[Y]])
+; CHECK-NEXT:    ret <16 x float> [[CALL]]
+;
+entry:
+  %call = tail call <16 x float> @_Z4pownDv16_fDv16_i(<16 x float> %x, <16 x i32> %y)
+  ret <16 x float> %call
+}
+
+define double @test_pown_f64(double %x, i32 %y) {
+; CHECK-LABEL: define double @test_pown_f64
+; CHECK-SAME: (double [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call double @_Z4powndi(double [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret double [[CALL]]
+;
+entry:
+  %call = tail call double @_Z4powndi(double %x, i32 %y)
+  ret double %call
+}
+
+define <2 x double> @test_pown_v2f64(<2 x double> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x double> @test_pown_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <2 x double> @_Z4pownDv2_dDv2_i(<2 x double> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[CALL]]
+;
+entry:
+  %call = tail call <2 x double> @_Z4pownDv2_dDv2_i(<2 x double> %x, <2 x i32> %y)
+  ret <2 x double> %call
+}
+
+define <3 x double> @test_pown_v3f64(<3 x double> %x, <3 x i32> %y) {
+; CHECK-LABEL: define <3 x double> @test_pown_v3f64
+; CHECK-SAME: (<3 x double> [[X:%.*]], <3 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <3 x double> @_Z4pownDv3_dDv3_i(<3 x double> [[X]], <3 x i32> [[Y]])
+; CHECK-NEXT:    ret <3 x double> [[CALL]]
+;
+entry:
+  %call = tail call <3 x double> @_Z4pownDv3_dDv3_i(<3 x double> %x, <3 x i32> %y)
+  ret <3 x double> %call
+}
+
+define <4 x double> @test_pown_v4f64(<4 x double> %x, <4 x i32> %y) {
+; CHECK-LABEL: define <4 x double> @test_pown_v4f64
+; CHECK-SAME: (<4 x double> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <4 x double> @_Z4pownDv4_dDv4_i(<4 x double> [[X]], <4 x i32> [[Y]])
+; CHECK-NEXT:    ret <4 x double> [[CALL]]
+;
+entry:
+  %call = tail call <4 x double> @_Z4pownDv4_dDv4_i(<4 x double> %x, <4 x i32> %y)
+  ret <4 x double> %call
+}
+
+define <8 x double> @test_pown_v8f64(<8 x double> %x, <8 x i32> %y) {
+; CHECK-LABEL: define <8 x double> @test_pown_v8f64
+; CHECK-SAME: (<8 x double> [[X:%.*]], <8 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <8 x double> @_Z4pownDv8_dDv8_i(<8 x double> [[X]], <8 x i32> [[Y]])
+; CHECK-NEXT:    ret <8 x double> [[CALL]]
+;
+entry:
+  %call = tail call <8 x double> @_Z4pownDv8_dDv8_i(<8 x double> %x, <8 x i32> %y)
+  ret <8 x double> %call
+}
+
+define <16 x double> @test_pown_v16f64(<16 x double> %x, <16 x i32> %y) {
+; CHECK-LABEL: define <16 x double> @test_pown_v16f64
+; CHECK-SAME: (<16 x double> [[X:%.*]], <16 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <16 x double> @_Z4pownDv16_dDv16_i(<16 x double> [[X]], <16 x i32> [[Y]])
+; CHECK-NEXT:    ret <16 x double> [[CALL]]
+;
+entry:
+  %call = tail call <16 x double> @_Z4pownDv16_dDv16_i(<16 x double> %x, <16 x i32> %y)
+  ret <16 x double> %call
+}
+
+define half @test_pown_f16(half %x, i32 %y) {
+; CHECK-LABEL: define half @test_pown_f16
+; CHECK-SAME: (half [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call half @_Z4pownDhi(half [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret half [[CALL]]
+;
+entry:
+  %call = tail call half @_Z4pownDhi(half %x, i32 %y)
+  ret half %call
+}
+
+define <2 x half> @test_pown_v2f16(<2 x half> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x half> @test_pown_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <2 x half> @_Z4pownDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[CALL]]
+;
+entry:
+  %call = tail call <2 x half> @_Z4pownDv2_DhDv2_i(<2 x half> %x, <2 x i32> %y)
+  ret <2 x half> %call
+}
+
+define <3 x half> @test_pown_v3f16(<3 x half> %x, <3 x i32> %y) {
+; CHECK-LABEL: define <3 x half> @test_pown_v3f16
+; CHECK-SAME: (<3 x half> [[X:%.*]], <3 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <3 x half> @_Z4pownDv3_DhDv3_i(<3 x half> [[X]], <3 x i32> [[Y]])
+; CHECK-NEXT:    ret <3 x half> [[CALL]]
+;
+entry:
+  %call = tail call <3 x half> @_Z4pownDv3_DhDv3_i(<3 x half> %x, <3 x i32> %y)
+  ret <3 x half> %call
+}
+
+define <4 x half> @test_pown_v4f16(<4 x half> %x, <4 x i32> %y) {
+; CHECK-LABEL: define <4 x half> @test_pown_v4f16
+; CHECK-SAME: (<4 x half> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <4 x half> @_Z4pownDv4_DhDv4_i(<4 x half> [[X]], <4 x i32> [[Y]])
+; CHECK-NEXT:    ret <4 x half> [[CALL]]
+;
+entry:
+  %call = tail call <4 x half> @_Z4pownDv4_DhDv4_i(<4 x half> %x, <4 x i32> %y)
+  ret <4 x half> %call
+}
+
+define <8 x half> @test_pown_v8f16(<8 x half> %x, <8 x i32> %y) {
+; CHECK-LABEL: define <8 x half> @test_pown_v8f16
+; CHECK-SAME: (<8 x half> [[X:%.*]], <8 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <8 x half> @_Z4pownDv8_DhDv8_i(<8 x half> [[X]], <8 x i32> [[Y]])
+; CHECK-NEXT:    ret <8 x half> [[CALL]]
+;
+entry:
+  %call = tail call <8 x half> @_Z4pownDv8_DhDv8_i(<8 x half> %x, <8 x i32> %y)
+  ret <8 x half> %call
+}
+
+define <16 x half> @test_pown_v16f16(<16 x half> %x, <16 x i32> %y) {
+; CHECK-LABEL: define <16 x half> @test_pown_v16f16
+; CHECK-SAME: (<16 x half> [[X:%.*]], <16 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <16 x half> @_Z4pownDv16_DhDv16_i(<16 x half> [[X]], <16 x i32> [[Y]])
+; CHECK-NEXT:    ret <16 x half> [[CALL]]
+;
+entry:
+  %call = tail call <16 x half> @_Z4pownDv16_DhDv16_i(<16 x half> %x, <16 x i32> %y)
+  ret <16 x half> %call
+}
+
+define float @test_pown_f32__y_0(float %x) {
+; CHECK-LABEL: define float @test_pown_f32__y_0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+entry:
+  %call = tail call float @_Z4pownfi(float %x, i32 0)
+  ret float %call
+}
+
+define float @test_pown_f32__y_poison(float %x) {
+; CHECK-LABEL: define float @test_pown_f32__y_poison
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z4pownfi(float [[X]], i32 poison)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+entry:
+  %call = tail call float @_Z4pownfi(float %x, i32 poison)
+  ret float %call
+}
+
+define <2 x float> @test_pown_v2f32__y_poison(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_v2f32__y_poison
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> poison)
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> poison)
+  ret <2 x float> %call
+}
+
+define <2 x float> @test_pown_v2f32__y_0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_v2f32__y_0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
+;
+entry:
+  %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> zeroinitializer)
+  ret <2 x float> %call
+}
+
+define <2 x float> @test_pown_v2f32__y_0_undef(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_v2f32__y_0_undef
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 0, i32 poison>)
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 0, i32 poison>)
+  ret <2 x float> %call
+}
+
+define <3 x float> @test_pown_v3f32__y_0(<3 x float> %x) {
+; CHECK-LABEL: define <3 x float> @test_pown_v3f32__y_0
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <3 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
+;
+entry:
+  %call = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> %x, <3 x i32> zeroinitializer)
+  ret <3 x float> %call
+}
+
+define <4 x float> @test_pown_v4f32__y_0(<4 x float> %x) {
+; CHECK-LABEL: define <4 x float> @test_pown_v4f32__y_0
+; CHECK-SAME: (<4 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
+;
+entry:
+  %call = tail call <4 x float> @_Z4pownDv4_fDv4_i(<4 x float> %x, <4 x i32> zeroinitializer)
+  ret <4 x float> %call
+}
+
+define <8 x float> @test_pown_v8f32__y_0(<8 x float> %x) {
+; CHECK-LABEL: define <8 x float> @test_pown_v8f32__y_0
+; CHECK-SAME: (<8 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <8 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
+;
+entry:
+  %call = tail call <8 x float> @_Z4pownDv8_fDv8_i(<8 x float> %x, <8 x i32> zeroinitializer)
+  ret <8 x float> %call
+}
+
+define <16 x float> @test_pown_v16f32__y_0(<16 x float> %x) {
+; CHECK-LABEL: define <16 x float> @test_pown_v16f32__y_0
+; CHECK-SAME: (<16 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <16 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
+;
+entry:
+  %call = tail call <16 x float> @_Z4pownDv16_fDv16_i(<16 x float> %x, <16 x i32> zeroinitializer)
+  ret <16 x float> %call
+}
+
+define float @test_pown_f32__y_1(float %x) {
+; CHECK-LABEL: define float @test_pown_f32__y_1
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret float [[X]]
+;
+entry:
+  %call = tail call float @_Z4pownfi(float %x, i32 1)
+  ret float %call
+}
+
+define <2 x float> @test_pown_v2f32__y_1(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_v2f32__y_1
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <2 x float> [[X]]
+;
+entry:
+  %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 1, i32 1>)
+  ret <2 x float> %call
+}
+
+define <2 x float> @test_pown_v2f32__y_1_undef(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_v2f32__y_1_undef
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 1, i32 poison>)
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 1, i32 poison>)
+  ret <2 x float> %call
+}
+
+define <3 x float> @test_pown_v3f32__y_1(<3 x float> %x) {
+; CHECK-LABEL: define <3 x float> @test_pown_v3f32__y_1
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <3 x float> [[X]]
+;
+entry:
+  %call = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> %x, <3 x i32> <i32 1, i32 1, i32 1>)
+  ret <3 x float> %call
+}
+
+define <3 x float> @test_pown_v3f32__y_1_undef(<3 x float> %x) {
+; CHECK-LABEL: define <3 x float> @test_pown_v3f32__y_1_undef
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> [[X]], <3 x i32> <i32 1, i32 1, i32 poison>)
+; CHECK-NEXT:    ret <3 x float> [[CALL]]
+;
+entry:
+  %call = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> %x, <3 x i32> <i32 1, i32 1, i32 poison>)
+  ret <3 x float> %call
+}
+
+define <4 x float> @test_pown_v4f32__y_1(<4 x float> %x) {
+; CHECK-LABEL: define <4 x float> @test_pown_v4f32__y_1
+; CHECK-SAME: (<4 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <4 x float> [[X]]
+;
+entry:
+  %call = tail call <4 x float> @_Z4pownDv4_fDv4_i(<4 x float> %x, <4 x i32> <i32 1, i32 1, i32 1, i32 1>)
+  ret <4 x float> %call
+}
+
+define <8 x float> @test_pown_v8f32__y_1(<8 x float> %x) {
+; CHECK-LABEL: define <8 x float> @test_pown_v8f32__y_1
+; CHECK-SAME: (<8 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <8 x float> [[X]]
+;
+entry:
+  %call = tail call <8 x float> @_Z4pownDv8_fDv8_i(<8 x float> %x, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>)
+  ret <8 x float> %call
+}
+
+define <16 x float> @test_pown_v16f32__y_1(<16 x float> %x) {
+; CHECK-LABEL: define <16 x float> @test_pown_v16f32__y_1
+; CHECK-SAME: (<16 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret <16 x float> [[X]]
+;
+entry:
+  %call = tail call <16 x float> @_Z4pownDv16_fDv16_i(<16 x float> %x, <16 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>)
+  ret <16 x float> %call
+}
+
+define float @test_pown_f32__y_2(float %x) {
+; CHECK-LABEL: define float @test_pown_f32__y_2
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul float [[X]], [[X]]
+; CHECK-NEXT:    ret float [[__POW2]]
+;
+entry:
+  %call = tail call float @_Z4pownfi(float %x, i32 2)
+  ret float %call
+}
+
+define <2 x float> @test_pown_v2f32__y_2(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_v2f32__y_2
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POW2]]
+;
+entry:
+  %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 2, i32 2>)
+  ret <2 x float> %call
+}
+
+define <3 x float> @test_pown_v3f32__y_2(<3 x float> %x) {
+; CHECK-LABEL: define <3 x float> @test_pown_v3f32__y_2
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul <3 x float> [[X]], [[X]]
+; CHECK-NEXT:    ret <3 x float> [[__POW2]]
+;
+entry:
+  %call = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> %x, <3 x i32> <i32 2, i32 2, i32 2>)
+  ret <3 x float> %call
+}
+
+define <3 x float> @test_pown_v3f32__y_2_undef(<3 x float> %x) {
+; CHECK-LABEL: define <3 x float> @test_pown_v3f32__y_2_undef
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> [[X]], <3 x i32> <i32 2, i32 poison, i32 2>)
+; CHECK-NEXT:    ret <3 x float> [[CALL]]
+;
+entry:
+  %call = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> %x, <3 x i32> <i32 2, i32 poison, i32 2>)
+  ret <3 x float> %call
+}
+
+define <4 x float> @test_pown_v4f32__y_2(<4 x float> %x) {
+; CHECK-LABEL: define <4 x float> @test_pown_v4f32__y_2
+; CHECK-SAME: (<4 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul <4 x float> [[X]], [[X]]
+; CHECK-NEXT:    ret <4 x float> [[__POW2]]
+;
+entry:
+  %call = tail call <4 x float> @_Z4pownDv4_fDv4_i(<4 x float> %x, <4 x i32> <i32 2, i32 2, i32 2, i32 2>)
+  ret <4 x float> %call
+}
+
+define <8 x float> @test_pown_v8f32__y_2(<8 x float> %x) {
+; CHECK-LABEL: define <8 x float> @test_pown_v8f32__y_2
+; CHECK-SAME: (<8 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul <8 x float> [[X]], [[X]]
+; CHECK-NEXT:    ret <8 x float> [[__POW2]]
+;
+entry:
+  %call = tail call <8 x float> @_Z4pownDv8_fDv8_i(<8 x float> %x, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>)
+  ret <8 x float> %call
+}
+
+define <16 x float> @test_pown_v26f32__y_2(<16 x float> %x) {
+; CHECK-LABEL: define <16 x float> @test_pown_v26f32__y_2
+; CHECK-SAME: (<16 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul <16 x float> [[X]], [[X]]
+; CHECK-NEXT:    ret <16 x float> [[__POW2]]
+;
+entry:
+  %call = tail call <16 x float> @_Z4pownDv16_fDv16_i(<16 x float> %x, <16 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>)
+  ret <16 x float> %call
+}
+
+define float @test_pown_f32__y_neg1(float %x) {
+; CHECK-LABEL: define float @test_pown_f32__y_neg1
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv float 1.000000e+00, [[X]]
+; CHECK-NEXT:    ret float [[__POWRECIP]]
+;
+entry:
+  %call = tail call float @_Z4pownfi(float %x, i32 -1)
+  ret float %call
+}
+
+define <2 x float> @test_pown_v2f32__y_neg1(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_v2f32__y_neg1
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POWRECIP]]
+;
+entry:
+  %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 -1, i32 -1>)
+  ret <2 x float> %call
+}
+
+define <3 x float> @test_pown_v3f32__y_neg1(<3 x float> %x) {
+; CHECK-LABEL: define <3 x float> @test_pown_v3f32__y_neg1
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv <3 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, [[X]]
+; CHECK-NEXT:    ret <3 x float> [[__POWRECIP]]
+;
+entry:
+  %call = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> %x, <3 x i32> <i32 -1, i32 -1, i32 -1>)
+  ret <3 x float> %call
+}
+
+define <3 x float> @test_pown_v3f32__y_neg1_undef(<3 x float> %x) {
+; CHECK-LABEL: define <3 x float> @test_pown_v3f32__y_neg1_undef
+; CHECK-SAME: (<3 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> [[X]], <3 x i32> <i32 -1, i32 -1, i32 poison>)
+; CHECK-NEXT:    ret <3 x float> [[CALL]]
+;
+entry:
+  %call = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> %x, <3 x i32> <i32 -1, i32 -1, i32 poison>)
+  ret <3 x float> %call
+}
+
+define <4 x float> @test_pown_v4f32__y_neg1(<4 x float> %x) {
+; CHECK-LABEL: define <4 x float> @test_pown_v4f32__y_neg1
+; CHECK-SAME: (<4 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, [[X]]
+; CHECK-NEXT:    ret <4 x float> [[__POWRECIP]]
+;
+entry:
+  %call = tail call <4 x float> @_Z4pownDv4_fDv4_i(<4 x float> %x, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>)
+  ret <4 x float> %call
+}
+
+define <8 x float> @test_pown_v8f32__y_neg1(<8 x float> %x) {
+; CHECK-LABEL: define <8 x float> @test_pown_v8f32__y_neg1
+; CHECK-SAME: (<8 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv <8 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, [[X]]
+; CHECK-NEXT:    ret <8 x float> [[__POWRECIP]]
+;
+entry:
+  %call = tail call <8 x float> @_Z4pownDv8_fDv8_i(<8 x float> %x, <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>)
+  ret <8 x float> %call
+}
+
+define <16 x float> @test_pown_v16f32__y_neg1(<16 x float> %x) {
+; CHECK-LABEL: define <16 x float> @test_pown_v16f32__y_neg1
+; CHECK-SAME: (<16 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv <16 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, [[X]]
+; CHECK-NEXT:    ret <16 x float> [[__POWRECIP]]
+;
+entry:
+  %call = tail call <16 x float> @_Z4pownDv16_fDv16_i(<16 x float> %x, <16 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>)
+  ret <16 x float> %call
+}
+
+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]]
+;
+entry:
+  %call = tail call afn float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+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]]
+;
+entry:
+  %call = tail call afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> %y)
+  ret <2 x float> %call
+}
+
+define double @test_pown_afn_f64(double %x, i32 %y) {
+; CHECK-LABEL: define double @test_pown_afn_f64
+; CHECK-SAME: (double [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call afn double @_Z4powndi(double [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret double [[CALL]]
+;
+entry:
+  %call = tail call afn double @_Z4powndi(double %x, i32 %y)
+  ret double %call
+}
+
+define <2 x double> @test_pown_afn_v2f64(<2 x double> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x double> @test_pown_afn_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call afn <2 x double> @_Z4pownDv2_dDv2_i(<2 x double> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[CALL]]
+;
+entry:
+  %call = tail call afn <2 x double> @_Z4pownDv2_dDv2_i(<2 x double> %x, <2 x i32> %y)
+  ret <2 x double> %call
+}
+
+define half @test_pown_afn_f16(half %x, i32 %y) {
+; CHECK-LABEL: define half @test_pown_afn_f16
+; CHECK-SAME: (half [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call afn half @_Z4pownDhi(half [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret half [[CALL]]
+;
+entry:
+  %call = tail call afn half @_Z4pownDhi(half %x, i32 %y)
+  ret half %call
+}
+
+define <2 x half> @test_pown_afn_v2f16(<2 x half> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x half> @test_pown_afn_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call afn <2 x half> @_Z4pownDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[CALL]]
+;
+entry:
+  %call = tail call afn <2 x half> @_Z4pownDv2_DhDv2_i(<2 x half> %x, <2 x i32> %y)
+  ret <2 x half> %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret float [[CALL]]
+;
+entry:
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define <2 x float> @test_pown_afn_nnan_ninf_v2f32(<2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32
+; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> %y)
+  ret <2 x float> %call
+}
+
+define double @test_pown_afn_nnan_ninf_f64(double %x, i32 %y) {
+; CHECK-LABEL: define double @test_pown_afn_nnan_ninf_f64
+; CHECK-SAME: (double [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn double @_Z4powndi(double [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret double [[CALL]]
+;
+entry:
+  %call = tail call nnan ninf afn double @_Z4powndi(double %x, i32 %y)
+  ret double %call
+}
+
+define <2 x double> @test_pown_afn_nnan_ninf_v2f64(<2 x double> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x double> @test_pown_afn_nnan_ninf_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x double> @_Z4pownDv2_dDv2_i(<2 x double> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[CALL]]
+;
+entry:
+  %call = tail call nnan ninf afn <2 x double> @_Z4pownDv2_dDv2_i(<2 x double> %x, <2 x i32> %y)
+  ret <2 x double> %call
+}
+
+define half @test_pown_afn_nnan_ninf_f16(half %x, i32 %y) {
+; CHECK-LABEL: define half @test_pown_afn_nnan_ninf_f16
+; CHECK-SAME: (half [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn half @_Z4pownDhi(half [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret half [[CALL]]
+;
+entry:
+  %call = tail call nnan ninf afn half @_Z4pownDhi(half %x, i32 %y)
+  ret half %call
+}
+
+define <2 x half> @test_pown_afn_nnan_ninf_v2f16(<2 x half> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x half> @test_pown_afn_nnan_ninf_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x half> @_Z4pownDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[CALL]]
+;
+entry:
+  %call = tail call nnan ninf afn <2 x half> @_Z4pownDv2_DhDv2_i(<2 x half> %x, <2 x i32> %y)
+  ret <2 x half> %call
+}
+
+define float @test_pown_fast_f32_nobuiltin(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_pown_fast_f32_nobuiltin
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call fast float @_Z4pownfi(float [[X]], i32 [[Y]]) #[[ATTR3:[0-9]+]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+entry:
+  %call = tail call fast float @_Z4pownfi(float %x, i32 %y) #0
+  ret float %call
+}
+
+define float @test_pown_fast_f32_strictfp(float %x, i32 %y) #1 {
+; CHECK-LABEL: define float @test_pown_fast_f32_strictfp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[__FABS:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call fast float @_Z4log2f(float [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul fast float [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call fast float @_Z4exp2f(float [[__YLOGX]])
+; CHECK-NEXT:    [[__YEVEN:%.*]] = shl i32 [[Y]], 31
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast float [[X]] to i32
+; CHECK-NEXT:    [[__POW_SIGN:%.*]] = and i32 [[__YEVEN]], [[TMP0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[__EXP2]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[__POW_SIGN]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32 [[TMP2]] to float
+; CHECK-NEXT:    ret float [[TMP3]]
+;
+entry:
+  %call = tail call fast float @_Z4pownfi(float %x, i32 %y) #1
+  ret float %call
+}
+
+define float @test_pown_fast_f32__y_poison(float %x) {
+; CHECK-LABEL: define float @test_pown_fast_f32__y_poison
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__FABS:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call fast float @_Z4log2f(float [[__FABS]])
+; CHECK-NEXT:    [[__EXP2:%.*]] = call fast float @_Z4exp2f(float poison)
+; CHECK-NEXT:    ret float poison
+;
+  %call = tail call fast float @_Z4pownfi(float %x, i32 poison)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_3(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_3
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 3)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 3)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_neg3(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg3
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -3)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -3)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_4(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_4
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 4)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 4)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_neg4(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg4
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -4)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -4)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_5(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 5)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 5)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_neg5(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -5)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -5)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_7(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_7
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 7)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 7)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_neg7(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg7
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -7)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -7)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_8(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_8
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 8)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 8)
+  ret float %call
+}
+
+define float @test_pown_afn_nnan_ninf_f32__y_neg8(float %x) {
+; CHECK-LABEL: define float @test_pown_afn_nnan_ninf_f32__y_neg8
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 -8)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -8)
+  ret float %call
+}
+
+define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_3(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_3
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 3, i32 3>)
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 3, i32 3>)
+  ret <2 x float> %call
+}
+
+define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_4(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_4
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 4, i32 4>)
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 4, i32 4>)
+  ret <2 x float> %call
+}
+
+define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_neg3(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_neg3
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 -3, i32 -3>)
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 -3, i32 -3>)
+  ret <2 x float> %call
+}
+
+define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_neg4(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_neg4
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 -4, i32 -4>)
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 -4, i32 -4>)
+  ret <2 x float> %call
+}
+
+define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_5(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_pown_afn_nnan_ninf_v2f32__y_5
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 5, i32 5>)
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+entry:
+  %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> <i32 5, i32 5>)
+  ret <2 x float> %call
+}
+
+define float @test_pown_f32__x_known_positive(float nofpclass(ninf nsub nnorm) %x, i32 %y) {
+; CHECK-LABEL: define float @test_pown_f32__x_known_positive
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z4pownfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret float [[CALL]]
+;
+entry:
+  %call = tail call float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define float @test_pown_afn_f32__x_known_positive(float nofpclass(ninf nsub nnorm) %x, i32 %y) {
+; 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]]
+;
+entry:
+  %call = tail call afn float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define float @test_pown_afn_ninf_nnan_f32__x_known_positive(float nofpclass(ninf nsub nnorm) %x, i32 %y) {
+; CHECK-LABEL: define float @test_pown_afn_ninf_nnan_f32__x_known_positive
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call nnan ninf afn float @_Z4pownfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret float [[CALL]]
+;
+entry:
+  %call = tail call afn ninf nnan float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define float @test_pown_afn_f32__x_known_positive__y_4(float nofpclass(ninf nsub nnorm) %x) {
+; 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]]
+;
+entry:
+  %call = tail call afn float @_Z4pownfi(float %x, i32 4)
+  ret float %call
+}
+
+define float @test_pown_f32__x_known_positive__y_4(float nofpclass(ninf nsub nnorm) %x) {
+; CHECK-LABEL: define float @test_pown_f32__x_known_positive__y_4
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z4pownfi(float [[X]], i32 4)
+; CHECK-NEXT:    ret float [[CALL]]
+;
+entry:
+  %call = tail call float @_Z4pownfi(float %x, i32 4)
+  ret float %call
+}
+
+define float @test_pown_f32_y_known_even(float %x, i32 %y.arg) {
+; CHECK-LABEL: define float @test_pown_f32_y_known_even
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y_ARG:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[Y_ARG]], 1
+; CHECK-NEXT:    [[CALL:%.*]] = tail call float @_Z4pownfi(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    ret float [[CALL]]
+;
+entry:
+  %y = shl i32 %y.arg, 1
+  %call = tail call float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define float @test_fast_pown_f32_y_known_even(float %x, i32 %y.arg) {
+; CHECK-LABEL: define float @test_fast_pown_f32_y_known_even
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y_ARG:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[Y_ARG]], 1
+; CHECK-NEXT:    [[__FABS:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call fast float @_Z4log2f(float [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul fast float [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call fast float @_Z4exp2f(float [[__YLOGX]])
+; CHECK-NEXT:    ret float [[__EXP2]]
+;
+entry:
+  %y = shl i32 %y.arg, 1
+  %call = tail call fast float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+define float @test_fast_pown_f32_known_positive_y_known_even(float nofpclass(ninf nsub nnorm) %x, i32 %y.arg) {
+; CHECK-LABEL: define float @test_fast_pown_f32_known_positive_y_known_even
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y_ARG:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[Y_ARG]], 1
+; CHECK-NEXT:    [[__FABS:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[__LOG2:%.*]] = call fast float @_Z4log2f(float [[__FABS]])
+; CHECK-NEXT:    [[POWNI2F:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul fast float [[__LOG2]], [[POWNI2F]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call fast float @_Z4exp2f(float [[__YLOGX]])
+; CHECK-NEXT:    ret float [[__EXP2]]
+;
+entry:
+  %y = shl i32 %y.arg, 1
+  %call = tail call fast float @_Z4pownfi(float %x, i32 %y)
+  ret float %call
+}
+
+attributes #0 = { nobuiltin }
+attributes #1 = { strictfp }

diff  --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll
new file mode 100644
index 00000000000000..9c136c946ab92f
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-powr.ll
@@ -0,0 +1,1206 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=amdgpu-simplifylib,instcombine -amdgpu-prelink %s | FileCheck %s
+
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8"
+
+declare float @_Z4powrff(float, float)
+declare <2 x float> @_Z4powrDv2_fS_(<2 x float>, <2 x float>)
+declare <3 x float> @_Z4powrDv3_fS_(<3 x float>, <3 x float>)
+declare <4 x float> @_Z4powrDv4_fS_(<4 x float>, <4 x float>)
+declare <8 x float> @_Z4powrDv8_fS_(<8 x float>, <8 x float>)
+declare <16 x float> @_Z4powrDv16_fS_(<16 x float>, <16 x float>)
+declare double @_Z4powrdd(double, double)
+declare <2 x double> @_Z4powrDv2_dS_(<2 x double>, <2 x double>)
+declare <3 x double> @_Z4powrDv3_dS_(<3 x double>, <3 x double>)
+declare <4 x double> @_Z4powrDv4_dS_(<4 x double>, <4 x double>)
+declare <8 x double> @_Z4powrDv8_dS_(<8 x double>, <8 x double>)
+declare <16 x double> @_Z4powrDv16_dS_(<16 x double>, <16 x double>)
+declare half @_Z4powrDhDh(half, half)
+declare <2 x half> @_Z4powrDv2_DhS_(<2 x half>, <2 x half>)
+declare <3 x half> @_Z4powrDv3_DhS_(<3 x half>, <3 x half>)
+declare <4 x half> @_Z4powrDv4_DhS_(<4 x half>, <4 x half>)
+declare <8 x half> @_Z4powrDv8_DhS_(<8 x half>, <8 x half>)
+declare <16 x half> @_Z4powrDv16_DhS_(<16 x half>, <16 x half>)
+
+define float @test_powr_fast_f32(float %x, float %y) {
+; CHECK-LABEL: define float @test_powr_fast_f32
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[__LOG2:%.*]] = call fast float @_Z4log2f(float [[X]])
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul fast float [[__LOG2]], [[Y]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call fast float @_Z4exp2f(float [[__YLOGX]])
+; CHECK-NEXT:    ret float [[__EXP2]]
+;
+  %powr = tail call fast float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+define <2 x float> @test_powr_fast_v2f32(<2 x float> %x, <2 x float> %y) {
+; CHECK-LABEL: define <2 x float> @test_powr_fast_v2f32
+; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[__LOG2:%.*]] = call fast <2 x float> @_Z4log2Dv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    [[__YLOGX:%.*]] = fmul fast <2 x float> [[__LOG2]], [[Y]]
+; CHECK-NEXT:    [[__EXP2:%.*]] = call fast <2 x float> @_Z4exp2Dv2_f(<2 x float> [[__YLOGX]])
+; CHECK-NEXT:    ret <2 x float> [[__EXP2]]
+;
+  %powr = tail call fast <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %powr
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn nnan float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %powr
+}
+
+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]]
+;
+  %powr = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> %y)
+  ret <3 x float> %powr
+}
+
+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]]
+;
+  %powr = tail call afn <4 x float> @_Z4powrDv4_fS_(<4 x float> %x, <4 x float> %y)
+  ret <4 x float> %powr
+}
+
+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]]
+;
+  %powr = tail call afn <8 x float> @_Z4powrDv8_fS_(<8 x float> %x, <8 x float> %y)
+  ret <8 x float> %powr
+}
+
+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]]
+;
+  %powr = tail call afn <16 x float> @_Z4powrDv16_fS_(<16 x float> %x, <16 x float> %y)
+  ret <16 x float> %powr
+}
+
+define double @test_powr_afn_f64(double %x, double %y) {
+; CHECK-LABEL: define double @test_powr_afn_f64
+; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn double @_Z4powrdd(double [[X]], double [[Y]])
+; CHECK-NEXT:    ret double [[POWR]]
+;
+  %powr = tail call afn double @_Z4powrdd(double %x, double %y)
+  ret double %powr
+}
+
+define <2 x double> @test_powr_afn_v2f64(<2 x double> %x, <2 x double> %y) {
+; CHECK-LABEL: define <2 x double> @test_powr_afn_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]], <2 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x double> @_Z4powrDv2_dS_(<2 x double> [[X]], <2 x double> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[POWR]]
+;
+  %powr = tail call afn <2 x double> @_Z4powrDv2_dS_(<2 x double> %x, <2 x double> %y)
+  ret <2 x double> %powr
+}
+
+define <3 x double> @test_powr_afn_v3f64(<3 x double> %x, <3 x double> %y) {
+; CHECK-LABEL: define <3 x double> @test_powr_afn_v3f64
+; CHECK-SAME: (<3 x double> [[X:%.*]], <3 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <3 x double> @_Z4powrDv3_dS_(<3 x double> [[X]], <3 x double> [[Y]])
+; CHECK-NEXT:    ret <3 x double> [[POWR]]
+;
+  %powr = tail call afn <3 x double> @_Z4powrDv3_dS_(<3 x double> %x, <3 x double> %y)
+  ret <3 x double> %powr
+}
+
+define <4 x double> @test_powr_afn_v4f64(<4 x double> %x, <4 x double> %y) {
+; CHECK-LABEL: define <4 x double> @test_powr_afn_v4f64
+; CHECK-SAME: (<4 x double> [[X:%.*]], <4 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <4 x double> @_Z4powrDv4_dS_(<4 x double> [[X]], <4 x double> [[Y]])
+; CHECK-NEXT:    ret <4 x double> [[POWR]]
+;
+  %powr = tail call afn <4 x double> @_Z4powrDv4_dS_(<4 x double> %x, <4 x double> %y)
+  ret <4 x double> %powr
+}
+
+define <8 x double> @test_powr_afn_v8f64(<8 x double> %x, <8 x double> %y) {
+; CHECK-LABEL: define <8 x double> @test_powr_afn_v8f64
+; CHECK-SAME: (<8 x double> [[X:%.*]], <8 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <8 x double> @_Z4powrDv8_dS_(<8 x double> [[X]], <8 x double> [[Y]])
+; CHECK-NEXT:    ret <8 x double> [[POWR]]
+;
+  %powr = tail call afn <8 x double> @_Z4powrDv8_dS_(<8 x double> %x, <8 x double> %y)
+  ret <8 x double> %powr
+}
+
+define <16 x double> @test_powr_afn_v16f64(<16 x double> %x, <16 x double> %y) {
+; CHECK-LABEL: define <16 x double> @test_powr_afn_v16f64
+; CHECK-SAME: (<16 x double> [[X:%.*]], <16 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <16 x double> @_Z4powrDv16_dS_(<16 x double> [[X]], <16 x double> [[Y]])
+; CHECK-NEXT:    ret <16 x double> [[POWR]]
+;
+  %powr = tail call afn <16 x double> @_Z4powrDv16_dS_(<16 x double> %x, <16 x double> %y)
+  ret <16 x double> %powr
+}
+
+define half @test_powr_afn_f16(half %x, half %y) {
+; CHECK-LABEL: define half @test_powr_afn_f16
+; CHECK-SAME: (half [[X:%.*]], half [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn half @_Z4powrDhDh(half [[X]], half [[Y]])
+; CHECK-NEXT:    ret half [[POWR]]
+;
+  %powr = tail call afn half @_Z4powrDhDh(half %x, half %y)
+  ret half %powr
+}
+
+define <2 x half> @test_powr_afn_v2f16(<2 x half> %x, <2 x half> %y) {
+; CHECK-LABEL: define <2 x half> @test_powr_afn_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]], <2 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <2 x half> @_Z4powrDv2_DhS_(<2 x half> [[X]], <2 x half> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[POWR]]
+;
+  %powr = tail call afn <2 x half> @_Z4powrDv2_DhS_(<2 x half> %x, <2 x half> %y)
+  ret <2 x half> %powr
+}
+
+define <3 x half> @test_powr_afn_v3f16(<3 x half> %x, <3 x half> %y) {
+; CHECK-LABEL: define <3 x half> @test_powr_afn_v3f16
+; CHECK-SAME: (<3 x half> [[X:%.*]], <3 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <3 x half> @_Z4powrDv3_DhS_(<3 x half> [[X]], <3 x half> [[Y]])
+; CHECK-NEXT:    ret <3 x half> [[POWR]]
+;
+  %powr = tail call afn <3 x half> @_Z4powrDv3_DhS_(<3 x half> %x, <3 x half> %y)
+  ret <3 x half> %powr
+}
+
+define <4 x half> @test_powr_afn_v4f16(<4 x half> %x, <4 x half> %y) {
+; CHECK-LABEL: define <4 x half> @test_powr_afn_v4f16
+; CHECK-SAME: (<4 x half> [[X:%.*]], <4 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <4 x half> @_Z4powrDv4_DhS_(<4 x half> [[X]], <4 x half> [[Y]])
+; CHECK-NEXT:    ret <4 x half> [[POWR]]
+;
+  %powr = tail call afn <4 x half> @_Z4powrDv4_DhS_(<4 x half> %x, <4 x half> %y)
+  ret <4 x half> %powr
+}
+
+define <8 x half> @test_powr_afn_v8f16(<8 x half> %x, <8 x half> %y) {
+; CHECK-LABEL: define <8 x half> @test_powr_afn_v8f16
+; CHECK-SAME: (<8 x half> [[X:%.*]], <8 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <8 x half> @_Z4powrDv8_DhS_(<8 x half> [[X]], <8 x half> [[Y]])
+; CHECK-NEXT:    ret <8 x half> [[POWR]]
+;
+  %powr = tail call afn <8 x half> @_Z4powrDv8_DhS_(<8 x half> %x, <8 x half> %y)
+  ret <8 x half> %powr
+}
+
+define <16 x half> @test_powr_afn_v16f16(<16 x half> %x, <16 x half> %y) {
+; CHECK-LABEL: define <16 x half> @test_powr_afn_v16f16
+; CHECK-SAME: (<16 x half> [[X:%.*]], <16 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn <16 x half> @_Z4powrDv16_DhS_(<16 x half> [[X]], <16 x half> [[Y]])
+; CHECK-NEXT:    ret <16 x half> [[POWR]]
+;
+  %powr = tail call afn <16 x half> @_Z4powrDv16_DhS_(<16 x half> %x, <16 x half> %y)
+  ret <16 x half> %powr
+}
+
+define float @test_powr_f32(float %x, float %y) {
+; CHECK-LABEL: define float @test_powr_f32
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call float @_Z4powrff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+define float @test_powr_f32_nnan(float %x, float %y) {
+; CHECK-LABEL: define float @test_powr_f32_nnan
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan float @_Z4powrff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call nnan float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+define <2 x float> @test_powr_v2f32(<2 x float> %x, <2 x float> %y) {
+; CHECK-LABEL: define <2 x float> @test_powr_v2f32
+; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %powr = tail call <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %powr
+}
+
+define <3 x float> @test_powr_v3f32(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_powr_v3f32
+; CHECK-SAME: (<3 x float> [[X:%.*]], <3 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <3 x float> @_Z4powrDv3_fS_(<3 x float> [[X]], <3 x float> [[Y]])
+; CHECK-NEXT:    ret <3 x float> [[POWR]]
+;
+  %powr = tail call <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> %y)
+  ret <3 x float> %powr
+}
+
+define <4 x float> @test_powr_v4f32(<4 x float> %x, <4 x float> %y) {
+; CHECK-LABEL: define <4 x float> @test_powr_v4f32
+; CHECK-SAME: (<4 x float> [[X:%.*]], <4 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <4 x float> @_Z4powrDv4_fS_(<4 x float> [[X]], <4 x float> [[Y]])
+; CHECK-NEXT:    ret <4 x float> [[POWR]]
+;
+  %powr = tail call <4 x float> @_Z4powrDv4_fS_(<4 x float> %x, <4 x float> %y)
+  ret <4 x float> %powr
+}
+
+define <8 x float> @test_powr_v8f32(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: define <8 x float> @test_powr_v8f32
+; CHECK-SAME: (<8 x float> [[X:%.*]], <8 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <8 x float> @_Z4powrDv8_fS_(<8 x float> [[X]], <8 x float> [[Y]])
+; CHECK-NEXT:    ret <8 x float> [[POWR]]
+;
+  %powr = tail call <8 x float> @_Z4powrDv8_fS_(<8 x float> %x, <8 x float> %y)
+  ret <8 x float> %powr
+}
+
+define <16 x float> @test_powr_v16f32(<16 x float> %x, <16 x float> %y) {
+; CHECK-LABEL: define <16 x float> @test_powr_v16f32
+; CHECK-SAME: (<16 x float> [[X:%.*]], <16 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <16 x float> @_Z4powrDv16_fS_(<16 x float> [[X]], <16 x float> [[Y]])
+; CHECK-NEXT:    ret <16 x float> [[POWR]]
+;
+  %powr = tail call <16 x float> @_Z4powrDv16_fS_(<16 x float> %x, <16 x float> %y)
+  ret <16 x float> %powr
+}
+
+define double @test_powr_f64(double %x, double %y) {
+; CHECK-LABEL: define double @test_powr_f64
+; CHECK-SAME: (double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call double @_Z4powrdd(double [[X]], double [[Y]])
+; CHECK-NEXT:    ret double [[POWR]]
+;
+  %powr = tail call double @_Z4powrdd(double %x, double %y)
+  ret double %powr
+}
+
+define <2 x double> @test_powr_v2f64(<2 x double> %x, <2 x double> %y) {
+; CHECK-LABEL: define <2 x double> @test_powr_v2f64
+; CHECK-SAME: (<2 x double> [[X:%.*]], <2 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <2 x double> @_Z4powrDv2_dS_(<2 x double> [[X]], <2 x double> [[Y]])
+; CHECK-NEXT:    ret <2 x double> [[POWR]]
+;
+  %powr = tail call <2 x double> @_Z4powrDv2_dS_(<2 x double> %x, <2 x double> %y)
+  ret <2 x double> %powr
+}
+
+define <3 x double> @test_powr_v3f64(<3 x double> %x, <3 x double> %y) {
+; CHECK-LABEL: define <3 x double> @test_powr_v3f64
+; CHECK-SAME: (<3 x double> [[X:%.*]], <3 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <3 x double> @_Z4powrDv3_dS_(<3 x double> [[X]], <3 x double> [[Y]])
+; CHECK-NEXT:    ret <3 x double> [[POWR]]
+;
+  %powr = tail call <3 x double> @_Z4powrDv3_dS_(<3 x double> %x, <3 x double> %y)
+  ret <3 x double> %powr
+}
+
+define <4 x double> @test_powr_v4f64(<4 x double> %x, <4 x double> %y) {
+; CHECK-LABEL: define <4 x double> @test_powr_v4f64
+; CHECK-SAME: (<4 x double> [[X:%.*]], <4 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <4 x double> @_Z4powrDv4_dS_(<4 x double> [[X]], <4 x double> [[Y]])
+; CHECK-NEXT:    ret <4 x double> [[POWR]]
+;
+  %powr = tail call <4 x double> @_Z4powrDv4_dS_(<4 x double> %x, <4 x double> %y)
+  ret <4 x double> %powr
+}
+
+define <8 x double> @test_powr_v8f64(<8 x double> %x, <8 x double> %y) {
+; CHECK-LABEL: define <8 x double> @test_powr_v8f64
+; CHECK-SAME: (<8 x double> [[X:%.*]], <8 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <8 x double> @_Z4powrDv8_dS_(<8 x double> [[X]], <8 x double> [[Y]])
+; CHECK-NEXT:    ret <8 x double> [[POWR]]
+;
+  %powr = tail call <8 x double> @_Z4powrDv8_dS_(<8 x double> %x, <8 x double> %y)
+  ret <8 x double> %powr
+}
+
+define <16 x double> @test_powr_v16f64(<16 x double> %x, <16 x double> %y) {
+; CHECK-LABEL: define <16 x double> @test_powr_v16f64
+; CHECK-SAME: (<16 x double> [[X:%.*]], <16 x double> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <16 x double> @_Z4powrDv16_dS_(<16 x double> [[X]], <16 x double> [[Y]])
+; CHECK-NEXT:    ret <16 x double> [[POWR]]
+;
+  %powr = tail call <16 x double> @_Z4powrDv16_dS_(<16 x double> %x, <16 x double> %y)
+  ret <16 x double> %powr
+}
+
+define half @test_powr_f16(half %x, half %y) {
+; CHECK-LABEL: define half @test_powr_f16
+; CHECK-SAME: (half [[X:%.*]], half [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call half @_Z4powrDhDh(half [[X]], half [[Y]])
+; CHECK-NEXT:    ret half [[POWR]]
+;
+  %powr = tail call half @_Z4powrDhDh(half %x, half %y)
+  ret half %powr
+}
+
+define <2 x half> @test_powr_v2f16(<2 x half> %x, <2 x half> %y) {
+; CHECK-LABEL: define <2 x half> @test_powr_v2f16
+; CHECK-SAME: (<2 x half> [[X:%.*]], <2 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <2 x half> @_Z4powrDv2_DhS_(<2 x half> [[X]], <2 x half> [[Y]])
+; CHECK-NEXT:    ret <2 x half> [[POWR]]
+;
+  %powr = tail call <2 x half> @_Z4powrDv2_DhS_(<2 x half> %x, <2 x half> %y)
+  ret <2 x half> %powr
+}
+
+define <3 x half> @test_powr_v3f16(<3 x half> %x, <3 x half> %y) {
+; CHECK-LABEL: define <3 x half> @test_powr_v3f16
+; CHECK-SAME: (<3 x half> [[X:%.*]], <3 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <3 x half> @_Z4powrDv3_DhS_(<3 x half> [[X]], <3 x half> [[Y]])
+; CHECK-NEXT:    ret <3 x half> [[POWR]]
+;
+  %powr = tail call <3 x half> @_Z4powrDv3_DhS_(<3 x half> %x, <3 x half> %y)
+  ret <3 x half> %powr
+}
+
+define <4 x half> @test_powr_v4f16(<4 x half> %x, <4 x half> %y) {
+; CHECK-LABEL: define <4 x half> @test_powr_v4f16
+; CHECK-SAME: (<4 x half> [[X:%.*]], <4 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <4 x half> @_Z4powrDv4_DhS_(<4 x half> [[X]], <4 x half> [[Y]])
+; CHECK-NEXT:    ret <4 x half> [[POWR]]
+;
+  %powr = tail call <4 x half> @_Z4powrDv4_DhS_(<4 x half> %x, <4 x half> %y)
+  ret <4 x half> %powr
+}
+
+define <8 x half> @test_powr_v8f16(<8 x half> %x, <8 x half> %y) {
+; CHECK-LABEL: define <8 x half> @test_powr_v8f16
+; CHECK-SAME: (<8 x half> [[X:%.*]], <8 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <8 x half> @_Z4powrDv8_DhS_(<8 x half> [[X]], <8 x half> [[Y]])
+; CHECK-NEXT:    ret <8 x half> [[POWR]]
+;
+  %powr = tail call <8 x half> @_Z4powrDv8_DhS_(<8 x half> %x, <8 x half> %y)
+  ret <8 x half> %powr
+}
+
+define <16 x half> @test_powr_v16f16(<16 x half> %x, <16 x half> %y) {
+; CHECK-LABEL: define <16 x half> @test_powr_v16f16
+; CHECK-SAME: (<16 x half> [[X:%.*]], <16 x half> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <16 x half> @_Z4powrDv16_DhS_(<16 x half> [[X]], <16 x half> [[Y]])
+; CHECK-NEXT:    ret <16 x half> [[POWR]]
+;
+  %powr = tail call <16 x half> @_Z4powrDv16_DhS_(<16 x half> %x, <16 x half> %y)
+  ret <16 x half> %powr
+}
+
+define float @test_powr_afn_f32_minsize(float %x, float %y) #0 {
+; CHECK-LABEL: define float @test_powr_afn_f32_minsize
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+define float @test_powr_afn_f32_nnan_minsize(float %x, float %y) #0 {
+; CHECK-LABEL: define float @test_powr_afn_f32_nnan_minsize
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan afn float @_Z4powrff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call afn nnan float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+define float @test_powr_afn_f32_noinline(float %x, float %y) {
+; CHECK-LABEL: define float @test_powr_afn_f32_noinline
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call afn float @_Z4powrff(float [[X]], float [[Y]]) #[[ATTR3:[0-9]+]]
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float %y) #1
+  ret float %powr
+}
+
+define float @test_powr_afn_f32_nnan_noinline(float %x, float %y) {
+; CHECK-LABEL: define float @test_powr_afn_f32_nnan_noinline
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan afn float @_Z4powrff(float [[X]], float [[Y]]) #[[ATTR3]]
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call afn nnan float @_Z4powrff(float %x, float %y) #1
+  ret float %powr
+}
+
+define float @test_powr_afn_f32_strictfp(float %x, float %y) #2 {
+; CHECK-LABEL: define float @test_powr_afn_f32_strictfp
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan nsz afn float @_Z4powrff(float [[X]], float [[Y]]) #[[ATTR1]]
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call afn nsz nnan float @_Z4powrff(float %x, float %y) #2
+  ret float %powr
+}
+
+define float @test_powr_fast_f32_nobuiltin(float %x, float %y) {
+; CHECK-LABEL: define float @test_powr_fast_f32_nobuiltin
+; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call fast float @_Z4powrff(float [[X]], float [[Y]]) #[[ATTR4:[0-9]+]]
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call fast float @_Z4powrff(float %x, float %y) #3
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float poison)
+  ret float %powr
+}
+
+define float @test_powr_afn_f32_0.0(float %x) {
+; CHECK-LABEL: define float @test_powr_afn_f32_0.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 0.0)
+  ret float %powr
+}
+
+define float @test_powr_afn_f32_neg0.0(float %x) {
+; CHECK-LABEL: define float @test_powr_afn_f32_neg0.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float -0.0)
+  ret float %powr
+}
+
+define <2 x float> @test_powr_afn_v2f32_0.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_0.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
+;
+  %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
+}
+
+define <2 x float> @test_powr_afn_v2f32_neg0.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_neg0.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+define <3 x float> @test_powr_afn_v3f32_0.0_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_powr_afn_v3f32_0.0_splat_undef
+; 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> <float 0.000000e+00, float poison, float 0.000000e+00>)
+; CHECK-NEXT:    ret <3 x float> [[POWR]]
+;
+  %powr = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> <float 0.0, float poison, float 0.0>)
+  ret <3 x float> %powr
+}
+
+define <3 x float> @test_powr_afn_v3f32_neg0.0_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_powr_afn_v3f32_neg0.0_splat_undef
+; 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> <float -0.000000e+00, float poison, float -0.000000e+00>)
+; CHECK-NEXT:    ret <3 x float> [[POWR]]
+;
+  %powr = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> <float -0.0, float poison, float -0.0>)
+  ret <3 x float> %powr
+}
+
+define float @test_powr_afn_f32_0.5(float %x) {
+; CHECK-LABEL: define float @test_powr_afn_f32_0.5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2SQRT:%.*]] = call afn float @_Z4sqrtf(float [[X]])
+; CHECK-NEXT:    ret float [[__POW2SQRT]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 0.5)
+  ret float %powr
+}
+
+define float @test_powr_afn_f32_neg0.5(float %x) {
+; CHECK-LABEL: define float @test_powr_afn_f32_neg0.5
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2RSQRT:%.*]] = call afn float @_Z5rsqrtf(float [[X]])
+; CHECK-NEXT:    ret float [[__POW2RSQRT]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float -0.5)
+  ret float %powr
+}
+
+define <2 x float> @test_powr_afn_v2f32_0.5(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_0.5
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2SQRT:%.*]] = call afn <2 x float> @_Z4sqrtDv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    ret <2 x float> [[__POW2SQRT]]
+;
+  %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
+}
+
+define <2 x float> @test_powr_afn_v2f32_neg0.5(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_neg0.5
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2RSQRT:%.*]] = call afn <2 x float> @_Z5rsqrtDv2_f(<2 x float> [[X]])
+; CHECK-NEXT:    ret <2 x float> [[__POW2RSQRT]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+define <3 x float> @test_powr_afn_v3f32_0.5_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_powr_afn_v3f32_0.5_splat_undef
+; 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> <float 5.000000e-01, float poison, float 5.000000e-01>)
+; CHECK-NEXT:    ret <3 x float> [[POWR]]
+;
+  %powr = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> <float 0.5, float poison, float 0.5>)
+  ret <3 x float> %powr
+}
+
+define <3 x float> @test_powr_afn_v3f32_neg0.5_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_powr_afn_v3f32_neg0.5_splat_undef
+; 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> <float -5.000000e-01, float poison, float -5.000000e-01>)
+; CHECK-NEXT:    ret <3 x float> [[POWR]]
+;
+  %powr = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> <float -0.5, float poison, float -0.5>)
+  ret <3 x float> %powr
+}
+
+define float @test_powr_afn_f32_1.0(float %x) {
+; CHECK-LABEL: define float @test_powr_afn_f32_1.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    ret float [[X]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 1.0)
+  ret float %powr
+}
+
+define float @test_powr_afn_f32_neg1.0(float %x) {
+; CHECK-LABEL: define float @test_powr_afn_f32_neg1.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv afn float 1.000000e+00, [[X]]
+; CHECK-NEXT:    ret float [[__POWRECIP]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float -1.0)
+  ret float %powr
+}
+
+define <2 x float> @test_powr_afn_v2f32_1.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_1.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    ret <2 x float> [[X]]
+;
+  %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
+}
+
+define <2 x float> @test_powr_afn_v2f32_neg1.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_neg1.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POWRECIP:%.*]] = fdiv afn <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POWRECIP]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+define <3 x float> @test_powr_afn_v3f32_1.0_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_powr_afn_v3f32_1.0_splat_undef
+; 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> <float 1.000000e+00, float poison, float 1.000000e+00>)
+; CHECK-NEXT:    ret <3 x float> [[POWR]]
+;
+  %powr = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> <float 1.0, float poison, float 1.0>)
+  ret <3 x float> %powr
+}
+
+define <3 x float> @test_powr_afn_v3f32_neg1.0_splat_undef(<3 x float> %x, <3 x float> %y) {
+; CHECK-LABEL: define <3 x float> @test_powr_afn_v3f32_neg1.0_splat_undef
+; 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> <float -1.000000e+00, float poison, float -1.000000e+00>)
+; CHECK-NEXT:    ret <3 x float> [[POWR]]
+;
+  %powr = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> <float -1.0, float poison, float -1.0>)
+  ret <3 x float> %powr
+}
+
+define float @test_powr_afn_f32_2.0(float %x) {
+; CHECK-LABEL: define float @test_powr_afn_f32_2.0
+; CHECK-SAME: (float [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul afn float [[X]], [[X]]
+; CHECK-NEXT:    ret float [[__POW2]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 2.0)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float -2.0)
+  ret float %powr
+}
+
+define <2 x float> @test_powr_afn_v2f32_2.0(<2 x float> %x) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_2.0
+; CHECK-SAME: (<2 x float> [[X:%.*]]) {
+; CHECK-NEXT:    [[__POW2:%.*]] = fmul afn <2 x float> [[X]], [[X]]
+; CHECK-NEXT:    ret <2 x float> [[__POW2]]
+;
+  %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
+}
+
+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> <float -2.000000e+00, float -2.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 3.0)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float -3.0)
+  ret float %powr
+}
+
+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> <float 3.000000e+00, float 3.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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> <float -3.000000e+00, float -3.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 0x400FEB8520000000)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 0xC00FEB8520000000)
+  ret float %powr
+}
+
+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> <float 0x400FEB8520000000, float 0x400FEB8520000000>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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> <float 0xC00FEB8520000000, float 0xC00FEB8520000000>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 8.0)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float -8.0)
+  ret float %powr
+}
+
+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> <float 8.000000e+00, float 8.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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> <float -8.000000e+00, float -8.000000e+00>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 12.0)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float -12.0)
+  ret float %powr
+}
+
+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> <float 1.200000e+01, float 1.200000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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> <float -1.200000e+01, float -1.200000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float 13.0)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float -13.0)
+  ret float %powr
+}
+
+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> <float 1.300000e+01, float 1.300000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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> <float -1.300000e+01, float -1.300000e+01>)
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %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
+}
+
+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]]
+;
+  %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
+}
+
+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]]
+;
+  %powr = tail call afn nnan float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+define float @test_powr_afn_f32_nnan_ninf_x_known_positive(float nofpclass(ninf nnorm nsub) %x, float %y) {
+; CHECK-LABEL: define float @test_powr_afn_f32_nnan_ninf_x_known_positive
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn float @_Z4powrff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call afn nnan ninf float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn nnan <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %powr
+}
+
+define <2 x float> @test_powr_afn_v2f32_nnan_ninf_x_known_positive(<2 x float> nofpclass(ninf nnorm nsub) %x, <2 x float> %y) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32_nnan_ninf_x_known_positive
+; CHECK-SAME: (<2 x float> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %powr = tail call afn nnan ninf <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %powr
+}
+
+define float @test_powr_f32_x_known_positive(float nofpclass(ninf nnorm nsub) %x, float %y) {
+; CHECK-LABEL: define float @test_powr_f32_x_known_positive
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call float @_Z4powrff(float [[X]], float [[Y]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %powr = tail call float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+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]]
+;
+  %powr = tail call afn float @_Z4powrff(float %x, float %y)
+  ret float %powr
+}
+
+define <2 x float> @test_powr_v2f32_x_known_positive(<2 x float> nofpclass(ninf nnorm nsub) %x, <2 x float> %y) {
+; CHECK-LABEL: define <2 x float> @test_powr_v2f32_x_known_positive
+; CHECK-SAME: (<2 x float> nofpclass(ninf nsub nnorm) [[X:%.*]], <2 x float> [[Y:%.*]]) {
+; CHECK-NEXT:    [[POWR:%.*]] = tail call <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %powr = tail call <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %powr
+}
+
+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]]
+;
+  %powr = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
+  ret <2 x float> %powr
+}
+
+define float @test_powr_f32_known_integral_sitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_powr_f32_known_integral_sitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POWR:%.*]] = tail call float @_Z4powrff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %y.cast = sitofp i32 %y to float
+  %powr = tail call float @_Z4powrff(float %x, float %y.cast)
+  ret float %powr
+}
+
+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]]
+;
+  %y.cast = sitofp i32 %y to float
+  %powr = tail call afn float @_Z4powrff(float %x, float %y.cast)
+  ret float %powr
+}
+
+define float @test_powr_afn_nnan_ninf_f32_known_integral_sitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_powr_afn_nnan_ninf_f32_known_integral_sitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn float @_Z4powrff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %y.cast = sitofp i32 %y to float
+  %powr = tail call afn nnan ninf float @_Z4powrff(float %x, float %y.cast)
+  ret float %powr
+}
+
+define float @test_powr_f32_known_integral_uitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_powr_f32_known_integral_uitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POWR:%.*]] = tail call float @_Z4powrff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %y.cast = uitofp i32 %y to float
+  %powr = tail call float @_Z4powrff(float %x, float %y.cast)
+  ret float %powr
+}
+
+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]]
+;
+  %y.cast = uitofp i32 %y to float
+  %powr = tail call afn float @_Z4powrff(float %x, float %y.cast)
+  ret float %powr
+}
+
+define float @test_powr_afn_nnan_ninf_f32_known_integral_uitofp(float %x, i32 %y) {
+; CHECK-LABEL: define float @test_powr_afn_nnan_ninf_f32_known_integral_uitofp
+; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp i32 [[Y]] to float
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn float @_Z4powrff(float [[X]], float [[Y_CAST]])
+; CHECK-NEXT:    ret float [[POWR]]
+;
+  %y.cast = uitofp i32 %y to float
+  %powr = tail call afn nnan ninf float @_Z4powrff(float %x, float %y.cast)
+  ret float %powr
+}
+
+define <2 x float> @test_powr_afn_nnan_ninf_v2f32_known_integral_sitofp(<2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_nnan_ninf_v2f32_known_integral_sitofp
+; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = sitofp <2 x i32> [[Y]] to <2 x float>
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %y.cast = sitofp <2 x i32> %y to <2 x float>
+  %powr = tail call afn nnan ninf <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y.cast)
+  ret <2 x float> %powr
+}
+
+define <2 x float> @test_powr_v2f32_known_integral_uitofp(<2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @test_powr_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 <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %y.cast = uitofp <2 x i32> %y to <2 x float>
+  %powr = tail call <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y.cast)
+  ret <2 x float> %powr
+}
+
+define <2 x float> @test_powr_afn_v2f32_known_integral_uitofp(<2 x float> %x, <2 x i32> %y) {
+; 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]]
+;
+  %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)
+  ret <2 x float> %powr
+}
+
+define <2 x float> @test_powr_afn_nnan_ninf_v2f32_known_integral_uitofp(<2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @test_powr_afn_nnan_ninf_v2f32_known_integral_uitofp
+; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:    [[Y_CAST:%.*]] = uitofp <2 x i32> [[Y]] to <2 x float>
+; CHECK-NEXT:    [[POWR:%.*]] = tail call nnan ninf afn <2 x float> @_Z4powrDv2_fS_(<2 x float> [[X]], <2 x float> [[Y_CAST]])
+; CHECK-NEXT:    ret <2 x float> [[POWR]]
+;
+  %y.cast = uitofp <2 x i32> %y to <2 x float>
+  %powr = tail call afn nnan ninf <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y.cast)
+  ret <2 x float> %powr
+}
+
+attributes #0 = { minsize }
+attributes #1 = { noinline }
+attributes #2 = { strictfp }
+attributes #3 = { nobuiltin }


        


More information about the llvm-commits mailing list