From 7758625d3fea67e55e98e7e4103d56c9918365be Mon Sep 17 00:00:00 2001 From: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Date: Fri, 29 Aug 2025 15:52:34 -0700 Subject: [CBP] Pointer frontend changes + groupshared pointer support (#7848) Resolves #7628 Resolves: #8197 Primary Goals: 1. Add `Access` to pointer 2. AddressSpace::GroupShared support for pointers (SPIR-V) 3. Add `__getAddress()` to replace `&` * `&` is not updated to `require(cpu)` since slangpy uses `&`. This means we must: (1) merge PR; (2) replace `&` with `__getAddress()`; (3) add `require(cpu)` to `&` Changes: * Added to `Ptr` the `Access` generic argument & logic (for `Access::Read`). * Moved the generic argument `AddressSpace` from `Ptr` to the end of the type. * Added pointer casting support between any `Ptr` as long as the `AddressSpace` is the same * Disallow globallycoherent T* and coherent T* * Disallow const T*, T const*, and const T* * Fixed .natvis display of `ConstantValue` `ValOperandNode` * Support generic resolution of type-casted integers * Added `VariablePointer` emitting for spirv + other minor logic needed for groupshared pointers Breaking Changes: * Anyone using the `AddressSpace` of `Ptr` will now have to account for the `Access` argument * we disallow various syntax paired with `Ptr` and `T*` --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> --- tests/autodiff/get-offset-ptr.slang | 40 +++++------ tests/bugs/gh-3601.slang | 8 +-- .../invalid-constant-pointer-taking.slang | 16 +++-- .../bitfield/msvc-repr-mixed.slang | 13 ++-- tests/language-feature/capability/address-of.slang | 17 +++++ .../pointer/const-ptr-variations.slang | 40 +++++++++++ .../pointer/get-address-validation.slang | 82 ++++++++++++++++++++++ .../pointer/globallycoherent-ptr.slang | 20 ++++++ .../pointer/groupshared-ptr-of-device.slang | 28 ++++++++ .../pointer-access/pointer-access-frontend.slang | 14 ++++ .../pointer-access/read-only-pointer-1.slang | 41 +++++++++++ .../pointer-access/read-only-pointer-2.slang | 19 +++++ .../pointer-casting/pointer-casting-rules.slang | 51 ++++++++++++++ .../pointer/pointer-self-reference.slang | 10 +-- .../pointer/ptr-to-groupshared.slang | 30 ++++++++ tests/spirv/pointer-from-user-guide.slang | 2 +- tests/spirv/pointer.slang | 4 +- tests/spirv/ptr-vector-member.slang | 20 +++--- 18 files changed, 399 insertions(+), 56 deletions(-) create mode 100644 tests/language-feature/capability/address-of.slang create mode 100644 tests/language-feature/pointer/const-ptr-variations.slang create mode 100644 tests/language-feature/pointer/get-address-validation.slang create mode 100644 tests/language-feature/pointer/globallycoherent-ptr.slang create mode 100644 tests/language-feature/pointer/groupshared-ptr-of-device.slang create mode 100644 tests/language-feature/pointer/pointer-access/pointer-access-frontend.slang create mode 100644 tests/language-feature/pointer/pointer-access/read-only-pointer-1.slang create mode 100644 tests/language-feature/pointer/pointer-access/read-only-pointer-2.slang create mode 100644 tests/language-feature/pointer/pointer-casting/pointer-casting-rules.slang create mode 100644 tests/language-feature/pointer/ptr-to-groupshared.slang (limited to 'tests') diff --git a/tests/autodiff/get-offset-ptr.slang b/tests/autodiff/get-offset-ptr.slang index 517acb54d..e497f1e48 100644 --- a/tests/autodiff/get-offset-ptr.slang +++ b/tests/autodiff/get-offset-ptr.slang @@ -1,40 +1,32 @@ -//TEST:SIMPLE(filecheck=CHECK): -target cuda -line-directive-mode none +//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK): -cuda -output-using-type -//CHECK: struct s_bwd_prop_function_Intermediates{{[_0-9]+}} -//CHECK: { -//CHECK: MyDiffPtr{{[_0-9]+}} {{[_A-Za-z0-9]+}}; -//CHECK: MyDiffPtr{{[_0-9]+}} {{[_A-Za-z0-9]+}}; -//CHECK: }; +// This test just ensures that we compile and run the code. +// It does not check the correctness of the autodiff. //TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out, name outputBuffer RWStructuredBuffer outputBuffer; struct MyDiffPtr { - uint offset; - uint d_offset; - - [BackwardDerivative(__bwd_foo)] - float foo() - { - return outputBuffer[offset] * outputBuffer[offset]; - } - - void __bwd_foo(float grad) - { - outputBuffer[d_offset] = 2.f * outputBuffer[offset] * grad; - } + float data1; + float data2; }; [Differentiable] -float function(MyDiffPtr *i) +float function(Ptr i) { - return i[0].foo() + i[1].foo(); + return i[0].data1 + i[1].data2; } +groupshared MyDiffPtr s[2]; [numthreads(1, 1, 1), shader("compute")] -void main(uint3 dispatchThreadID: SV_DispatchThreadID) +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) { - MyDiffPtr s[2] = {{0, 2}, {1, 3}}; - __bwd_diff(function)(&s[0], 1.0f); + s = { { 0, 2 }, { 1, 3 } }; + float result = 1.0f; + let pair = __fwd_diff(function)(__getAddress(s[0])); + outputBuffer[0] = pair.getPrimal(); + outputBuffer[1] = pair.getDifferential(); + // CHECK: 3.0 + // CHECK-NEXT: 0.0 } \ No newline at end of file diff --git a/tests/bugs/gh-3601.slang b/tests/bugs/gh-3601.slang index 5d545262b..65245f971 100644 --- a/tests/bugs/gh-3601.slang +++ b/tests/bugs/gh-3601.slang @@ -4,7 +4,7 @@ struct TestStruct uint index; }; -[[vk::binding(2, 0)]] StructuredBuffer test; +[[vk::binding(2, 0)]] uniform uint64_t* test; struct PP { @@ -28,15 +28,15 @@ int* funcThatReturnsPointer(PP* p) // CHECK: OpEntryPoint -[[vk::binding(0, 0)]] StructuredBuffer buffer; +[[vk::binding(0, 0)]] uniform Data* buffer; [[vk::binding(1, 0)]] RWStructuredBuffer output; [shader("compute")] [numthreads(8, 8, 1)] void main(int id : SV_DispatchThreadID) { - TestStruct * ptr = (TestStruct *)(test[0]); + TestStruct* ptr = (TestStruct*)(test[0]); output[0] = buffer[ptr.index].pNext.data; - let pData = &(buffer[0].pNext.data); + let pData = __getAddress(buffer[0].pNext.data); // CHECK: OpPtrAccessChain int* pData1 = pData + 1; *pData1 = 3; diff --git a/tests/diagnostics/invalid-constant-pointer-taking.slang b/tests/diagnostics/invalid-constant-pointer-taking.slang index 349f8cc25..658a84b1b 100644 --- a/tests/diagnostics/invalid-constant-pointer-taking.slang +++ b/tests/diagnostics/invalid-constant-pointer-taking.slang @@ -1,4 +1,4 @@ -//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -stage compute -entry computeMain -target spirv +//TEST:SIMPLE(filecheck=CHECK): -stage compute -entry computeMain -target spirv RWStructuredBuffer mutable_float_buffer; RWStructuredBuffer mutable_uint_buffer; @@ -6,18 +6,24 @@ RWStructuredBuffer mutable_uint_buffer; StructuredBuffer constant_float_buffer; StructuredBuffer constant_uint_buffer; +// We do not allow taking a pointer from a StructuredBuffer/RWStructuredBuffer. [shader("compute")] [numthreads(1,1,1)] void computeMain(uint3 threadId : SV_DispatchThreadID) { - float* mutablePtr = &mutable_float_buffer[threadId.x]; + float* mutablePtr1 = &mutable_float_buffer[threadId.x]; + + // CHECK: ([[# @LINE+1]]): error 31160 + float* mutablePtr2 = __getAddress(mutable_float_buffer[threadId.x]); InterlockedAdd(mutable_uint_buffer[threadId.x], 1); // Constant pointers arent a thing in slang - // CHECK: error 30078: - float* ptr = &constant_float_buffer[threadId.x]; + // CHECK: ([[# @LINE+1]]): error 30079: + float* ptr1 = &constant_float_buffer[threadId.x]; + // CHECK: ([[# @LINE+1]]): error 31160 + float* ptr2 = __getAddress(constant_float_buffer[threadId.x]); InterlockedAdd(constant_uint_buffer[0], 1); -} \ No newline at end of file +} diff --git a/tests/language-feature/bitfield/msvc-repr-mixed.slang b/tests/language-feature/bitfield/msvc-repr-mixed.slang index 47f03ad1d..cf1925dd6 100644 --- a/tests/language-feature/bitfield/msvc-repr-mixed.slang +++ b/tests/language-feature/bitfield/msvc-repr-mixed.slang @@ -19,20 +19,23 @@ struct MixedSizes { uint16_t d : 8; // Same backing field }; +groupshared MixedSizes m; + +typealias GroupSharedPtr = Ptr; + [numthreads(1, 1, 1)] void computeMain() { - MixedSizes m; m.a = 0xA; m.b = 0xB; m.c = 0xCD; m.d = 0xEF; // Read the two backing fields separately - uint8_t* p8 = (uint8_t*)&m; - uint16_t* p16 = (uint16_t*)((uint8_t*)&m + 2); // Skip uint8_t + padding + GroupSharedPtr p8 = (GroupSharedPtr)__getAddress(m); + GroupSharedPtr p16 = (GroupSharedPtr)( ((GroupSharedPtr)__getAddress(m)) + 2); // Skip uint8_t + padding - outputBuffer[0] = uint(*p8); - outputBuffer[1] = uint(*p16); + outputBuffer[0] = (uint)*p8; + outputBuffer[1] = (uint)*p16; } diff --git a/tests/language-feature/capability/address-of.slang b/tests/language-feature/capability/address-of.slang new file mode 100644 index 000000000..924312b0e --- /dev/null +++ b/tests/language-feature/capability/address-of.slang @@ -0,0 +1,17 @@ +//TEST:SIMPLE(filecheck=CHECK_FAIL): -target glsl -entry computeMain -stage compute +//TEST:SIMPLE(filecheck=CHECK_PASS): -target spirv -entry computeMain -stage compute + +// Test that __getAddress correctly reports capabilities. + +uniform int* outputBuffer; +uniform int* buffer; + +// CHECK_PASS: OpEntryPoint +// CHECK_PASS-NOT: error + +// CHECK_FAIL: ([[# @LINE+1]]): error 36107{{.*}}glsl +void computeMain() +{ + // CHECK: ([[# @LINE+1]]): note: see using of '__getAddress' + outputBuffer[0] = *(__getAddress(buffer[0])); +} \ No newline at end of file diff --git a/tests/language-feature/pointer/const-ptr-variations.slang b/tests/language-feature/pointer/const-ptr-variations.slang new file mode 100644 index 000000000..a2619d6c4 --- /dev/null +++ b/tests/language-feature/pointer/const-ptr-variations.slang @@ -0,0 +1,40 @@ +//TEST:SIMPLE(filecheck=CHECK_1):-stage compute -entry computeMain -target spirv -DT1 +//TEST:SIMPLE(filecheck=CHECK_2):-stage compute -entry computeMain -target spirv -DT2 +//TEST:SIMPLE(filecheck=CHECK_3):-stage compute -entry computeMain -target spirv -DT3 +//TEST:SIMPLE(filecheck=CHECK_4):-stage compute -entry computeMain -target spirv -DT4 + +// Tests for invalid use of `const` with Ptr/T* +// Due to bad syntax breaking the parser, it is more robust to use disjoint tests with +// #define's. +cbuffer Globals +{ + int* ptr; +} + +[numthreads(1, 1, 1)] +void computeMain(int id : SV_DispatchThreadID) +{ + // disallowed syntax with modifier `const` +#ifdef T1 + // CHECK_1: ([[# @LINE+1]]): error + int const* ptr1 = ptr; +#endif + +#ifdef T2 + // CHECK_2: ([[# @LINE+1]]): error + int* const ptr2 = ptr; +#endif + +#ifdef T3 + // CHECK_3: ([[# @LINE+1]]): error 20017 + const int* ptr3 = ptr; + // CHECK_3: ([[# @LINE+1]]): error 20018 + Ptr ptr4 = ptr; +#endif + +#ifdef T4 + // CHECK_4: OpEntryPoint + // CHECK_4-NOT: error + const Ptr ptr5 = ptr; +#endif +} \ No newline at end of file diff --git a/tests/language-feature/pointer/get-address-validation.slang b/tests/language-feature/pointer/get-address-validation.slang new file mode 100644 index 000000000..3931c13a2 --- /dev/null +++ b/tests/language-feature/pointer/get-address-validation.slang @@ -0,0 +1,82 @@ +//TEST:SIMPLE(filecheck=CHECK):-stage compute -entry computeMain -target spirv + +// Tests for invalid/valid use of `__getAddress` + +struct DeviceStruct +{ + int data1; + int data2; +} + +struct StructPtrInStruct +{ + DeviceStruct* ptr; +} + +uniform int* bufferUserPointer; +RWStructuredBuffer bufferStorage; +groupshared int bufferGroupShared[100]; +uniform DeviceStruct* bufferUserPointerStruct; +uniform int2* bufferUserPointerVector; + +int* output; + +typealias GroupSharedPtr = Ptr; + +GroupSharedPtr paramGroupShared(out groupshared T[100] ptr) +{ + // CHECK: ([[# @LINE+1]]): error 30019 + T* ptr1 = __getAddress(ptr[5]); + + // CHECK-NOT: ([[# @LINE+1]]): error + GroupSharedPtr ptr2 = __getAddress(ptr[5]); + + return ptr2; +} + +[numthreads(1, 1, 1)] +void computeMain(int id : SV_DispatchThreadID) +{ + // CHECK: ([[# @LINE+1]]): error 31160 + int* ptr1 = __getAddress(bufferStorage[id.x]); + + // CHECK ([[# @LINE+1]]): error + int[100]* ptr2 = __getAddress(bufferGroupShared); + + // CHECK: ([[# @LINE+1]]): error + int* ptr3 = __getAddress(bufferGroupShared[id.x]); + + // CHECK-NOT: ([[# @LINE+1]]): error + int* ptr4 = __getAddress(bufferUserPointer[id.x]); + + // CHECK-NOT: ([[# @LINE+1]]): error + GroupSharedPtr ptr5 = __getAddress(bufferGroupShared); + + // CHECK-NOT: ([[# @LINE+1]]): error + GroupSharedPtr ptr6 = __getAddress(bufferGroupShared[id.x]); + + // CHECK-NOT: ([[# @LINE+1]]): error + GroupSharedPtr ptr7 = paramGroupShared(bufferGroupShared); + + // CHECK-NOT: ([[# @LINE+1]]): error + int* ptr8 = __getAddress(bufferUserPointerStruct.data1); + + StructPtrInStruct structPtrInStruct; + structPtrInStruct.ptr = bufferUserPointerStruct; + // CHECK-NOT: ([[# @LINE+1]]): error + int* ptr9 = __getAddress(structPtrInStruct.ptr[id.x].data1); + + // CHECK-NOT: ([[# @LINE+1]]): error + int* ptr10 = __getAddress(bufferUserPointerVector[0].x); + + output[id] = ptr1[id]; + output[id] = ptr2[id][0]; + output[id] = ptr3[id]; + output[id] = ptr4[id]; + output[id] = ptr5[id]; + output[id] = ptr6[id]; + output[id] = ptr7[id]; + output[id] = ptr8[id]; + output[id] = ptr9[id]; + output[id] = ptr10[id]; +} diff --git a/tests/language-feature/pointer/globallycoherent-ptr.slang b/tests/language-feature/pointer/globallycoherent-ptr.slang new file mode 100644 index 000000000..4909537d7 --- /dev/null +++ b/tests/language-feature/pointer/globallycoherent-ptr.slang @@ -0,0 +1,20 @@ +//TEST:SIMPLE(filecheck=CHECK):-stage compute -entry computeMain -target spirv + +// Tests for invalid use of `globallycoherent` with Ptr/T* + +cbuffer Globals +{ + // CHECK: ([[# @LINE+1]]): error 30078 + globallycoherent Ptr ptr1; + // CHECK: ([[# @LINE+1]]): error 30078 + globallycoherent int* ptr2; + // CHECK: ([[# @LINE+1]]): error 30078 + coherent Ptr ptr3; + // CHECK: ([[# @LINE+1]]): error 30078 + coherent int* ptr4; +} + +[numthreads(1, 1, 1)] +void computeMain(int id : SV_DispatchThreadID) +{ +} diff --git a/tests/language-feature/pointer/groupshared-ptr-of-device.slang b/tests/language-feature/pointer/groupshared-ptr-of-device.slang new file mode 100644 index 000000000..31703819e --- /dev/null +++ b/tests/language-feature/pointer/groupshared-ptr-of-device.slang @@ -0,0 +1,28 @@ +//TEST:SIMPLE(filecheck=SPIRV):-stage compute -entry computeMain -target spirv -capability vk_mem_model+sm_6_0+spvGroupNonUniformBallot +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-vk -output-using-type -emit-spirv-directly -capability vk_mem_model+sm_6_0+spvGroupNonUniformBallot + +// Tests if we pass-through and handle pointers via groupshared-memory correctly. +// Ensure SPIRV emits coherent operations here +// SPIRV: OpEntryPoint +// SPIRV-NOT: error + +// CHECK: 1 +// CHECK-NEXT: 0 +// CHECK-NEXT: 2 +// CHECK-NEXT: 0 +// CHECK-NEXT: 3 + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0], stride=4):out,name=outputBuffer +uniform int* outputBuffer; + +groupshared int* sharedPtr[3]; + +[numthreads(3, 1, 1)] +void computeMain(uint3 group_thread_id: SV_GroupThreadID) +{ + sharedPtr[group_thread_id.x] = outputBuffer + group_thread_id.x; + sharedPtr[group_thread_id.x] = sharedPtr[group_thread_id.x]+group_thread_id.x; + GroupMemoryBarrierWithGroupSync(); + + *sharedPtr[group_thread_id.x] = group_thread_id.x+1; +} \ No newline at end of file diff --git a/tests/language-feature/pointer/pointer-access/pointer-access-frontend.slang b/tests/language-feature/pointer/pointer-access/pointer-access-frontend.slang new file mode 100644 index 000000000..98a2a076d --- /dev/null +++ b/tests/language-feature/pointer/pointer-access/pointer-access-frontend.slang @@ -0,0 +1,14 @@ +//TEST:SIMPLE(filecheck=CHECK):-stage compute -entry computeMain -target spirv + +//CHECK: OpEntryPoint +//CHECK-NOT: error + +int* processMemory; +int* output; + +[numthreads(1, 1, 1)] +void computeMain(int id : SV_DispatchThreadID) +{ + Ptr ptr1 = processMemory + id.x + 5; + Ptr ptr2 = processMemory + id.x + 4; +} \ No newline at end of file diff --git a/tests/language-feature/pointer/pointer-access/read-only-pointer-1.slang b/tests/language-feature/pointer/pointer-access/read-only-pointer-1.slang new file mode 100644 index 000000000..e7f1ad534 --- /dev/null +++ b/tests/language-feature/pointer/pointer-access/read-only-pointer-1.slang @@ -0,0 +1,41 @@ +//TEST:SIMPLE(filecheck=CHECK):-stage compute -entry computeMain -target spirv + +// Writing with a read-only pointer should be an error + +int* processMemory; +RWStructuredBuffer output; + +typealias ReadPtr = Ptr; + +void writeToReadOnlyPointer(ReadPtr ptr) +{ + // CHECK: ([[# @LINE+1]]): error 30011 + ptr[0] = 1; +} + +void writeToReadOnlyPointerOut(out int ptrVal) +{ + ptrVal = 1; +} + +[numthreads(1, 1, 1)] +void computeMain(int id : SV_DispatchThreadID) +{ + // CHECK-NOT: ([[# @LINE+1]]): error + ReadPtr ptr1 = ReadPtr(processMemory + id.x); + + // CHECK: ([[# @LINE+1]]): error 30011 + ptr1[id + 1] = 1; + // CHECK: ([[# @LINE+1]]): error 30011 + *ptr1 = 1; + + writeToReadOnlyPointer(ptr1); + + // CHECK: ([[# @LINE+1]]): error 30047 + writeToReadOnlyPointerOut(ptr1[1]); + + // CHECK: ([[# @LINE+1]]): error 30047 + writeToReadOnlyPointerOut(*(ptr1+2)); + + output[id] = ptr1[id]; +} diff --git a/tests/language-feature/pointer/pointer-access/read-only-pointer-2.slang b/tests/language-feature/pointer/pointer-access/read-only-pointer-2.slang new file mode 100644 index 000000000..c5288caba --- /dev/null +++ b/tests/language-feature/pointer/pointer-access/read-only-pointer-2.slang @@ -0,0 +1,19 @@ +//TEST:SIMPLE(filecheck=CHECK):-stage compute -entry computeMain -target spirv + +// Tests valid use of read-only pointer + +// CHECK: OpEntryPoint +// CHECK-NOT: error + +int* processMemory; +int* output; + +typealias ReadPtr = Ptr; + +[numthreads(1, 1, 1)] +void computeMain(int id : SV_DispatchThreadID) +{ + ReadPtr ptr1 = ReadPtr(processMemory + id.x); + + output[id] = ptr1[id]; +} diff --git a/tests/language-feature/pointer/pointer-casting/pointer-casting-rules.slang b/tests/language-feature/pointer/pointer-casting/pointer-casting-rules.slang new file mode 100644 index 000000000..d0a016fe5 --- /dev/null +++ b/tests/language-feature/pointer/pointer-casting/pointer-casting-rules.slang @@ -0,0 +1,51 @@ +//TEST:SIMPLE(filecheck=CHECK):-stage compute -entry computeMain -target spirv + +// Tests pointer casting rules: Only explicit casting is allowed between pointer types. +// All implicit conversions between pointer types should fail. +int* processMemory; +RWStructuredBuffer output; + +[numthreads(1, 1, 1)] +void computeMain(int id : SV_DispatchThreadID) +{ + // regular address-of + // CHECK-NOT: ([[# @LINE+1]]): error + Ptr rwPtr = processMemory + id.x; + // copying a pointer of T* syntax + // CHECK-NOT: ([[# @LINE+1]]): error + Ptr copiedPtrOfLegacySyntax = processMemory; + // casting to Read ptr + // CHECK-NOT: ([[# @LINE+1]]): error + Ptr rPtr = Ptr(processMemory + id.x); + + // casting to RW ptr from a R ptr + // CHECK-NOT: ([[# @LINE+1]]): error + Ptr p1 = Ptr(rPtr); + // casting to R ptr from a RW ptr + // CHECK-NOT: ([[# @LINE+1]]): error + Ptr p2 = Ptr(rwPtr); + // casting to ptr of different type + // CHECK-NOT: ([[# @LINE+1]]): error + Ptr p3 = Ptr(rPtr); + + // Cannot implicit cast ptr's + // CHECK: ([[# @LINE+1]]): error 30019 + Ptr p4 = rPtr; + // cannot implcitly cast between different access qualifiers + // CHECK: ([[# @LINE+1]]): error 30019 + Ptr p5 = Ptr(processMemory + id.x); + // cannot implcitly cast between different access qualifiers + // CHECK: ([[# @LINE+1]]): error 30019 + Ptr p6 = Ptr(processMemory + id.x); + + // TODO: Enable this when we allow user-defined group-shared address space, Issue #8173. + // Cannot cast between different address spaces. + // CHECK: ([[# @LINE+1]]): error + Ptr p7 = Ptr(rwPtr); + // CHECK: ([[# @LINE+1]]): error + Ptr p8 = Ptr(p1); + // CHECK: ([[# @LINE+1]]): error + Ptr p9 = rwPtr; + + output[id] = *rwPtr; +} diff --git a/tests/language-feature/pointer/pointer-self-reference.slang b/tests/language-feature/pointer/pointer-self-reference.slang index e78b70db0..75ff4e7a9 100644 --- a/tests/language-feature/pointer/pointer-self-reference.slang +++ b/tests/language-feature/pointer/pointer-self-reference.slang @@ -1,6 +1,8 @@ // pointer-self-reference.slang -//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute -output-using-type -shaderobj +// We are disabling this test because '&' is intentionally not supported. +// Design for pointers in Slang are not yet finalized. +//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute -output-using-type -shaderobj //TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer RWStructuredBuffer outputBuffer; @@ -18,13 +20,13 @@ void computeMain(int3 dispatchThreadID: SV_DispatchThreadID) Thing things[2]; - things[0].next = &things[1]; + things[0].next = __getAddress(things[1]); things[0].value = 27; - things[1].next = &things[0]; + things[1].next = __getAddress(things[0]); things[1].value = idx * idx; - Ptr cur = &things[0]; + Ptr cur = __getAddress(things[0]); for (int i = 0; cur && i < idx; ++i) { diff --git a/tests/language-feature/pointer/ptr-to-groupshared.slang b/tests/language-feature/pointer/ptr-to-groupshared.slang new file mode 100644 index 000000000..3ad4c5e0b --- /dev/null +++ b/tests/language-feature/pointer/ptr-to-groupshared.slang @@ -0,0 +1,30 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-vk -output-using-type -emit-spirv-directly + +// Tests if we handle passing groupshared address-space pointers correctly to a function +// when that data-type needs legalization (Data -> Data_natural due to `lower-buffer-element-type`). +// CHECK: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 0 + +struct Data +{ + int value1; + int value2; +} + +//TEST_INPUT:ubuffer(data=[0 0 0], stride=4):out,name=outputBuffer +uniform int* outputBuffer; +groupshared Data shared; + +void foo(Ptr ptr) +{ + outputBuffer[0] = ptr.value1; + outputBuffer[1] = ptr.value2; +} + +[numthreads(3, 1, 1)] +void computeMain(uint3 group_thread_id: SV_GroupThreadID) +{ + shared = Data(1, 2); + foo(__getAddress(shared)); +} \ No newline at end of file diff --git a/tests/spirv/pointer-from-user-guide.slang b/tests/spirv/pointer-from-user-guide.slang index 662579c2b..115530b2b 100644 --- a/tests/spirv/pointer-from-user-guide.slang +++ b/tests/spirv/pointer-from-user-guide.slang @@ -15,7 +15,7 @@ float test(MyType* pObj) { //SPV: OpTypePointer MyType* pNext = pObj + 1; - MyType* pNext2 = &pNext[1]; + MyType* pNext2 = __getAddress(pNext[1]); return pNext.a + pNext->a + (*pNext2).a + pNext2[0].a; } diff --git a/tests/spirv/pointer.slang b/tests/spirv/pointer.slang index affc52e1b..f3b086e6a 100644 --- a/tests/spirv/pointer.slang +++ b/tests/spirv/pointer.slang @@ -28,12 +28,12 @@ void funcWithInOutParam(inout PP p) // CHECK: OpEntryPoint -StructuredBuffer buffer; +uniform Data* buffer; RWStructuredBuffer output; void main(int id : SV_DispatchThreadID) { output[0] = buffer[0].pNext.data; - let pData = &(buffer[0].pNext->data); // operator -> is also allowed on pointer types. + let pData = __getAddress(buffer[0].pNext->data); // operator -> is also allowed on pointer types. // CHECK: OpPtrAccessChain int* pData1 = pData + 1; *pData1 = 3; diff --git a/tests/spirv/ptr-vector-member.slang b/tests/spirv/ptr-vector-member.slang index 0683d8838..6e493b4c7 100644 --- a/tests/spirv/ptr-vector-member.slang +++ b/tests/spirv/ptr-vector-member.slang @@ -1,19 +1,17 @@ -//TEST:SIMPLE(filecheck=CHECK): -target spirv +//DISABLE_TEST:SIMPLE(filecheck=SPIRV):-stage compute -entry computeMain -target spirv +//DISABLE_TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-vk -output-using-type -emit-spirv-directly -// CHECK: %[[PTR:[0-9a-zA-Z_]+]] = OpAccessChain %_ptr_PhysicalStorageBuffer_uint %16 %int_0 -// CHECK: %{{.*}} = OpAtomicIAdd %uint %[[PTR]] %uint_1 %uint_0 %uint_1 +// SPIRV: OpEntryPoint +// SPIRV-NOT: error -struct Push2 -{ - uint4 * value; -}; - -[[vk::push_constant]] Push2 push2; +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer +uniform int4* output; [shader("compute")] [numthreads(1, 1, 1)] -void main() +void computeMain() { - uint * v = &push2.value[0].x; + // CHECK: 1 + int* v = __getAddress(output[0].x); InterlockedAdd(*v, 1); } \ No newline at end of file -- cgit v1.2.3