Index: llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp +++ llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp @@ -14,6 +14,7 @@ #include "AMDGPU.h" #include "AMDGPULibFunc.h" #include "GCNSubtarget.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicsAMDGPU.h" @@ -846,6 +847,17 @@ } } + if (FInfo.getId() == AMDGPULibFunc::EI_POW) { + FunctionCallee PowrFunc = + getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_POWR, FInfo)); + + // TODO: Pass all arguments to cannotBeOrderedLessThanZero + if (PowrFunc && cannotBeOrderedLessThanZero(opr0, M->getDataLayout())) { + cast(FPOp)->setCalledFunction(PowrFunc); + return true; + } + } + if (!isUnsafeFiniteOnlyMath(FPOp)) return false; Index: llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll +++ llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll @@ -1017,7 +1017,7 @@ 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: [[POW:%.*]] = tail call nnan afn float @_Z4powrff(float [[X]], float [[Y]]) ; CHECK-NEXT: ret float [[POW]] ; %pow = tail call afn nnan float @_Z3powff(float %x, float %y) @@ -1027,7 +1027,7 @@ 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: [[POW:%.*]] = tail call nnan ninf afn float @_Z4powrff(float [[X]], float [[Y]]) ; CHECK-NEXT: ret float [[POW]] ; %pow = tail call afn nnan ninf float @_Z3powff(float %x, float %y) @@ -1037,7 +1037,7 @@ 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: [[POW:%.*]] = tail call nnan afn <2 x float> @_Z4powrDv2_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) @@ -1047,7 +1047,7 @@ 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: [[POW:%.*]] = tail call nnan ninf afn <2 x float> @_Z4powrDv2_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) @@ -1057,7 +1057,7 @@ 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: [[POW:%.*]] = tail call float @_Z4powrff(float [[X]], float [[Y]]) ; CHECK-NEXT: ret float [[POW]] ; %pow = tail call float @_Z3powff(float %x, float %y) @@ -1067,7 +1067,7 @@ 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: [[POW:%.*]] = tail call afn float @_Z4powrff(float [[X]], float [[Y]]) ; CHECK-NEXT: ret float [[POW]] ; %pow = tail call afn float @_Z3powff(float %x, float %y) @@ -1077,7 +1077,7 @@ 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: [[POW:%.*]] = tail call <2 x float> @_Z4powrDv2_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) @@ -1087,7 +1087,7 @@ 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: [[POW:%.*]] = tail call afn <2 x float> @_Z4powrDv2_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) @@ -1097,7 +1097,7 @@ 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: [[POW:%.*]] = tail call nnan afn double @_Z4powrdd(double [[X]], double [[Y]]) ; CHECK-NEXT: ret double [[POW]] ; %pow = tail call afn nnan double @_Z3powdd(double %x, double %y) @@ -1107,7 +1107,7 @@ 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: [[POW:%.*]] = tail call nnan ninf afn double @_Z4powrdd(double [[X]], double [[Y]]) ; CHECK-NEXT: ret double [[POW]] ; %pow = tail call afn nnan ninf double @_Z3powdd(double %x, double %y) @@ -1117,7 +1117,7 @@ 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: [[POW:%.*]] = tail call nnan afn <2 x double> @_Z4powrDv2_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) @@ -1127,7 +1127,7 @@ 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: [[POW:%.*]] = tail call nnan ninf afn <2 x double> @_Z4powrDv2_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) @@ -1137,7 +1137,7 @@ 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: [[POW:%.*]] = tail call double @_Z4powrdd(double [[X]], double [[Y]]) ; CHECK-NEXT: ret double [[POW]] ; %pow = tail call double @_Z3powdd(double %x, double %y) @@ -1147,7 +1147,7 @@ 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: [[POW:%.*]] = tail call afn double @_Z4powrdd(double [[X]], double [[Y]]) ; CHECK-NEXT: ret double [[POW]] ; %pow = tail call afn double @_Z3powdd(double %x, double %y) @@ -1157,7 +1157,7 @@ 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: [[POW:%.*]] = tail call <2 x double> @_Z4powrDv2_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) @@ -1167,7 +1167,7 @@ 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: [[POW:%.*]] = tail call afn <2 x double> @_Z4powrDv2_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) @@ -1177,7 +1177,7 @@ 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: [[POW:%.*]] = tail call nnan afn half @_Z4powrDhDh(half [[X]], half [[Y]]) ; CHECK-NEXT: ret half [[POW]] ; %pow = tail call afn nnan half @_Z3powDhDh(half %x, half %y) @@ -1187,7 +1187,7 @@ 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: [[POW:%.*]] = tail call nnan ninf afn half @_Z4powrDhDh(half [[X]], half [[Y]]) ; CHECK-NEXT: ret half [[POW]] ; %pow = tail call afn nnan ninf half @_Z3powDhDh(half %x, half %y) @@ -1197,7 +1197,7 @@ 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: [[POW:%.*]] = tail call nnan afn <2 x half> @_Z4powrDv2_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) @@ -1207,7 +1207,7 @@ 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: [[POW:%.*]] = tail call nnan ninf afn <2 x half> @_Z4powrDv2_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) @@ -1217,7 +1217,7 @@ 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: [[POW:%.*]] = tail call half @_Z4powrDhDh(half [[X]], half [[Y]]) ; CHECK-NEXT: ret half [[POW]] ; %pow = tail call half @_Z3powDhDh(half %x, half %y) @@ -1227,7 +1227,7 @@ 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: [[POW:%.*]] = tail call afn half @_Z4powrDhDh(half [[X]], half [[Y]]) ; CHECK-NEXT: ret half [[POW]] ; %pow = tail call afn half @_Z3powDhDh(half %x, half %y) @@ -1237,7 +1237,7 @@ 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: [[POW:%.*]] = tail call <2 x half> @_Z4powrDv2_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) @@ -1247,7 +1247,7 @@ 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: [[POW:%.*]] = tail call afn <2 x half> @_Z4powrDv2_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)