-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[HLSL] Implement the ldexp
intrinsic
#138182
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s | ||
|
||
// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) half @_ZN4hlsl8__detail10ldexp_implIDhEET_S2_S2_ | ||
// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn half @llvm.exp2.f16(half %{{.*}}) | ||
// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn half %elt.exp2, %{{.*}} | ||
// CHECK: ret half %mul | ||
half test_ldexp_half(half X, half Exp) { return ldexp(X, Exp); } | ||
|
||
// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <2 x half> @_ZN4hlsl8__detail10ldexp_implIDv2_DhEET_S3_S3_ | ||
// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp2.v2f16(<2 x half> %{{.*}}) | ||
// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <2 x half> %elt.exp2, %{{.*}} | ||
// CHECK: ret <2 x half> %mul | ||
half2 test_ldexp_half2(half2 X, half2 Exp) { return ldexp(X, Exp); } | ||
|
||
// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <3 x half> @_ZN4hlsl8__detail10ldexp_implIDv3_DhEET_S3_S3_ | ||
// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp2.v3f16(<3 x half> %{{.*}}) | ||
// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <3 x half> %elt.exp2, %{{.*}} | ||
// CHECK: ret <3 x half> %mul | ||
half3 test_ldexp_half3(half3 X, half3 Exp) { return ldexp(X, Exp); } | ||
|
||
// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <4 x half> @_ZN4hlsl8__detail10ldexp_implIDv4_DhEET_S3_S3_ | ||
// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp2.v4f16(<4 x half> %{{.*}}) | ||
// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <4 x half> %elt.exp2, %{{.*}} | ||
// CHECK: ret <4 x half> %mul | ||
half4 test_ldexp_half4(half4 X, half4 Exp) { return ldexp(X, Exp); } | ||
|
||
// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) float @_ZN4hlsl8__detail10ldexp_implIfEET_S2_S2_ | ||
// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32(float %{{.*}}) | ||
// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn float %elt.exp2, %{{.*}} | ||
// CHECK: ret float %mul | ||
float test_ldexp_float(float X, float Exp) { return ldexp(X, Exp); } | ||
|
||
// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <2 x float> @_ZN4hlsl8__detail10ldexp_implIDv2_fEET_S3_S3_ | ||
// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32(<2 x float> %{{.*}}) | ||
// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <2 x float> %elt.exp2, %{{.*}} | ||
// CHECK: ret <2 x float> %mul | ||
float2 test_ldexp_float2(float2 X, float2 Exp) { return ldexp(X, Exp); } | ||
|
||
// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <3 x float> @_ZN4hlsl8__detail10ldexp_implIDv3_fEET_S3_S3_ | ||
// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32(<3 x float> %{{.*}}) | ||
// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <3 x float> %elt.exp2, %{{.*}} | ||
// CHECK: ret <3 x float> %mul | ||
float3 test_ldexp_float3(float3 X, float3 Exp) { return ldexp(X, Exp); } | ||
|
||
// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <4 x float> @_ZN4hlsl8__detail10ldexp_implIDv4_fEET_S3_S3_ | ||
// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32(<4 x float> %{{.*}}) | ||
// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <4 x float> %elt.exp2, %{{.*}} | ||
// CHECK: ret <4 x float> %mul | ||
float4 test_ldexp_float4(float4 X, float4 Exp) { return ldexp(X, Exp); } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify | ||
|
||
float test_double_inputs(double p0, double p1) { | ||
return ldexp(p0, p1); | ||
// expected-error@-1 {{no matching function for call to 'ldexp'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it worth including these notes in these tests? They don't seem valuable to me, and can be excluded with -verify-ignore-unexpected=note There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea the notes don't seem worthwhile to include. They're more distracting than anything useful. Plus, I don't see any other tests checking for notes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ignoring notes will also ignore the template substitution notes which explains the no matching function error for vec5 call to 'ldexp'. Thats something I'd like to explicitly test for to make sure the template is behaving the way we want it to.
git grep for |
||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}} | ||
} | ||
|
||
float test_int_inputs(int p0, int p1, int p2) { | ||
return ldexp(p0, p1); | ||
// expected-error@-1 {{no matching function for call to 'ldexp'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}} | ||
} | ||
|
||
float1 test_vec1_inputs(float1 p0, float1 p1) { | ||
return ldexp(p0, p1); | ||
// expected-error@-1 {{no matching function for call to 'ldexp'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}} | ||
} | ||
|
||
typedef float float5 __attribute__((ext_vector_type(5))); | ||
|
||
float5 test_vec5_inputs(float5 p0, float5 p1) { | ||
return ldexp(p0, p1); | ||
// expected-error@-1 {{no matching function for call to 'ldexp'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 5>>'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 5>>'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}} | ||
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of the builtins that support half and float have tests with native half and without native half.
See: https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGenHLSL/builtins/cos.hlsl
Should we do that here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, to be consistent if nothing else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping we would only do those for intrinsics that require clang builtins since we define most of them as
void(...)
. for anything thats pure HLSL like this one we have extensive testing of native half.