-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Add length builtins and length HLSL function to DirectX Backend #101256
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
7027cf2
fc20777
08110b7
2fa4ffd
fa06012
46dec9d
0af5ca8
8857963
9ac2968
2f7f10d
b620bab
3eab70e
d04a061
dc3a89d
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,73 @@ | ||
// 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: call half @llvm.fabs.f16(half | ||
// NO_HALF: call float @llvm.fabs.f32(float | ||
// NATIVE_HALF: ret half | ||
// NO_HALF: ret float | ||
half test_length_half(half p0) | ||
{ | ||
return length(p0); | ||
} | ||
// NATIVE_HALF: define noundef half @ | ||
// NATIVE_HALF: %hlsl.length = call half @llvm.dx.length.v2f16 | ||
// NO_HALF: %hlsl.length = call float @llvm.dx.length.v2f32( | ||
// NATIVE_HALF: ret half %hlsl.length | ||
// NO_HALF: ret float %hlsl.length | ||
half test_length_half2(half2 p0) | ||
{ | ||
return length(p0); | ||
} | ||
// NATIVE_HALF: define noundef half @ | ||
// NATIVE_HALF: %hlsl.length = call half @llvm.dx.length.v3f16 | ||
// NO_HALF: %hlsl.length = call float @llvm.dx.length.v3f32( | ||
// NATIVE_HALF: ret half %hlsl.length | ||
// NO_HALF: ret float %hlsl.length | ||
half test_length_half3(half3 p0) | ||
{ | ||
return length(p0); | ||
} | ||
// NATIVE_HALF: define noundef half @ | ||
// NATIVE_HALF: %hlsl.length = call half @llvm.dx.length.v4f16 | ||
// NO_HALF: %hlsl.length = call float @llvm.dx.length.v4f32( | ||
// NATIVE_HALF: ret half %hlsl.length | ||
// NO_HALF: ret float %hlsl.length | ||
half test_length_half4(half4 p0) | ||
{ | ||
return length(p0); | ||
} | ||
|
||
// CHECK: define noundef float @ | ||
// CHECK: call float @llvm.fabs.f32(float | ||
// CHECK: ret float | ||
float test_length_float(float p0) | ||
{ | ||
return length(p0); | ||
} | ||
// CHECK: define noundef float @ | ||
// CHECK: %hlsl.length = call float @llvm.dx.length.v2f32( | ||
// CHECK: ret float %hlsl.length | ||
float test_length_float2(float2 p0) | ||
{ | ||
return length(p0); | ||
} | ||
// CHECK: define noundef float @ | ||
// CHECK: %hlsl.length = call float @llvm.dx.length.v3f32( | ||
// CHECK: ret float %hlsl.length | ||
float test_length_float3(float3 p0) | ||
{ | ||
return length(p0); | ||
} | ||
// CHECK: define noundef float @ | ||
// CHECK: %hlsl.length = call float @llvm.dx.length.v4f32( | ||
// CHECK: ret float %hlsl.length | ||
float test_length_float4(float4 p0) | ||
{ | ||
return length(p0); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// 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 | ||
|
||
void test_too_few_arg() | ||
{ | ||
return __builtin_hlsl_length(); | ||
// expected-error@-1 {{too few arguments to function call, expected 1, have 0}} | ||
} | ||
|
||
void test_too_many_arg(float2 p0) | ||
{ | ||
return __builtin_hlsl_length(p0, p0); | ||
// expected-error@-1 {{too many arguments to function call, expected 1, have 2}} | ||
} | ||
|
||
bool builtin_bool_to_float_type_promotion(bool p1) | ||
{ | ||
return __builtin_hlsl_length(p1); | ||
// expected-error@-1 {passing 'bool' to parameter of incompatible type 'float'}} | ||
} | ||
|
||
bool builtin_length_int_to_float_promotion(int p1) | ||
{ | ||
return __builtin_hlsl_length(p1); | ||
// expected-error@-1 {{passing 'int' to parameter of incompatible type 'float'}} | ||
} | ||
|
||
bool2 builtin_length_int2_to_float2_promotion(int2 p1) | ||
{ | ||
return __builtin_hlsl_length(p1); | ||
// expected-error@-1 {{passing 'int2' (aka 'vector<int, 2>') to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(float)))) float' (vector of 2 'float' values)}} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,5 +63,6 @@ let TargetPrefix = "spv" in { | |
def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]>; | ||
def int_spv_lerp : Intrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>], | ||
[IntrNoMem, IntrWillReturn] >; | ||
def int_spv_length : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], [llvm_anyfloat_ty]>; | ||
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. I thought this change didn't include the SPIRV parts of this? 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. He has to define this because of |
||
def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK | ||
; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK | ||
|
||
; Make sure dxil operation function calls for length are generated for half/float. | ||
|
||
declare half @llvm.fabs.f16(half) | ||
farzonl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
declare half @llvm.dx.length.v2f16(<2 x half>) | ||
declare half @llvm.dx.length.v3f16(<3 x half>) | ||
declare half @llvm.dx.length.v4f16(<4 x half>) | ||
|
||
declare float @llvm.fabs.f32(float) | ||
declare float @llvm.dx.length.v2f32(<2 x float>) | ||
declare float @llvm.dx.length.v3f32(<3 x float>) | ||
declare float @llvm.dx.length.v4f32(<4 x float>) | ||
|
||
define noundef half @test_length_half2(<2 x half> noundef %p0) { | ||
entry: | ||
; CHECK: extractelement <2 x half> %{{.*}}, i64 0 | ||
; CHECK: fmul half %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <2 x half> %{{.*}}, i64 1 | ||
; CHECK: fmul half %{{.*}}, %{{.*}} | ||
; CHECK: fadd half %{{.*}}, %{{.*}} | ||
; EXPCHECK: call half @llvm.sqrt.f16(half %{{.*}}) | ||
; DOPCHECK: call half @dx.op.unary.f16(i32 24, half %{{.*}}) | ||
|
||
%hlsl.length = call half @llvm.dx.length.v2f16(<2 x half> %p0) | ||
ret half %hlsl.length | ||
} | ||
|
||
define noundef half @test_length_half3(<3 x half> noundef %p0) { | ||
entry: | ||
; CHECK: extractelement <3 x half> %{{.*}}, i64 0 | ||
; CHECK: fmul half %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <3 x half> %{{.*}}, i64 1 | ||
; CHECK: fmul half %{{.*}}, %{{.*}} | ||
; CHECK: fadd half %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <3 x half> %{{.*}}, i64 2 | ||
; CHECK: fmul half %{{.*}}, %{{.*}} | ||
; CHECK: fadd half %{{.*}}, %{{.*}} | ||
; EXPCHECK: call half @llvm.sqrt.f16(half %{{.*}}) | ||
; DOPCHECK: call half @dx.op.unary.f16(i32 24, half %{{.*}}) | ||
|
||
%hlsl.length = call half @llvm.dx.length.v3f16(<3 x half> %p0) | ||
ret half %hlsl.length | ||
} | ||
|
||
define noundef half @test_length_half4(<4 x half> noundef %p0) { | ||
entry: | ||
; CHECK: extractelement <4 x half> %{{.*}}, i64 0 | ||
; CHECK: fmul half %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <4 x half> %{{.*}}, i64 1 | ||
; CHECK: fmul half %{{.*}}, %{{.*}} | ||
; CHECK: fadd half %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <4 x half> %{{.*}}, i64 2 | ||
; CHECK: fmul half %{{.*}}, %{{.*}} | ||
; CHECK: fadd half %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <4 x half> %{{.*}}, i64 3 | ||
; CHECK: fmul half %{{.*}}, %{{.*}} | ||
; CHECK: fadd half %{{.*}}, %{{.*}} | ||
; EXPCHECK: call half @llvm.sqrt.f16(half %{{.*}}) | ||
; DOPCHECK: call half @dx.op.unary.f16(i32 24, half %{{.*}}) | ||
|
||
%hlsl.length = call half @llvm.dx.length.v4f16(<4 x half> %p0) | ||
ret half %hlsl.length | ||
} | ||
|
||
define noundef float @test_length_float2(<2 x float> noundef %p0) { | ||
entry: | ||
; CHECK: extractelement <2 x float> %{{.*}}, i64 0 | ||
; CHECK: fmul float %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <2 x float> %{{.*}}, i64 1 | ||
; CHECK: fmul float %{{.*}}, %{{.*}} | ||
; CHECK: fadd float %{{.*}}, %{{.*}} | ||
; EXPCHECK: call float @llvm.sqrt.f32(float %{{.*}}) | ||
; DOPCHECK: call float @dx.op.unary.f32(i32 24, float %{{.*}}) | ||
|
||
%hlsl.length = call float @llvm.dx.length.v2f32(<2 x float> %p0) | ||
ret float %hlsl.length | ||
} | ||
|
||
define noundef float @test_length_float3(<3 x float> noundef %p0) { | ||
entry: | ||
; CHECK: extractelement <3 x float> %{{.*}}, i64 0 | ||
; CHECK: fmul float %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <3 x float> %{{.*}}, i64 1 | ||
; CHECK: fmul float %{{.*}}, %{{.*}} | ||
; CHECK: fadd float %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <3 x float> %{{.*}}, i64 2 | ||
; CHECK: fmul float %{{.*}}, %{{.*}} | ||
; CHECK: fadd float %{{.*}}, %{{.*}} | ||
; EXPCHECK: call float @llvm.sqrt.f32(float %{{.*}}) | ||
; DOPCHECK: call float @dx.op.unary.f32(i32 24, float %{{.*}}) | ||
|
||
%hlsl.length = call float @llvm.dx.length.v3f32(<3 x float> %p0) | ||
ret float %hlsl.length | ||
} | ||
|
||
define noundef float @test_length_float4(<4 x float> noundef %p0) { | ||
entry: | ||
; CHECK: extractelement <4 x float> %{{.*}}, i64 0 | ||
; CHECK: fmul float %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <4 x float> %{{.*}}, i64 1 | ||
; CHECK: fmul float %{{.*}}, %{{.*}} | ||
; CHECK: fadd float %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <4 x float> %{{.*}}, i64 2 | ||
; CHECK: fmul float %{{.*}}, %{{.*}} | ||
; CHECK: fadd float %{{.*}}, %{{.*}} | ||
; CHECK: extractelement <4 x float> %{{.*}}, i64 3 | ||
; CHECK: fmul float %{{.*}}, %{{.*}} | ||
; CHECK: fadd float %{{.*}}, %{{.*}} | ||
; EXPCHECK: call float @llvm.sqrt.f32(float %{{.*}}) | ||
; DOPCHECK: call float @dx.op.unary.f32(i32 24, float %{{.*}}) | ||
|
||
%hlsl.length = call float @llvm.dx.length.v4f32(<4 x float> %p0) | ||
ret float %hlsl.length | ||
} |
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.
PR title looks like it may be misnamed, since this is also adding the HLSL builtin functions, it is doing more than just adding it to the backend.