If a float-typed call site is marked with afn, replace the 4 flavors of pow with a faster variant. This transforms pow, powr, pown, and rootn to __pow_fast, __powr_fast, __pown_fast, and __rootn_fast if available. Also attempts to handle all of the same basic folds on the new fast variants that were already performed with the base forms. This maintains optimizations with OpenCL when the device libs unsafe math control library is deleted. This maintains the status quo of how libcalls work, and only handles 4 new entry points. This only helps with the elimination of the control library, and not general libcall emission problems. This makes no practical difference for HIP, which is the status quo for libcall optimizations. AMDGPULibCalls recognizes the OpenCL mangled names. e.g., OpenCL float "pow" is really _Z3powff but the HIP provided function "powf" is really named _ZL4powfff, and std::pow with float is _ZL3powff. The pass still runs for HIP, so by accident if you used the OpenCL mangled function names, this would trigger. Since the functions cannot yet be relied on from the library, introduce a temporary module flag check. I'm not planning on emitting it anywhere and it's a poor substitute for versioning the target.
488 lines
18 KiB
LLVM
488 lines
18 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
|
|
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=amdgpu-simplifylib,instcombine -amdgpu-prelink %s | FileCheck %s
|
|
|
|
define float @test_powr_afn_f32(float %x, float %y) #0 {
|
|
; CHECK-LABEL: define float @test_powr_afn_f32(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn float @_Z11__powr_fastff(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z4powrff(float %x, float %y)
|
|
ret float %call
|
|
}
|
|
|
|
declare float @_Z4powrff(float, float) #1
|
|
|
|
define <2 x float> @test_powr_afn_v2f32(<2 x float> %x, <2 x float> %y) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn <2 x float> @_Z11__powr_fastDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
|
|
; CHECK-NEXT: ret <2 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> %y)
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
declare <2 x float> @_Z4powrDv2_fS_(<2 x float>, <2 x float>) #1
|
|
|
|
define <3 x float> @test_powr_afn_v3f32(<3 x float> %x, <3 x float> %y) #0 {
|
|
; CHECK-LABEL: define <3 x float> @test_powr_afn_v3f32(
|
|
; CHECK-SAME: <3 x float> [[X:%.*]], <3 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn <3 x float> @_Z11__powr_fastDv3_fS_(<3 x float> [[X]], <3 x float> [[Y]])
|
|
; CHECK-NEXT: ret <3 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <3 x float> @_Z4powrDv3_fS_(<3 x float> %x, <3 x float> %y)
|
|
ret <3 x float> %call
|
|
}
|
|
|
|
declare <3 x float> @_Z4powrDv3_fS_(<3 x float>, <3 x float>) #1
|
|
|
|
define <4 x float> @test_powr_afn_v4f32(<4 x float> %x, <4 x float> %y) #0 {
|
|
; CHECK-LABEL: define <4 x float> @test_powr_afn_v4f32(
|
|
; CHECK-SAME: <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn <4 x float> @_Z11__powr_fastDv4_fS_(<4 x float> [[X]], <4 x float> [[Y]])
|
|
; CHECK-NEXT: ret <4 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <4 x float> @_Z4powrDv4_fS_(<4 x float> %x, <4 x float> %y)
|
|
ret <4 x float> %call
|
|
}
|
|
|
|
declare <4 x float> @_Z4powrDv4_fS_(<4 x float>, <4 x float>) #1
|
|
|
|
define <8 x float> @test_powr_afn_v8f32(<8 x float> %x, <8 x float> %y) #0 {
|
|
; CHECK-LABEL: define <8 x float> @test_powr_afn_v8f32(
|
|
; CHECK-SAME: <8 x float> [[X:%.*]], <8 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn <8 x float> @_Z11__powr_fastDv8_fS_(<8 x float> [[X]], <8 x float> [[Y]])
|
|
; CHECK-NEXT: ret <8 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <8 x float> @_Z4powrDv8_fS_(<8 x float> %x, <8 x float> %y)
|
|
ret <8 x float> %call
|
|
}
|
|
|
|
declare <8 x float> @_Z4powrDv8_fS_(<8 x float>, <8 x float>) #1
|
|
|
|
define <16 x float> @test_powr_afn_v16f32(<16 x float> %x, <16 x float> %y) #0 {
|
|
; CHECK-LABEL: define <16 x float> @test_powr_afn_v16f32(
|
|
; CHECK-SAME: <16 x float> [[X:%.*]], <16 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn <16 x float> @_Z11__powr_fastDv16_fS_(<16 x float> [[X]], <16 x float> [[Y]])
|
|
; CHECK-NEXT: ret <16 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <16 x float> @_Z4powrDv16_fS_(<16 x float> %x, <16 x float> %y)
|
|
ret <16 x float> %call
|
|
}
|
|
|
|
declare <16 x float> @_Z4powrDv16_fS_(<16 x float>, <16 x float>) #1
|
|
|
|
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: [[CALL:%.*]] = tail call afn float @_Z11__powr_fastff(float [[X]], float [[Y_CAST]])
|
|
; CHECK-NEXT: ret float [[CALL]]
|
|
;
|
|
%y.cast = sitofp i32 %y to float
|
|
%call = tail call afn float @_Z4powrff(float %x, float %y.cast)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test_powr_afn_f32__0(float %x) #0 {
|
|
; CHECK-LABEL: define float @test_powr_afn_f32__0(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: ret float 1.000000e+00
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z4powrff(float %x, float 0.0)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test_powr_afn_f32__1(float %x) #0 {
|
|
; CHECK-LABEL: define float @test_powr_afn_f32__1(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: ret float [[X]]
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z4powrff(float %x, float 1.0)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test_powr_afn_f32__2(float %x) #0 {
|
|
; CHECK-LABEL: define float @test_powr_afn_f32__2(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POW2:%.*]] = fmul afn float [[X]], [[X]]
|
|
; CHECK-NEXT: ret float [[__POW2]]
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z4powrff(float %x, float 2.0)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test_powr_afn_f32__3(float %x) #0 {
|
|
; CHECK-LABEL: define float @test_powr_afn_f32__3(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn float @_Z11__powr_fastff(float [[X]], float 3.000000e+00)
|
|
; CHECK-NEXT: ret float [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z4powrff(float %x, float 3.0)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test_powr_afn_f32__8(float %x) #0 {
|
|
; CHECK-LABEL: define float @test_powr_afn_f32__8(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn float @_Z11__powr_fastff(float [[X]], float 8.000000e+00)
|
|
; CHECK-NEXT: ret float [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z4powrff(float %x, float 8.0)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test_powr_afn_f32__neg1(float %x) #0 {
|
|
; CHECK-LABEL: define float @test_powr_afn_f32__neg1(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POWRECIP:%.*]] = fdiv afn float 1.000000e+00, [[X]]
|
|
; CHECK-NEXT: ret float [[__POWRECIP]]
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z4powrff(float %x, float -1.0)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test_powr_afn_f32__half(float %x) #0 {
|
|
; CHECK-LABEL: define float @test_powr_afn_f32__half(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POW2SQRT:%.*]] = call afn float @_Z4sqrtf(float [[X]])
|
|
; CHECK-NEXT: ret float [[__POW2SQRT]]
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z4powrff(float %x, float 0.5)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test_powr_afn_f32__neghalf(float %x) #0 {
|
|
; CHECK-LABEL: define float @test_powr_afn_f32__neghalf(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POW2RSQRT:%.*]] = call afn float @_Z5rsqrtf(float [[X]])
|
|
; CHECK-NEXT: ret float [[__POW2RSQRT]]
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z4powrff(float %x, float -0.5)
|
|
ret float %call
|
|
}
|
|
|
|
define <2 x float> @test_powr_afn_v2f32__0(<2 x float> %x) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32__0(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: ret <2 x float> splat (float 1.000000e+00)
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> zeroinitializer)
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
define <2 x float> @test_powr_afn_v2f32__1(<2 x float> %x) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32__1(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: ret <2 x float> [[X]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> splat (float 1.0))
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
define <2 x float> @test_powr_afn_v2f32__2(<2 x float> %x) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32__2(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POW2:%.*]] = fmul afn <2 x float> [[X]], [[X]]
|
|
; CHECK-NEXT: ret <2 x float> [[__POW2]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> splat (float 2.0))
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
define <2 x float> @test_powr_afn_v2f32__3(<2 x float> %x) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32__3(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn <2 x float> @_Z11__powr_fastDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 3.000000e+00))
|
|
; CHECK-NEXT: ret <2 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> splat (float 3.0))
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
define <2 x float> @test_powr_afn_v2f32__8(<2 x float> %x) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32__8(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn <2 x float> @_Z11__powr_fastDv2_fS_(<2 x float> [[X]], <2 x float> splat (float 8.000000e+00))
|
|
; CHECK-NEXT: ret <2 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> splat (float 8.0))
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
define <2 x float> @test_powr_afn_v2f32__neg1(<2 x float> %x) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32__neg1(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POWRECIP:%.*]] = fdiv afn <2 x float> splat (float 1.000000e+00), [[X]]
|
|
; CHECK-NEXT: ret <2 x float> [[__POWRECIP]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> splat (float -1.0))
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
define <2 x float> @test_powr_afn_v2f32__half(<2 x float> %x) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32__half(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POW2SQRT:%.*]] = call afn <2 x float> @_Z4sqrtDv2_f(<2 x float> [[X]])
|
|
; CHECK-NEXT: ret <2 x float> [[__POW2SQRT]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> splat (float 0.5))
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
define <2 x float> @test_powr_afn_v2f32__neghalf(<2 x float> %x) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test_powr_afn_v2f32__neghalf(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POW2RSQRT:%.*]] = call afn <2 x float> @_Z5rsqrtDv2_f(<2 x float> [[X]])
|
|
; CHECK-NEXT: ret <2 x float> [[__POW2RSQRT]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x float> @_Z4powrDv2_fS_(<2 x float> %x, <2 x float> splat (float -0.5))
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
define float @test__powr_fast_f32(float %x, float %y) #0 {
|
|
; CHECK-LABEL: define float @test__powr_fast_f32(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z11__powr_fastff(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call float @_Z11__powr_fastff(float %x, float %y)
|
|
ret float %call
|
|
}
|
|
|
|
declare float @_Z11__powr_fastff(float, float) #1
|
|
|
|
define <2 x float> @test__powr_fast_v2f32(<2 x float> %x, <2 x float> %y) #0 {
|
|
; CHECK-LABEL: define <2 x float> @test__powr_fast_v2f32(
|
|
; CHECK-SAME: <2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z11__powr_fastDv2_fS_(<2 x float> [[X]], <2 x float> [[Y]])
|
|
; CHECK-NEXT: ret <2 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call <2 x float> @_Z11__powr_fastDv2_fS_(<2 x float> %x, <2 x float> %y)
|
|
ret <2 x float> %call
|
|
}
|
|
|
|
declare <2 x float> @_Z11__powr_fastDv2_fS_(<2 x float>, <2 x float>) #1
|
|
|
|
define <3 x float> @test__powr_fast_v3f32(<3 x float> %x, <3 x float> %y) #0 {
|
|
; CHECK-LABEL: define <3 x float> @test__powr_fast_v3f32(
|
|
; CHECK-SAME: <3 x float> [[X:%.*]], <3 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z11__powr_fastDv3_fS_(<3 x float> [[X]], <3 x float> [[Y]])
|
|
; CHECK-NEXT: ret <3 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call <3 x float> @_Z11__powr_fastDv3_fS_(<3 x float> %x, <3 x float> %y)
|
|
ret <3 x float> %call
|
|
}
|
|
|
|
declare <3 x float> @_Z11__powr_fastDv3_fS_(<3 x float>, <3 x float>) #1
|
|
|
|
define <4 x float> @test__powr_fast_v4f32(<4 x float> %x, <4 x float> %y) #0 {
|
|
; CHECK-LABEL: define <4 x float> @test__powr_fast_v4f32(
|
|
; CHECK-SAME: <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call <4 x float> @_Z11__powr_fastDv4_fS_(<4 x float> [[X]], <4 x float> [[Y]])
|
|
; CHECK-NEXT: ret <4 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call <4 x float> @_Z11__powr_fastDv4_fS_(<4 x float> %x, <4 x float> %y)
|
|
ret <4 x float> %call
|
|
}
|
|
|
|
declare <4 x float> @_Z11__powr_fastDv4_fS_(<4 x float>, <4 x float>) #1
|
|
|
|
define <8 x float> @test__powr_fast_v8f32(<8 x float> %x, <8 x float> %y) #0 {
|
|
; CHECK-LABEL: define <8 x float> @test__powr_fast_v8f32(
|
|
; CHECK-SAME: <8 x float> [[X:%.*]], <8 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call <8 x float> @_Z11__powr_fastDv8_fS_(<8 x float> [[X]], <8 x float> [[Y]])
|
|
; CHECK-NEXT: ret <8 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call <8 x float> @_Z11__powr_fastDv8_fS_(<8 x float> %x, <8 x float> %y)
|
|
ret <8 x float> %call
|
|
}
|
|
|
|
declare <8 x float> @_Z11__powr_fastDv8_fS_(<8 x float>, <8 x float>) #1
|
|
|
|
define <16 x float> @test__powr_fast_v16f32(<16 x float> %x, <16 x float> %y) #0 {
|
|
; CHECK-LABEL: define <16 x float> @test__powr_fast_v16f32(
|
|
; CHECK-SAME: <16 x float> [[X:%.*]], <16 x float> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call <16 x float> @_Z11__powr_fastDv16_fS_(<16 x float> [[X]], <16 x float> [[Y]])
|
|
; CHECK-NEXT: ret <16 x float> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call <16 x float> @_Z11__powr_fastDv16_fS_(<16 x float> %x, <16 x float> %y)
|
|
ret <16 x float> %call
|
|
}
|
|
|
|
declare <16 x float> @_Z11__powr_fastDv16_fS_(<16 x float>, <16 x float>) #1
|
|
|
|
define float @test__powr_fast_f32_known_integral_sitofp(float %x, i32 %y) {
|
|
; CHECK-LABEL: define float @test__powr_fast_f32_known_integral_sitofp(
|
|
; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[Y_CAST:%.*]] = sitofp i32 [[Y]] to float
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z11__powr_fastff(float [[X]], float [[Y_CAST]])
|
|
; CHECK-NEXT: ret float [[CALL]]
|
|
;
|
|
%y.cast = sitofp i32 %y to float
|
|
%call = tail call float @_Z11__powr_fastff(float %x, float %y.cast)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test__powr_fast_f32_0(float %x) #0 {
|
|
; CHECK-LABEL: define float @test__powr_fast_f32_0(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: ret float 1.000000e+00
|
|
;
|
|
entry:
|
|
%call = tail call float @_Z11__powr_fastff(float %x, float 0.0)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test__powr_fast_afn_f32_0(float %x) #0 {
|
|
; CHECK-LABEL: define float @test__powr_fast_afn_f32_0(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: ret float 1.000000e+00
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z11__powr_fastff(float %x, float 0.0)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test__powr_fast_f32_2(float %x) #0 {
|
|
; CHECK-LABEL: define float @test__powr_fast_f32_2(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POW2:%.*]] = fmul float [[X]], [[X]]
|
|
; CHECK-NEXT: ret float [[__POW2]]
|
|
;
|
|
entry:
|
|
%call = tail call float @_Z11__powr_fastff(float %x, float 2.0)
|
|
ret float %call
|
|
}
|
|
|
|
define float @test__powr_fast_afn_f32_2(float %x) #0 {
|
|
; CHECK-LABEL: define float @test__powr_fast_afn_f32_2(
|
|
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[__POW2:%.*]] = fmul afn float [[X]], [[X]]
|
|
; CHECK-NEXT: ret float [[__POW2]]
|
|
;
|
|
entry:
|
|
%call = tail call afn float @_Z11__powr_fastff(float %x, float 2.0)
|
|
ret float %call
|
|
}
|
|
|
|
define double @test_powr_afn_f64(double %x, double %y) #0 {
|
|
; CHECK-LABEL: define double @test_powr_afn_f64(
|
|
; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn double @_Z4powrdd(double [[X]], double [[Y]])
|
|
; CHECK-NEXT: ret double [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn double @_Z4powrdd(double %x, double %y)
|
|
ret double %call
|
|
}
|
|
|
|
declare double @_Z4powrdd(double, double) #0
|
|
|
|
define <2 x double> @test_powr_afn_v2f64(<2 x double> %x, <2 x double> %y) #0 {
|
|
; CHECK-LABEL: define <2 x double> @test_powr_afn_v2f64(
|
|
; CHECK-SAME: <2 x double> [[X:%.*]], <2 x double> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn <2 x double> @_Z4powrDv2_dS_(<2 x double> [[X]], <2 x double> [[Y]])
|
|
; CHECK-NEXT: ret <2 x double> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x double> @_Z4powrDv2_dS_(<2 x double> %x, <2 x double> %y)
|
|
ret <2 x double> %call
|
|
}
|
|
|
|
declare <2 x double> @_Z4powrDv2_dS_(<2 x double>, <2 x double>) #0
|
|
|
|
define half @test_powr_afn_f16(half %x, half %y) #0 {
|
|
; CHECK-LABEL: define half @test_powr_afn_f16(
|
|
; CHECK-SAME: half [[X:%.*]], half [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn half @_Z4powrDhDh(half [[X]], half [[Y]])
|
|
; CHECK-NEXT: ret half [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn half @_Z4powrDhDh(half %x, half %y)
|
|
ret half %call
|
|
}
|
|
|
|
declare half @_Z4powrDhDh(half, half) #0
|
|
|
|
define <2 x half> @test_powr_afn_v2f16(<2 x half> %x, <2 x half> %y) #0 {
|
|
; CHECK-LABEL: define <2 x half> @test_powr_afn_v2f16(
|
|
; CHECK-SAME: <2 x half> [[X:%.*]], <2 x half> [[Y:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call afn <2 x half> @_Z4powrDv2_DhS_(<2 x half> [[X]], <2 x half> [[Y]])
|
|
; CHECK-NEXT: ret <2 x half> [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call afn <2 x half> @_Z4powrDv2_DhS_(<2 x half> %x, <2 x half> %y)
|
|
ret <2 x half> %call
|
|
}
|
|
|
|
declare <2 x half> @_Z4powrDv2_DhS_(<2 x half>, <2 x half>) #0
|
|
|
|
attributes #0 = { mustprogress nofree norecurse nounwind willreturn memory(none) }
|
|
attributes #1 = { mustprogress nofree nounwind willreturn memory(none) }
|