; 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 -check-prefixes=CHECK,PRELINK %s ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=amdgpu-simplifylib,instcombine %s | FileCheck -check-prefixes=CHECK,NOPRELINK %s 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> splat (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: ret <2 x float> splat (float 1.000000e+00) ; entry: %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> ) 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> splat (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> splat (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> splat (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> splat (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> ) 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: ret <2 x float> [[X]] ; entry: %call = tail call <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> ) 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> ) 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: ret <3 x float> [[X]] ; entry: %call = tail call <3 x float> @_Z4pownDv3_fDv3_i(<3 x float> %x, <3 x i32> ) 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> ) 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> ) 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> ) 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> ) 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> ) 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: [[__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> ) 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> ) 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> ) 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> ) 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> splat (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> ) 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> splat (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> ) 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: [[__POWRECIP:%.*]] = fdiv <3 x float> splat (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> ) 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> splat (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> ) 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> splat (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> ) 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> splat (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> ) ret <16 x float> %call } define float @test_pown_afn_f32(float %x, i32 %y) { ; PRELINK-LABEL: define float @test_pown_afn_f32 ; PRELINK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) { ; PRELINK-NEXT: entry: ; PRELINK-NEXT: [[CALL:%.*]] = tail call afn float @_Z11__pown_fastfi(float [[X]], i32 [[Y]]) ; PRELINK-NEXT: ret float [[CALL]] ; ; NOPRELINK-LABEL: define float @test_pown_afn_f32 ; NOPRELINK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) { ; NOPRELINK-NEXT: entry: ; NOPRELINK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[Y]], 0 ; NOPRELINK-NEXT: [[TMP1:%.*]] = select afn i1 [[TMP0]], float 1.000000e+00, float [[X]] ; NOPRELINK-NEXT: [[TMP2:%.*]] = sitofp i32 [[Y]] to float ; NOPRELINK-NEXT: [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP1]]) ; NOPRELINK-NEXT: [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]]) ; NOPRELINK-NEXT: [[TMP5:%.*]] = fmul afn float [[TMP4]], [[TMP2]] ; NOPRELINK-NEXT: [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]]) ; NOPRELINK-NEXT: [[TMP7:%.*]] = and i32 [[Y]], 1 ; NOPRELINK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP7]], 0 ; NOPRELINK-NEXT: [[TMP8:%.*]] = select afn i1 [[DOTNOT]], float 1.000000e+00, float [[TMP1]] ; NOPRELINK-NEXT: [[TMP9:%.*]] = call afn float @llvm.copysign.f32(float [[TMP6]], float [[TMP8]]) ; NOPRELINK-NEXT: [[TMP10:%.*]] = call afn float @llvm.fabs.f32(float [[TMP1]]) ; NOPRELINK-NEXT: [[TMP11:%.*]] = fcmp afn oeq float [[TMP10]], +inf ; NOPRELINK-NEXT: [[TMP12:%.*]] = fcmp afn oeq float [[TMP1]], 0.000000e+00 ; NOPRELINK-NEXT: [[TMP13:%.*]] = or i1 [[TMP11]], [[TMP12]] ; NOPRELINK-NEXT: [[TMP14:%.*]] = icmp slt i32 [[Y]], 0 ; NOPRELINK-NEXT: [[TMP15:%.*]] = xor i1 [[TMP12]], [[TMP14]] ; NOPRELINK-NEXT: [[TMP16:%.*]] = select afn i1 [[TMP15]], float 0.000000e+00, float +inf ; NOPRELINK-NEXT: [[TMP17:%.*]] = select afn i1 [[DOTNOT]], float 0.000000e+00, float [[TMP1]] ; NOPRELINK-NEXT: [[TMP18:%.*]] = call afn float @llvm.copysign.f32(float [[TMP16]], float [[TMP17]]) ; NOPRELINK-NEXT: [[TMP19:%.*]] = select afn i1 [[TMP13]], float [[TMP18]], float [[TMP9]] ; NOPRELINK-NEXT: ret float [[TMP19]] ; 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) { ; PRELINK-LABEL: define <2 x float> @test_pown_afn_v2f32 ; PRELINK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) { ; PRELINK-NEXT: entry: ; PRELINK-NEXT: [[CALL:%.*]] = tail call afn <2 x float> @_Z11__pown_fastDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]]) ; PRELINK-NEXT: ret <2 x float> [[CALL]] ; ; NOPRELINK-LABEL: define <2 x float> @test_pown_afn_v2f32 ; NOPRELINK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) { ; NOPRELINK-NEXT: entry: ; NOPRELINK-NEXT: [[TMP0:%.*]] = icmp eq <2 x i32> [[Y]], zeroinitializer ; NOPRELINK-NEXT: [[TMP1:%.*]] = select afn <2 x i1> [[TMP0]], <2 x float> splat (float 1.000000e+00), <2 x float> [[X]] ; NOPRELINK-NEXT: [[TMP2:%.*]] = sitofp <2 x i32> [[Y]] to <2 x float> ; NOPRELINK-NEXT: [[TMP3:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP1]]) ; NOPRELINK-NEXT: [[TMP4:%.*]] = call afn <2 x float> @llvm.log2.v2f32(<2 x float> [[TMP3]]) ; NOPRELINK-NEXT: [[TMP5:%.*]] = fmul afn <2 x float> [[TMP4]], [[TMP2]] ; NOPRELINK-NEXT: [[TMP6:%.*]] = call afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[TMP5]]) ; NOPRELINK-NEXT: [[TMP7:%.*]] = and <2 x i32> [[Y]], splat (i32 1) ; NOPRELINK-NEXT: [[DOTNOT:%.*]] = icmp eq <2 x i32> [[TMP7]], zeroinitializer ; NOPRELINK-NEXT: [[TMP8:%.*]] = select afn <2 x i1> [[DOTNOT]], <2 x float> splat (float 1.000000e+00), <2 x float> [[TMP1]] ; NOPRELINK-NEXT: [[TMP9:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP6]], <2 x float> [[TMP8]]) ; NOPRELINK-NEXT: [[TMP10:%.*]] = call afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP1]]) ; NOPRELINK-NEXT: [[TMP11:%.*]] = fcmp afn oeq <2 x float> [[TMP10]], splat (float +inf) ; NOPRELINK-NEXT: [[TMP12:%.*]] = fcmp afn oeq <2 x float> [[TMP1]], zeroinitializer ; NOPRELINK-NEXT: [[TMP13:%.*]] = or <2 x i1> [[TMP11]], [[TMP12]] ; NOPRELINK-NEXT: [[TMP14:%.*]] = icmp slt <2 x i32> [[Y]], zeroinitializer ; NOPRELINK-NEXT: [[TMP15:%.*]] = xor <2 x i1> [[TMP12]], [[TMP14]] ; NOPRELINK-NEXT: [[TMP16:%.*]] = select afn <2 x i1> [[TMP15]], <2 x float> zeroinitializer, <2 x float> splat (float +inf) ; NOPRELINK-NEXT: [[TMP17:%.*]] = select afn <2 x i1> [[DOTNOT]], <2 x float> zeroinitializer, <2 x float> [[TMP1]] ; NOPRELINK-NEXT: [[TMP18:%.*]] = call afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[TMP16]], <2 x float> [[TMP17]]) ; NOPRELINK-NEXT: [[TMP19:%.*]] = select afn <2 x i1> [[TMP13]], <2 x float> [[TMP18]], <2 x float> [[TMP9]] ; NOPRELINK-NEXT: ret <2 x float> [[TMP19]] ; entry: %call = tail call afn <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> %y) 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: [[__FABS:%.*]] = call nnan ninf afn float @llvm.fabs.f32(float [[X]]) ; CHECK-NEXT: [[__LOG2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[__FABS]]) ; CHECK-NEXT: [[POWNI2F:%.*]] = sitofp i32 [[Y]] to float ; CHECK-NEXT: [[__YLOGX:%.*]] = fmul nnan ninf afn float [[__LOG2]], [[POWNI2F]] ; CHECK-NEXT: [[__EXP2:%.*]] = call nnan ninf afn nofpclass(nan ninf nzero nsub nnorm) float @llvm.exp2.f32(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 i32 [[__POW_SIGN]] to float ; CHECK-NEXT: [[__POW_SIGN1:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[__EXP2]], float [[TMP1]]) ; CHECK-NEXT: ret float [[__POW_SIGN1]] ; 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: [[__FABS:%.*]] = call nnan ninf afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]]) ; CHECK-NEXT: [[__LOG2:%.*]] = call nnan ninf afn <2 x float> @llvm.log2.v2f32(<2 x float> [[__FABS]]) ; CHECK-NEXT: [[POWNI2F:%.*]] = sitofp <2 x i32> [[Y]] to <2 x float> ; CHECK-NEXT: [[__YLOGX:%.*]] = fmul nnan ninf afn <2 x float> [[__LOG2]], [[POWNI2F]] ; CHECK-NEXT: [[__EXP2:%.*]] = call nnan ninf afn nofpclass(nan ninf nzero nsub nnorm) <2 x float> @llvm.exp2.v2f32(<2 x float> [[__YLOGX]]) ; CHECK-NEXT: [[__YEVEN:%.*]] = shl <2 x i32> [[Y]], splat (i32 31) ; CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[X]] to <2 x i32> ; CHECK-NEXT: [[__POW_SIGN:%.*]] = and <2 x i32> [[__YEVEN]], [[TMP0]] ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[__POW_SIGN]] to <2 x float> ; CHECK-NEXT: [[__POW_SIGN1:%.*]] = call nnan ninf afn <2 x float> @llvm.copysign.v2f32(<2 x float> [[__EXP2]], <2 x float> [[TMP1]]) ; CHECK-NEXT: ret <2 x float> [[__POW_SIGN1]] ; 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) { ; PRELINK-LABEL: define double @test_pown_afn_nnan_ninf_f64 ; PRELINK-SAME: (double [[X:%.*]], i32 [[Y:%.*]]) { ; PRELINK-NEXT: entry: ; PRELINK-NEXT: [[__FABS:%.*]] = call nnan ninf afn double @llvm.fabs.f64(double [[X]]) ; PRELINK-NEXT: [[__LOG2:%.*]] = call nnan ninf afn double @_Z4log2d(double [[__FABS]]) ; PRELINK-NEXT: [[POWNI2F:%.*]] = sitofp i32 [[Y]] to double ; PRELINK-NEXT: [[__YLOGX:%.*]] = fmul nnan ninf afn double [[__LOG2]], [[POWNI2F]] ; PRELINK-NEXT: [[__EXP2:%.*]] = call nnan ninf afn nofpclass(nan ninf nzero nsub nnorm) double @_Z4exp2d(double [[__YLOGX]]) ; PRELINK-NEXT: [[__YTOU:%.*]] = zext i32 [[Y]] to i64 ; PRELINK-NEXT: [[__YEVEN:%.*]] = shl i64 [[__YTOU]], 63 ; PRELINK-NEXT: [[TMP0:%.*]] = bitcast double [[X]] to i64 ; PRELINK-NEXT: [[__POW_SIGN:%.*]] = and i64 [[__YEVEN]], [[TMP0]] ; PRELINK-NEXT: [[TMP1:%.*]] = bitcast i64 [[__POW_SIGN]] to double ; PRELINK-NEXT: [[__POW_SIGN1:%.*]] = call nnan ninf afn double @llvm.copysign.f64(double [[__EXP2]], double [[TMP1]]) ; PRELINK-NEXT: ret double [[__POW_SIGN1]] ; ; NOPRELINK-LABEL: define double @test_pown_afn_nnan_ninf_f64 ; NOPRELINK-SAME: (double [[X:%.*]], i32 [[Y:%.*]]) { ; NOPRELINK-NEXT: entry: ; NOPRELINK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn double @_Z4powndi(double [[X]], i32 [[Y]]) ; NOPRELINK-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) { ; PRELINK-LABEL: define <2 x double> @test_pown_afn_nnan_ninf_v2f64 ; PRELINK-SAME: (<2 x double> [[X:%.*]], <2 x i32> [[Y:%.*]]) { ; PRELINK-NEXT: entry: ; PRELINK-NEXT: [[__FABS:%.*]] = call nnan ninf afn <2 x double> @llvm.fabs.v2f64(<2 x double> [[X]]) ; PRELINK-NEXT: [[__LOG2:%.*]] = call nnan ninf afn <2 x double> @_Z4log2Dv2_d(<2 x double> [[__FABS]]) ; PRELINK-NEXT: [[POWNI2F:%.*]] = sitofp <2 x i32> [[Y]] to <2 x double> ; PRELINK-NEXT: [[__YLOGX:%.*]] = fmul nnan ninf afn <2 x double> [[__LOG2]], [[POWNI2F]] ; PRELINK-NEXT: [[__EXP2:%.*]] = call nnan ninf afn nofpclass(nan ninf nzero nsub nnorm) <2 x double> @_Z4exp2Dv2_d(<2 x double> [[__YLOGX]]) ; PRELINK-NEXT: [[__YTOU:%.*]] = zext <2 x i32> [[Y]] to <2 x i64> ; PRELINK-NEXT: [[__YEVEN:%.*]] = shl <2 x i64> [[__YTOU]], splat (i64 63) ; PRELINK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[X]] to <2 x i64> ; PRELINK-NEXT: [[__POW_SIGN:%.*]] = and <2 x i64> [[__YEVEN]], [[TMP0]] ; PRELINK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[__POW_SIGN]] to <2 x double> ; PRELINK-NEXT: [[__POW_SIGN1:%.*]] = call nnan ninf afn <2 x double> @llvm.copysign.v2f64(<2 x double> [[__EXP2]], <2 x double> [[TMP1]]) ; PRELINK-NEXT: ret <2 x double> [[__POW_SIGN1]] ; ; NOPRELINK-LABEL: define <2 x double> @test_pown_afn_nnan_ninf_v2f64 ; NOPRELINK-SAME: (<2 x double> [[X:%.*]], <2 x i32> [[Y:%.*]]) { ; NOPRELINK-NEXT: entry: ; NOPRELINK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn <2 x double> @_Z4pownDv2_dDv2_i(<2 x double> [[X]], <2 x i32> [[Y]]) ; NOPRELINK-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: [[__FABS:%.*]] = call nnan ninf afn half @llvm.fabs.f16(half [[X]]) ; CHECK-NEXT: [[__LOG2:%.*]] = call nnan ninf afn half @llvm.log2.f16(half [[__FABS]]) ; CHECK-NEXT: [[POWNI2F:%.*]] = sitofp i32 [[Y]] to half ; CHECK-NEXT: [[__YLOGX:%.*]] = fmul nnan ninf afn half [[__LOG2]], [[POWNI2F]] ; CHECK-NEXT: [[__EXP2:%.*]] = call nnan ninf afn nofpclass(nan ninf nzero nsub nnorm) half @llvm.exp2.f16(half [[__YLOGX]]) ; CHECK-NEXT: [[__YTOU:%.*]] = trunc i32 [[Y]] to i16 ; CHECK-NEXT: [[__YEVEN:%.*]] = shl i16 [[__YTOU]], 15 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast half [[X]] to i16 ; CHECK-NEXT: [[__POW_SIGN:%.*]] = and i16 [[__YEVEN]], [[TMP0]] ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i16 [[__POW_SIGN]] to half ; CHECK-NEXT: [[__POW_SIGN1:%.*]] = call nnan ninf afn half @llvm.copysign.f16(half [[__EXP2]], half [[TMP1]]) ; CHECK-NEXT: ret half [[__POW_SIGN1]] ; 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: [[__FABS:%.*]] = call nnan ninf afn <2 x half> @llvm.fabs.v2f16(<2 x half> [[X]]) ; CHECK-NEXT: [[__LOG2:%.*]] = call nnan ninf afn <2 x half> @llvm.log2.v2f16(<2 x half> [[__FABS]]) ; CHECK-NEXT: [[POWNI2F:%.*]] = sitofp <2 x i32> [[Y]] to <2 x half> ; CHECK-NEXT: [[__YLOGX:%.*]] = fmul nnan ninf afn <2 x half> [[__LOG2]], [[POWNI2F]] ; CHECK-NEXT: [[__EXP2:%.*]] = call nnan ninf afn nofpclass(nan ninf nzero nsub nnorm) <2 x half> @llvm.exp2.v2f16(<2 x half> [[__YLOGX]]) ; CHECK-NEXT: [[__YTOU:%.*]] = trunc <2 x i32> [[Y]] to <2 x i16> ; CHECK-NEXT: [[__YEVEN:%.*]] = shl <2 x i16> [[__YTOU]], splat (i16 15) ; CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x half> [[X]] to <2 x i16> ; CHECK-NEXT: [[__POW_SIGN:%.*]] = and <2 x i16> [[__YEVEN]], [[TMP0]] ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[__POW_SIGN]] to <2 x half> ; CHECK-NEXT: [[__POW_SIGN1:%.*]] = call nnan ninf afn <2 x half> @llvm.copysign.v2f16(<2 x half> [[__EXP2]], <2 x half> [[TMP1]]) ; CHECK-NEXT: ret <2 x half> [[__POW_SIGN1]] ; 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) { ; PRELINK-LABEL: define float @test_pown_fast_f32_nobuiltin ; PRELINK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) { ; PRELINK-NEXT: entry: ; PRELINK-NEXT: [[CALL:%.*]] = tail call fast float @_Z4pownfi(float [[X]], i32 [[Y]]) #[[ATTR4:[0-9]+]] ; PRELINK-NEXT: ret float [[CALL]] ; ; NOPRELINK-LABEL: define float @test_pown_fast_f32_nobuiltin ; NOPRELINK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) { ; NOPRELINK-NEXT: entry: ; NOPRELINK-NEXT: [[CALL:%.*]] = tail call fast float @_Z4pownfi(float [[X]], i32 [[Y]]) #[[ATTR3:[0-9]+]] ; NOPRELINK-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]]) #[[ATTR0]] ; CHECK-NEXT: [[__LOG2:%.*]] = call fast float @llvm.log2.f32(float [[__FABS]]) #[[ATTR0]] ; CHECK-NEXT: [[POWNI2F:%.*]] = call fast float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: [[__YLOGX:%.*]] = call fast float @llvm.experimental.constrained.fmul.f32(float [[POWNI2F]], float [[__LOG2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: [[__EXP2:%.*]] = call fast nofpclass(nan ninf nzero nsub nnorm) float @llvm.exp2.f32(float [[__YLOGX]]) #[[ATTR0]] ; 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 i32 [[__POW_SIGN]] to float ; CHECK-NEXT: [[__POW_SIGN1:%.*]] = call fast float @llvm.copysign.f32(float [[__EXP2]], float [[TMP1]]) #[[ATTR0]] ; CHECK-NEXT: ret float [[__POW_SIGN1]] ; 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: 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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWPROD:%.*]] = fmul nnan ninf afn float [[X]], [[__POWX2]] ; CHECK-NEXT: ret float [[__POWPROD]] ; %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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWPROD:%.*]] = fmul nnan ninf afn float [[X]], [[__POWX2]] ; CHECK-NEXT: [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWPROD]] ; CHECK-NEXT: ret float [[__1POWPROD]] ; %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -3) ret float %call } 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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: ret float [[__POWX21]] ; %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 4) ret float %call } 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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWX21]] ; CHECK-NEXT: ret float [[__1POWPROD]] ; %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -4) ret float %call } 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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: [[__POWPROD:%.*]] = fmul nnan ninf afn float [[X]], [[__POWX21]] ; CHECK-NEXT: ret float [[__POWPROD]] ; %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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: [[__POWPROD:%.*]] = fmul nnan ninf afn float [[X]], [[__POWX21]] ; CHECK-NEXT: [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWPROD]] ; CHECK-NEXT: ret float [[__1POWPROD]] ; %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -5) ret float %call } 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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWPROD:%.*]] = fmul nnan ninf afn float [[X]], [[__POWX2]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: [[__POWPROD2:%.*]] = fmul nnan ninf afn float [[__POWPROD]], [[__POWX21]] ; CHECK-NEXT: ret float [[__POWPROD2]] ; %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 7) ret float %call } 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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWPROD:%.*]] = fmul nnan ninf afn float [[X]], [[__POWX2]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: [[__POWPROD2:%.*]] = fmul nnan ninf afn float [[__POWPROD]], [[__POWX21]] ; CHECK-NEXT: [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWPROD2]] ; CHECK-NEXT: ret float [[__1POWPROD]] ; %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -7) ret float %call } 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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: [[__POWX22:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[__POWX21]] ; CHECK-NEXT: ret float [[__POWX22]] ; %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 8) ret float %call } 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: [[__POWX2:%.*]] = fmul nnan ninf afn float [[X]], [[X]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn float [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: [[__POWX22:%.*]] = fmul nnan ninf afn float [[__POWX21]], [[__POWX21]] ; CHECK-NEXT: [[__1POWPROD:%.*]] = fdiv nnan ninf afn float 1.000000e+00, [[__POWX22]] ; CHECK-NEXT: ret float [[__1POWPROD]] ; %call = tail call nnan ninf afn float @_Z4pownfi(float %x, i32 -8) ret float %call } 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: [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]] ; CHECK-NEXT: [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[__POWX2]] ; CHECK-NEXT: ret <2 x float> [[__POWPROD]] ; entry: %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> ) 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: [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: ret <2 x float> [[__POWX21]] ; entry: %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> ) 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: [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]] ; CHECK-NEXT: [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[__POWX2]] ; CHECK-NEXT: [[__1POWPROD:%.*]] = fdiv nnan ninf afn <2 x float> splat (float 1.000000e+00), [[__POWPROD]] ; CHECK-NEXT: ret <2 x float> [[__1POWPROD]] ; entry: %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> ) 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: [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: [[__1POWPROD:%.*]] = fdiv nnan ninf afn <2 x float> splat (float 1.000000e+00), [[__POWX21]] ; CHECK-NEXT: ret <2 x float> [[__1POWPROD]] ; entry: %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> ) 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: [[__POWX2:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[X]] ; CHECK-NEXT: [[__POWX21:%.*]] = fmul nnan ninf afn <2 x float> [[__POWX2]], [[__POWX2]] ; CHECK-NEXT: [[__POWPROD:%.*]] = fmul nnan ninf afn <2 x float> [[X]], [[__POWX21]] ; CHECK-NEXT: ret <2 x float> [[__POWPROD]] ; entry: %call = tail call afn nnan ninf <2 x float> @_Z4pownDv2_fDv2_i(<2 x float> %x, <2 x i32> ) 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) { ; PRELINK-LABEL: define float @test_pown_afn_f32__x_known_positive ; PRELINK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) { ; PRELINK-NEXT: entry: ; PRELINK-NEXT: [[CALL:%.*]] = tail call afn float @_Z11__pown_fastfi(float [[X]], i32 [[Y]]) ; PRELINK-NEXT: ret float [[CALL]] ; ; NOPRELINK-LABEL: define float @test_pown_afn_f32__x_known_positive ; NOPRELINK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) { ; NOPRELINK-NEXT: entry: ; NOPRELINK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[Y]], 0 ; NOPRELINK-NEXT: [[TMP1:%.*]] = select afn i1 [[TMP0]], float 1.000000e+00, float [[X]] ; NOPRELINK-NEXT: [[TMP2:%.*]] = sitofp i32 [[Y]] to float ; NOPRELINK-NEXT: [[TMP3:%.*]] = call afn float @llvm.fabs.f32(float [[TMP1]]) ; NOPRELINK-NEXT: [[TMP4:%.*]] = call afn float @llvm.log2.f32(float [[TMP3]]) ; NOPRELINK-NEXT: [[TMP5:%.*]] = fmul afn float [[TMP4]], [[TMP2]] ; NOPRELINK-NEXT: [[TMP6:%.*]] = call afn float @llvm.exp2.f32(float [[TMP5]]) ; NOPRELINK-NEXT: [[TMP7:%.*]] = and i32 [[Y]], 1 ; NOPRELINK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP7]], 0 ; NOPRELINK-NEXT: [[TMP8:%.*]] = select afn i1 [[DOTNOT]], float 1.000000e+00, float [[TMP1]] ; NOPRELINK-NEXT: [[TMP9:%.*]] = call afn float @llvm.copysign.f32(float [[TMP6]], float [[TMP8]]) ; NOPRELINK-NEXT: [[TMP10:%.*]] = call afn float @llvm.fabs.f32(float [[TMP1]]) ; NOPRELINK-NEXT: [[TMP11:%.*]] = fcmp afn oeq float [[TMP10]], +inf ; NOPRELINK-NEXT: [[TMP12:%.*]] = fcmp afn oeq float [[TMP1]], 0.000000e+00 ; NOPRELINK-NEXT: [[TMP13:%.*]] = or i1 [[TMP11]], [[TMP12]] ; NOPRELINK-NEXT: [[TMP14:%.*]] = icmp slt i32 [[Y]], 0 ; NOPRELINK-NEXT: [[TMP15:%.*]] = xor i1 [[TMP12]], [[TMP14]] ; NOPRELINK-NEXT: [[TMP16:%.*]] = select afn i1 [[TMP15]], float 0.000000e+00, float +inf ; NOPRELINK-NEXT: [[TMP17:%.*]] = select afn i1 [[DOTNOT]], float 0.000000e+00, float [[TMP1]] ; NOPRELINK-NEXT: [[TMP18:%.*]] = call afn float @llvm.copysign.f32(float [[TMP16]], float [[TMP17]]) ; NOPRELINK-NEXT: [[TMP19:%.*]] = select afn i1 [[TMP13]], float [[TMP18]], float [[TMP9]] ; NOPRELINK-NEXT: ret float [[TMP19]] ; 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: [[__LOG2:%.*]] = call nnan ninf afn float @llvm.log2.f32(float [[X]]) ; CHECK-NEXT: [[POWNI2F:%.*]] = sitofp i32 [[Y]] to float ; CHECK-NEXT: [[__YLOGX:%.*]] = fmul nnan ninf afn float [[__LOG2]], [[POWNI2F]] ; CHECK-NEXT: [[__EXP2:%.*]] = call nnan ninf afn nofpclass(nan ninf nzero nsub nnorm) float @llvm.exp2.f32(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 i32 [[__POW_SIGN]] to float ; CHECK-NEXT: [[__POW_SIGN1:%.*]] = call nnan ninf afn float @llvm.copysign.f32(float [[__EXP2]], float [[TMP1]]) ; CHECK-NEXT: ret float [[__POW_SIGN1]] ; 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) { ; PRELINK-LABEL: define float @test_pown_afn_f32__x_known_positive__y_4 ; PRELINK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) { ; PRELINK-NEXT: entry: ; PRELINK-NEXT: [[CALL:%.*]] = tail call afn float @_Z11__pown_fastfi(float [[X]], i32 4) ; PRELINK-NEXT: ret float [[CALL]] ; ; NOPRELINK-LABEL: define float @test_pown_afn_f32__x_known_positive__y_4 ; NOPRELINK-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) { ; NOPRELINK-NEXT: entry: ; NOPRELINK-NEXT: [[TMP0:%.*]] = call afn float @llvm.fabs.f32(float [[X]]) ; NOPRELINK-NEXT: [[TMP1:%.*]] = call afn float @llvm.log2.f32(float [[TMP0]]) ; NOPRELINK-NEXT: [[TMP2:%.*]] = fmul afn float [[TMP1]], 4.000000e+00 ; NOPRELINK-NEXT: [[TMP3:%.*]] = call afn float @llvm.exp2.f32(float [[TMP2]]) ; NOPRELINK-NEXT: [[TMP4:%.*]] = call afn float @llvm.fabs.f32(float [[TMP3]]) ; NOPRELINK-NEXT: [[TMP5:%.*]] = call afn float @llvm.fabs.f32(float [[X]]) ; NOPRELINK-NEXT: [[TMP6:%.*]] = fcmp afn oeq float [[TMP5]], +inf ; NOPRELINK-NEXT: [[TMP7:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00 ; NOPRELINK-NEXT: [[TMP8:%.*]] = select i1 [[TMP6]], float +inf, float [[TMP4]] ; NOPRELINK-NEXT: [[TMP9:%.*]] = select i1 [[TMP7]], float 0.000000e+00, float [[TMP8]] ; NOPRELINK-NEXT: ret float [[TMP9]] ; 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 @llvm.log2.f32(float [[__FABS]]) ; CHECK-NEXT: [[POWNI2F:%.*]] = sitofp i32 [[Y]] to float ; CHECK-NEXT: [[__YLOGX:%.*]] = fmul fast float [[__LOG2]], [[POWNI2F]] ; CHECK-NEXT: [[__EXP2:%.*]] = call fast nofpclass(nan ninf nzero nsub nnorm) float @llvm.exp2.f32(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: [[__LOG2:%.*]] = call fast float @llvm.log2.f32(float [[X]]) ; CHECK-NEXT: [[POWNI2F:%.*]] = sitofp i32 [[Y]] to float ; CHECK-NEXT: [[__YLOGX:%.*]] = fmul fast float [[__LOG2]], [[POWNI2F]] ; CHECK-NEXT: [[__EXP2:%.*]] = call fast nofpclass(nan ninf nzero nsub nnorm) float @llvm.exp2.f32(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 } !llvm.module.flags = !{!0} !0 = !{i32 1, !"amdgpu-libcall-have-fast-pow", i32 1}