-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[HLSL] Enable unbounded resource arrays at global scope #155053
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
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
75a7511
[HLSL] Codegen for indexing of sub-arrays of multi-dimensional resour…
hekota 7afa5cc
[HLSL] Enable unbounded resource arrays at global scope
hekota ad85d72
code review feedback - use dyncast
hekota 0379f42
Merge branch 'main' of https://github.com/llvm/llvm-project into reso…
hekota fb1d14f
clang-format
hekota 9772c73
Update comment in test to explain index calculation
hekota File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
64 changes: 64 additions & 0 deletions
64
clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -finclude-default-header \ | ||
// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -check-prefixes=CHECK,DXIL | ||
// RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute \ | ||
// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -check-prefixes=CHECK,SPV | ||
|
||
// CHECK: @[[BufA:.*]] = private unnamed_addr constant [2 x i8] c"A\00", align 1 | ||
// CHECK: @[[BufB:.*]] = private unnamed_addr constant [2 x i8] c"B\00", align 1 | ||
|
||
RWBuffer<float> A[] : register(u10, space1); | ||
RWBuffer<int> B[][5][4]; | ||
|
||
RWStructuredBuffer<float> Out; | ||
|
||
float foo(RWBuffer<int> Arr[4], uint Index) { | ||
return (float)Arr[Index][0]; | ||
} | ||
|
||
// NOTE: | ||
// - _ZN4hlsl8RWBufferIfEC1EjjijPKc is the constructor call for explicit binding for RWBuffer<float> | ||
// (has "jjij" in the mangled name) and the arguments are (register, space, range_size, index, name). | ||
// - _ZN4hlsl8RWBufferIiEC1EjijjPKc is the constructor call for implicit binding for RWBuffer<int> | ||
// (has "jijj" in the mangled name) and the arguments are (space, range_size, index, order_id, name). | ||
// - _ZN4hlsl8RWBufferIfEixEj is the subscript operator on RWBuffer<float> | ||
|
||
[numthreads(4,1,1)] | ||
void main(uint GI : SV_GroupIndex) { | ||
// CHECK: define internal {{.*}}void @_Z4mainj(i32 noundef %GI) | ||
// CHECK: %[[GI_alloca:.*]] = alloca i32, align 4 | ||
// CHECK-NEXT: %a = alloca float, align 4 | ||
// CHECK-NEXT: %[[Tmp0:.*]] = alloca %"class.hlsl::RWBuffer | ||
// CHECK-NEXT: %b = alloca float, align 4 | ||
// CHECK-NEXT: %[[Tmp1:.*]] = alloca [4 x %"class.hlsl::RWBuffer"] | ||
// CHECK-NEXT: %[[Tmp2:.*]] = alloca [4 x %"class.hlsl::RWBuffer"] | ||
// CHECK-NEXT: store i32 %GI, ptr %[[GI_alloca]], align 4 | ||
|
||
// Make sure A[100] is translated to a RWBuffer<float> constructor call with range -1 and index 100 | ||
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. Using |
||
// and explicit binding (u10, space1) | ||
// CHECK: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Tmp0]], i32 noundef 10, i32 noundef 1, i32 noundef -1, i32 noundef 100, ptr noundef @A.str) | ||
// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr{{.*}} @_ZN4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[Tmp0]], i32 noundef 0) | ||
// CHECK-NEXT: %[[Value1:.*]] = load float, ptr{{.*}} %[[BufPtr]], align 4 | ||
// CHECK-NEXT: store float %[[Value1]], ptr %a, align 4 | ||
float a = A[100][0]; | ||
|
||
// Make sure B[2][3] is translated to a local RWBuffer<int>[4] array where each array element | ||
// is initialized by a constructor call with range -1 and index 52-54 | ||
hekota marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
// and implicit binding (space 0, order_id 0) | ||
// CHECK-NEXT: %[[Ptr_Tmp2_0:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 0 | ||
// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1EjijjPKc(ptr {{.*}} %[[Ptr_Tmp2_0]], i32 noundef 0, i32 noundef -1, i32 noundef 52, i32 noundef 0, ptr noundef @B.str) | ||
// CHECK-NEXT: %[[Ptr_Tmp2_1:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 1 | ||
// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1EjijjPKc(ptr {{.*}} %[[Ptr_Tmp2_1]], i32 noundef 0, i32 noundef -1, i32 noundef 53, i32 noundef 0, ptr noundef @B.str) | ||
// CHECK-NEXT: %[[Ptr_Tmp2_2:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 2 | ||
// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1EjijjPKc(ptr {{.*}} %[[Ptr_Tmp2_2]], i32 noundef 0, i32 noundef -1, i32 noundef 54, i32 noundef 0, ptr noundef @B.str) | ||
// CHECK-NEXT: %[[Ptr_Tmp2_3:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 3 | ||
// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1EjijjPKc(ptr {{.*}} %[[Ptr_Tmp2_3]], i32 noundef 0, i32 noundef -1, i32 noundef 55, i32 noundef 0, ptr noundef @B.str) | ||
// DXIL-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Tmp1]], ptr align 4 %[[Tmp2]], i32 16, i1 false) | ||
// SPV-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[Tmp1]], ptr align 8 %[[Tmp2]], i64 32, i1 false) | ||
// CHECK-NEXT: %[[GI:.*]] = load i32, ptr %[[GI_alloca]], align 4 | ||
// DXIL-NEXT: %[[Value2:.*]] = call {{.*}} float @_Z3fooA4_N4hlsl8RWBufferIiEEj(ptr noundef byval([4 x %"class.hlsl::RWBuffer"]) align 4 %[[Tmp1]], i32 noundef %[[GI]]) | ||
// SPV-NEXT: %[[Value2:.*]] = call {{.*}} float @_Z3fooA4_N4hlsl8RWBufferIiEEj(ptr noundef byval([4 x %"class.hlsl::RWBuffer"]) align 8 %[[Tmp1]], i32 noundef %[[GI]]) | ||
// CHECK-NEXT: store float %[[Value2]], ptr %b, align 4 | ||
float b = foo(B[2][3], GI); | ||
|
||
Out[0] = a + b; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// RUN: not %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -finclude-default-header --o - %s -verify | ||
|
||
// unbounded resource array at a global scope | ||
RWBuffer<float> unbounded_array[]; // no_error | ||
|
||
// expected-error@+1 {{incomplete resource array in a function parameter}} | ||
void foo(RWBuffer<float> array_arg[]) {} | ||
|
||
RWBuffer<float> A, B; | ||
|
||
[numthreads(4,1,1)] | ||
void main() { | ||
// expected-error@+1{{definition of variable with array type needs an explicit size or an initializer}} | ||
RWBuffer<float> res_local_array1[]; | ||
|
||
// expected-error@+1{{array initializer must be an initialzer list}} | ||
RWBuffer<float> res_local_array2[] = unbounded_array; | ||
|
||
// local incomplete resource array with initializer | ||
RWBuffer<float> res_local_array3[] = { A, B }; // no error | ||
} |
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.
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.
Can we/should we pipe to
llvm-cxxfilt
in the RUN lines so this explanation isn't necessary? I see some precedent for that in otherclang/test/CodeGen*
tests...Uh oh!
There was an error while loading. Please reload this page.
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.
Good idea! If it's ok with you, I would add the
llvm-cxxfilt
filter as part of the change to use static create methods because that change will be removing these lines anyway.