-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[HLSL] implement exp intrinsic #83832
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-backend-directx @llvm/pr-subscribers-backend-x86 Author: Farzon Lotfi (farzonl) ChangesThis change implements: #70072
Full diff: https://github.com/llvm/llvm-project/pull/83832.diff 5 Files Affected:
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 5180530363889f..acbc21ba548bc4 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -277,6 +277,38 @@ uint64_t dot(uint64_t3, uint64_t3);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
uint64_t dot(uint64_t4, uint64_t4);
+//===----------------------------------------------------------------------===//
+// exp builtins
+//===----------------------------------------------------------------------===//
+
+/// \fn T exp(T x)
+/// \brief Returns the base-e exponential, or \a e**x, of the specified value.
+/// \param x The specified input value.
+///
+/// The return value is the base-e exponential of the \a x parameter.
+
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp)
+half exp(half);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp)
+half2 exp(half2);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp)
+half3 exp(half3);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp)
+half4 exp(half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp)
+float exp(float);
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp)
+float2 exp(float2);
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp)
+float3 exp(float3);
+_HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp)
+float4 exp(float4);
+
//===----------------------------------------------------------------------===//
// floor builtins
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CodeGenHLSL/builtins/exp.hlsl b/clang/test/CodeGenHLSL/builtins/exp.hlsl
new file mode 100644
index 00000000000000..773edbe3364fd2
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/exp.hlsl
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: --check-prefixes=CHECK,NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF
+
+// NATIVE_HALF: define noundef half @
+// NATIVE_HALF: %elt.exp = call half @llvm.exp.f16(
+// NATIVE_HALF: ret half %elt.exp
+// NO_HALF: define noundef float @"?test_exp_half@@YA$halff@$halff@@Z"(
+// NO_HALF: %elt.exp = call float @llvm.exp.f32(
+// NO_HALF: ret float %elt.exp
+half test_exp_half(half p0) { return exp(p0); }
+// NATIVE_HALF: define noundef <2 x half> @
+// NATIVE_HALF: %elt.exp = call <2 x half> @llvm.exp.v2f16
+// NATIVE_HALF: ret <2 x half> %elt.exp
+// NO_HALF: define noundef <2 x float> @
+// NO_HALF: %elt.exp = call <2 x float> @llvm.exp.v2f32(
+// NO_HALF: ret <2 x float> %elt.exp
+half2 test_exp_half2(half2 p0) { return exp(p0); }
+// NATIVE_HALF: define noundef <3 x half> @
+// NATIVE_HALF: %elt.exp = call <3 x half> @llvm.exp.v3f16
+// NATIVE_HALF: ret <3 x half> %elt.exp
+// NO_HALF: define noundef <3 x float> @
+// NO_HALF: %elt.exp = call <3 x float> @llvm.exp.v3f32(
+// NO_HALF: ret <3 x float> %elt.exp
+half3 test_exp_half3(half3 p0) { return exp(p0); }
+// NATIVE_HALF: define noundef <4 x half> @
+// NATIVE_HALF: %elt.exp = call <4 x half> @llvm.exp.v4f16
+// NATIVE_HALF: ret <4 x half> %elt.exp
+// NO_HALF: define noundef <4 x float> @
+// NO_HALF: %elt.exp = call <4 x float> @llvm.exp.v4f32(
+// NO_HALF: ret <4 x float> %elt.exp
+half4 test_exp_half4(half4 p0) { return exp(p0); }
+
+// CHECK: define noundef float @
+// CHECK: %elt.exp = call float @llvm.exp.f32(
+// CHECK: ret float %elt.exp
+float test_exp_float(float p0) { return exp(p0); }
+// CHECK: define noundef <2 x float> @
+// CHECK: %elt.exp = call <2 x float> @llvm.exp.v2f32
+// CHECK: ret <2 x float> %elt.exp
+float2 test_exp_float2(float2 p0) { return exp(p0); }
+// CHECK: define noundef <3 x float> @
+// CHECK: %elt.exp = call <3 x float> @llvm.exp.v3f32
+// CHECK: ret <3 x float> %elt.exp
+float3 test_exp_float3(float3 p0) { return exp(p0); }
+// CHECK: define noundef <4 x float> @
+// CHECK: %elt.exp = call <4 x float> @llvm.exp.v4f32
+// CHECK: ret <4 x float> %elt.exp
+float4 test_exp_float4(float4 p0) { return exp(p0); }
diff --git a/clang/test/SemaHLSL/BuiltIns/exp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/exp-errors.hlsl
new file mode 100644
index 00000000000000..60ba2dfbb48263
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/exp-errors.hlsl
@@ -0,0 +1,27 @@
+
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected
+
+float test_too_few_arg() {
+ return __builtin_elementwise_exp();
+ // expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
+}
+
+float2 test_too_many_arg(float2 p0) {
+ return __builtin_elementwise_exp(p0, p0);
+ // expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
+}
+
+float builtin_bool_to_float_type_promotion(bool p1) {
+ return __builtin_elementwise_exp(p1);
+ // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'bool')}}
+}
+
+float builtin_exp_int_to_float_promotion(int p1) {
+ return __builtin_elementwise_exp(p1);
+ // expected-error@-1 {{1st argument must be a floating point type (was 'int')}}
+}
+
+float2 builtin_exp_int2_to_float2_promotion(int2 p1) {
+ return __builtin_elementwise_exp(p1);
+ // expected-error@-1 {{1st argument must be a floating point type (was 'int2' (aka 'vector<int, 2>'))}}
+}
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 33b08ed93e3d0a..31f32ab750e45a 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -218,6 +218,9 @@ class DXILOpMapping<int opCode, DXILOpClass opClass, Intrinsic intrinsic, string
// Concrete definition of DXIL Operation mapping to corresponding LLVM intrinsic
def Sin : DXILOpMapping<13, unary, int_sin,
"Returns sine(theta) for theta in radians.">;
+def Exp : DXILOpMapping<21, unary, int_exp,
+ "Returns the base-e exponential of the x parameter."
+ "exp(x) = e**x.">;
def Frac : DXILOpMapping<22, unary, int_dx_frac,
"Returns a fraction from 0 to 1 that represents the "
"decimal part of the input.">;
diff --git a/llvm/test/CodeGen/DirectX/exp.ll b/llvm/test/CodeGen/DirectX/exp.ll
new file mode 100644
index 00000000000000..ec7bdcdf347982
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/exp.ll
@@ -0,0 +1,31 @@
+; RUN: opt -S -dxil-op-lower < %s | FileCheck %s
+
+; Make sure dxil operation function calls for exp are generated for float and half.
+; CHECK:call float @dx.op.unary.f32(i32 21, float %{{.*}})
+; CHECK:call half @dx.op.unary.f16(i32 21, half %{{.*}})
+
+target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-pc-shadermodel6.7-library"
+
+; Function Attrs: noinline nounwind optnone
+define noundef float @exp_float(float noundef %a) #0 {
+entry:
+ %a.addr = alloca float, align 4
+ store float %a, ptr %a.addr, align 4
+ %0 = load float, ptr %a.addr, align 4
+ %elt.exp = call float @llvm.exp.f32(float %0)
+ ret float %elt.exp
+}
+
+; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn
+declare float @llvm.exp.f32(float) #1
+
+; Function Attrs: noinline nounwind optnone
+define noundef half @exp_half(half noundef %a) #0 {
+entry:
+ %a.addr = alloca half, align 2
+ store half %a, ptr %a.addr, align 2
+ %0 = load half, ptr %a.addr, align 2
+ %elt.exp = call half @llvm.exp.f16(half %0)
+ ret half %elt.exp
+}
|
python3kgae
reviewed
Mar 4, 2024
This change implements: llvm#70072 hlsl_intrinsics.h - add the exp api DXIL.td add the llvm intrinsic to DXIL opcode lowering mapping This change reuses llvm's existing intrinsic __builtin_elementwise_exp\ int_exp
…dle exp via instruction expansion
9f894dc
to
371bbef
Compare
python3kgae
approved these changes
Mar 4, 2024
bogner
approved these changes
Mar 5, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
backend:DirectX
clang:headers
Headers provided by Clang, e.g. for intrinsics
clang
Clang issues not falling into any other category
HLSL
HLSL Language Support
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This change implements: #70072
hlsl_intrinsics.h
- add theexp
apiDXIL.td
- add the llvm intrinsic to DXIL opcode lowering mapping.__builtin_elementwise_exp
\int_exp
&__builtin_elementwise_exp2
\int_exp2
Part2 will expand
int_exp
tojust like we do in TranslateExp