Skip to content

Commit

Permalink
[HLSL] add pow library function
Browse files Browse the repository at this point in the history
This change exposes the pow library function for HLSL, only available for floating point types.
The pow function is supported for all scalar, vector, and matrix types that contain floating point types.

The full documentation of the HLSL pow function is available here:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-pow

Reviewed By: bogner

Differential Revision: https://reviews.llvm.org/D156178
  • Loading branch information
bob80905 committed Aug 8, 2023
1 parent 211c975 commit df5137e
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
31 changes: 31 additions & 0 deletions clang/lib/Headers/hlsl/hlsl_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,5 +532,36 @@ __attribute__((clang_builtin_alias(__builtin_elementwise_bitreverse)))
uint64_t3 reversebits(uint64_t3);
__attribute__((clang_builtin_alias(__builtin_elementwise_bitreverse)))
uint64_t4 reversebits(uint64_t4);

// pow builtins
#ifdef __HLSL_ENABLE_16_BIT
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
half pow(half, half);
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
half2 pow(half2, half2);
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
half3 pow(half3, half3);
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
half4 pow(half4, half4);
#endif

__attribute__((clang_builtin_alias(__builtin_elementwise_pow))) float
pow(float, float);
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
float2 pow(float2, float2);
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
float3 pow(float3, float3);
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
float4 pow(float4, float4);

__attribute__((clang_builtin_alias(__builtin_elementwise_pow))) double
pow(double, double);
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
double2 pow(double2, double2);
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
double3 pow(double3, double3);
__attribute__((clang_builtin_alias(__builtin_elementwise_pow)))
double4 pow(double4, double4);

} // namespace hlsl
#endif //_HLSL_HLSL_INTRINSICS_H_
89 changes: 89 additions & 0 deletions clang/test/CodeGenHLSL/builtins/pow.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
// RUN: -D__HLSL_ENABLE_16_BIT -o - | FileCheck %s --check-prefix=NO_HALF

// CHECK: define noundef half @
// CHECK: call half @llvm.pow.f16(
// NO_HALF: define noundef float @"?test_pow_half@@YA$halff@$halff@0@Z"(
// NO_HALF: call float @llvm.pow.f32(
half test_pow_half(half p0, half p1)
{
return pow(p0, p1);
}
// CHECK: define noundef <2 x half> @"?test_pow_half2@@YAT?$__vector@$f16@$01@__clang@@T12@0@Z"(
// CHECK: call <2 x half> @llvm.pow.v2f16
// NO_HALF: define noundef <2 x float> @"?test_pow_float2@@YAT?$__vector@M$01@__clang@@T12@0@Z"(
// NO_HALF: call <2 x float> @llvm.pow.v2f32(
half2 test_pow_half2(half2 p0, half2 p1)
{
return pow(p0, p1);
}
// CHECK: define noundef <3 x half> @"?test_pow_half3@@YAT?$__vector@$f16@$02@__clang@@T12@0@Z"(
// CHECK: call <3 x half> @llvm.pow.v3f16
// NO_HALF: define noundef <3 x float> @"?test_pow_float3@@YAT?$__vector@M$02@__clang@@T12@0@Z"(
// NO_HALF: call <3 x float> @llvm.pow.v3f32(
half3 test_pow_half3(half3 p0, half3 p1)
{
return pow(p0, p1);
}
// CHECK: define noundef <4 x half> @"?test_pow_half4@@YAT?$__vector@$f16@$03@__clang@@T12@0@Z"(
// CHECK: call <4 x half> @llvm.pow.v4f16
// NO_HALF: define noundef <4 x float> @"?test_pow_float4@@YAT?$__vector@M$03@__clang@@T12@0@Z"(
// NO_HALF: call <4 x float> @llvm.pow.v4f32(
half4 test_pow_half4(half4 p0, half4 p1)
{
return pow(p0, p1);
}

// CHECK: define noundef float @"?test_pow_float@@YAMMM@Z"(
// CHECK: call float @llvm.pow.f32(
float test_pow_float(float p0, float p1)
{
return pow(p0, p1);
}
// CHECK: define noundef <2 x float> @"?test_pow_float2@@YAT?$__vector@M$01@__clang@@T12@0@Z"(
// CHECK: call <2 x float> @llvm.pow.v2f32
float2 test_pow_float2(float2 p0, float2 p1)
{
return pow(p0, p1);
}
// CHECK: define noundef <3 x float> @"?test_pow_float3@@YAT?$__vector@M$02@__clang@@T12@0@Z"(
// CHECK: call <3 x float> @llvm.pow.v3f32
float3 test_pow_float3(float3 p0, float3 p1)
{
return pow(p0, p1);
}
// CHECK: define noundef <4 x float> @"?test_pow_float4@@YAT?$__vector@M$03@__clang@@T12@0@Z"(
// CHECK: call <4 x float> @llvm.pow.v4f32
float4 test_pow_float4(float4 p0, float4 p1)
{
return pow(p0, p1);
}

// CHECK: define noundef double @"?test_pow_double@@YANNN@Z"(
// CHECK: call double @llvm.pow.f64(
double test_pow_double(double p0, double p1)
{
return pow(p0, p1);
}
// CHECK: define noundef <2 x double> @"?test_pow_double2@@YAT?$__vector@N$01@__clang@@T12@0@Z"(
// CHECK: call <2 x double> @llvm.pow.v2f64
double2 test_pow_double2(double2 p0, double2 p1)
{
return pow(p0, p1);
}
// CHECK: define noundef <3 x double> @"?test_pow_double3@@YAT?$__vector@N$02@__clang@@T12@0@Z"(
// CHECK: call <3 x double> @llvm.pow.v3f64
double3 test_pow_double3(double3 p0, double3 p1)
{
return pow(p0, p1);
}
// CHECK: define noundef <4 x double> @"?test_pow_double4@@YAT?$__vector@N$03@__clang@@T12@0@Z"(
// CHECK: call <4 x double> @llvm.pow.v4f64
double4 test_pow_double4(double4 p0, double4 p1)
{
return pow(p0, p1);
}

0 comments on commit df5137e

Please sign in to comment.