diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 71cb14fab29..07b062b083f 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -2878,6 +2878,12 @@ __intrinsic_op(0) [require(cpp_cuda_spirv_llvm)] __prefix Ptr operator&(__ref T value); +__generic +__intrinsic_op(0) +[KnownBuiltin( $((int)KnownBuiltinDeclName::InternalAddressOf))] +[require(cpp_cuda_spirv_llvm)] +Ptr __addressOf(__ref T value); + __generic<$(ptrTypeParameterList), TInt : __BuiltinIntegerType> __intrinsic_op($(kIROp_GetOffsetPtr)) $(fullPtrType) operator+($(fullPtrType) value, TInt offset); diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h index 8f0e7145c05..e724ea6ffc8 100644 --- a/source/slang/slang-ast-support-types.h +++ b/source/slang/slang-ast-support-types.h @@ -235,6 +235,7 @@ FIDDLE() namespace Slang IDifferentiablePtr, NullDifferential, OperatorAddressOf, + InternalAddressOf, COUNT }; diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index f7b21c6affd..c770f017228 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -3110,7 +3110,9 @@ Expr* SemanticsVisitor::CheckInvokeExprWithCheckedOperands(InvokeExpr* expr) as(knownBuiltinAttr->name)) { if (constantIntVal->getValue() == - (int)KnownBuiltinDeclName::OperatorAddressOf) + (int)KnownBuiltinDeclName::OperatorAddressOf || + constantIntVal->getValue() == + (int)KnownBuiltinDeclName::InternalAddressOf) { getSink()->diagnose( argExpr, diff --git a/source/standard-modules/neural/bindless-storage.slang b/source/standard-modules/neural/bindless-storage.slang index 7d723e5a27b..cb830123ed3 100644 --- a/source/standard-modules/neural/bindless-storage.slang +++ b/source/standard-modules/neural/bindless-storage.slang @@ -62,7 +62,7 @@ public struct BindlessAddress : IPointerLikeAddress { case cuda: // On CUDA, use packed vector atomic for types that support it (half2, bfloat16x2). - let scalarPtr = &handle[baseIndex + index]; + let scalarPtr = __addressOf(handle[baseIndex + index]); let vecPtr = reinterpret*>(scalarPtr); __atomic_reduce_add(vecPtr[0], value); default: diff --git a/tests/bugs/gh-3601.slang b/tests/bugs/gh-3601.slang index 65245f97160..05aef98af82 100644 --- a/tests/bugs/gh-3601.slang +++ b/tests/bugs/gh-3601.slang @@ -23,7 +23,7 @@ void funcThatTakesPointer(PP* p) } int* funcThatReturnsPointer(PP* p) { - return &p.data; + return __addressOf(p.data); } // CHECK: OpEntryPoint diff --git a/tests/bugs/gh-7499.slang b/tests/bugs/gh-7499.slang index ea543275800..338fe9ceee2 100644 --- a/tests/bugs/gh-7499.slang +++ b/tests/bugs/gh-7499.slang @@ -20,7 +20,7 @@ export __extern_cpp int main() // Success is not crashing the compiler. int size = 0; int arr = 0; - f(&arr, size); + f(__addressOf(arr), size); return 0; } diff --git a/tests/bugs/gh-8659.slang b/tests/bugs/gh-8659.slang index 599c09b3be8..067abe4371a 100644 --- a/tests/bugs/gh-8659.slang +++ b/tests/bugs/gh-8659.slang @@ -9,7 +9,7 @@ RWStructuredBuffer outputBuffer; [numthreads(1,1,1)] void computeMain() { - let indices = (uint*)&ptr[0]; + let indices = (uint*)__addressOf(ptr[0]); *indices = 100; // CHECK: 100 outputBuffer[0] = ptr[0]; diff --git a/tests/cpu-program/gfx-smoke.slang b/tests/cpu-program/gfx-smoke.slang index 3ed04877ea3..335fd007f8f 100644 --- a/tests/cpu-program/gfx-smoke.slang +++ b/tests/cpu-program/gfx-smoke.slang @@ -7,7 +7,7 @@ export __extern_cpp int main() gfx.DeviceDesc deviceDesc = {}; deviceDesc.deviceType = gfx.DeviceType.CPU; Optional device; - gfx.gfxCreateDevice(&deviceDesc, device); + gfx.gfxCreateDevice(__addressOf(deviceDesc), device); if (device == none) { printf("fail\n"); @@ -17,7 +17,7 @@ export __extern_cpp int main() gfx.CommandQueueDesc queueDesc = {gfx::QueueType::Graphics}; queueDesc.type = gfx.QueueType.Graphics; Optional queue; - device.value.createCommandQueue(&queueDesc, queue); + device.value.createCommandQueue(__addressOf(queueDesc), queue); gfx.ShaderProgramDesc2 programDesc = {}; NativeString s = R"( @@ -36,15 +36,15 @@ export __extern_cpp int main() programDesc.sourceDataSize = s.length; programDesc.entryPointCount = 1; NativeString entryPointName = "computeMain"; - programDesc.entryPointNames = &entryPointName; + programDesc.entryPointNames = __addressOf(entryPointName); Optional program; Optional diagBlob; - device.value.createProgram2(&programDesc, program, diagBlob); + device.value.createProgram2(__addressOf(programDesc), program, diagBlob); Optional pipeline; gfx.ComputePipelineStateDesc pipelineDesc; pipelineDesc.program = NativeRef(program.value); - device.value.createComputePipelineState(&pipelineDesc, pipeline); + device.value.createComputePipelineState(__addressOf(pipelineDesc), pipeline); Optional transientHeap; gfx.TransientResourceHeapDesc transientHeapDesc; @@ -54,7 +54,7 @@ export __extern_cpp int main() transientHeapDesc.uavDescriptorCount = 1024; transientHeapDesc.samplerDescriptorCount = 256; transientHeapDesc.accelerationStructureDescriptorCount = 32; - device.value.createTransientResourceHeap(&transientHeapDesc, transientHeap); + device.value.createTransientResourceHeap(__addressOf(transientHeapDesc), transientHeap); Optional buffer; gfx.BufferResourceDesc bufferDesc = {}; @@ -64,12 +64,12 @@ export __extern_cpp int main() bufferDesc.elementSize = 4; bufferDesc.sizeInBytes = 256; bufferDesc.type = gfx.ResourceType.Buffer; - device.value.createBufferResource(&bufferDesc, nullptr, buffer); + device.value.createBufferResource(__addressOf(bufferDesc), nullptr, buffer); Optional bufferView; gfx.ResourceViewDesc viewDesc; viewDesc.type = gfx.ResourceViewType.UnorderedAccess; - device.value.createBufferView(buffer.value, none, &viewDesc, bufferView); + device.value.createBufferView(buffer.value, none, __addressOf(viewDesc), bufferView); Optional commandBuffer; transientHeap.value.createCommandBuffer(commandBuffer); @@ -80,13 +80,13 @@ export __extern_cpp int main() Optional entryPointObject; rootObject.value.getEntryPoint(0, entryPointObject); gfx.ShaderOffset offset = {}; - entryPointObject.value.setResource(&offset, bufferView.value); + entryPointObject.value.setResource(__addressOf(offset), bufferView.value); encoder.value.dispatchCompute(1, 1, 1); encoder.value.endEncoding(); commandBuffer.value.close(); NativeRef commandBufferRef = NativeRef(commandBuffer.value); - queue.value.executeCommandBuffers(1, &commandBufferRef, none, 0); + queue.value.executeCommandBuffers(1, __addressOf(commandBufferRef), none, 0); queue.value.waitOnHost(); Optional blob; diff --git a/tests/cpu-program/pointer-basics.slang b/tests/cpu-program/pointer-basics.slang index db705d50786..33e64665742 100644 --- a/tests/cpu-program/pointer-basics.slang +++ b/tests/cpu-program/pointer-basics.slang @@ -2,13 +2,13 @@ export __extern_cpp int main() { uint2 value; - int *pValue = (int*)&value; + int *pValue = (int*)__addressOf(value); *pValue = 1; (*pValue)++; ++pValue[0]; ++pValue; *pValue = 1; - pValue = (int *)&value; + pValue = (int *)__addressOf(value); int64_t ptrVal = int64_t(pValue); pValue = (int *)ptrVal; if (pValue diff --git a/tests/cpu-program/pointer-deref.slang b/tests/cpu-program/pointer-deref.slang index f5bad5b09db..d3eaf0548ea 100644 --- a/tests/cpu-program/pointer-deref.slang +++ b/tests/cpu-program/pointer-deref.slang @@ -14,7 +14,7 @@ struct Record export __extern_cpp int main() { Record rec; - Record *pRec = &rec; + Record *pRec = __addressOf(rec); pRec.field = 1; pRec.sub.field2 = 2; pRec.sub.field3 = 3.0f; diff --git a/tests/diagnostics/invalid-constant-pointer-taking.slang b/tests/diagnostics/invalid-constant-pointer-taking.slang index 658a84b1b25..2d1aec394e7 100644 --- a/tests/diagnostics/invalid-constant-pointer-taking.slang +++ b/tests/diagnostics/invalid-constant-pointer-taking.slang @@ -11,7 +11,7 @@ StructuredBuffer constant_uint_buffer; [numthreads(1,1,1)] void computeMain(uint3 threadId : SV_DispatchThreadID) { - float* mutablePtr1 = &mutable_float_buffer[threadId.x]; + float* mutablePtr1 = __addressOf(mutable_float_buffer[threadId.x]); // CHECK: ([[# @LINE+1]]): error 31160 float* mutablePtr2 = __getAddress(mutable_float_buffer[threadId.x]); @@ -20,7 +20,7 @@ void computeMain(uint3 threadId : SV_DispatchThreadID) // Constant pointers arent a thing in slang // CHECK: ([[# @LINE+1]]): error 30079: - float* ptr1 = &constant_float_buffer[threadId.x]; + float* ptr1 = __addressOf(constant_float_buffer[threadId.x]); // CHECK: ([[# @LINE+1]]): error 31160 float* ptr2 = __getAddress(constant_float_buffer[threadId.x]); diff --git a/tests/language-feature/bitfield/msvc-repr.slang b/tests/language-feature/bitfield/msvc-repr.slang index 4edd47556d3..390e7f06180 100644 --- a/tests/language-feature/bitfield/msvc-repr.slang +++ b/tests/language-feature/bitfield/msvc-repr.slang @@ -31,6 +31,6 @@ void computeMain() s.d = 0xDEF0; // Write the struct to memory and read it back as uint - outputBuffer[0] = *((uint*)&s); + outputBuffer[0] = *((uint*)__addressOf(s)); } diff --git a/tests/language-feature/bitfield/repr-mixed.slang b/tests/language-feature/bitfield/repr-mixed.slang index 44a3f69d9ca..09a79bf885e 100644 --- a/tests/language-feature/bitfield/repr-mixed.slang +++ b/tests/language-feature/bitfield/repr-mixed.slang @@ -31,6 +31,6 @@ void computeMain() m.d = 0xEF; // With default packing, all fields are in one backing field - outputBuffer[0] = *((uint*)&m) & 0xFFFFFF; // Mask to 24 bits + outputBuffer[0] = *((uint*)__addressOf(m)) & 0xFFFFFF; // Mask to 24 bits } diff --git a/tests/language-feature/bitfield/repr.slang b/tests/language-feature/bitfield/repr.slang index a199b23ffa8..8e1723119cd 100644 --- a/tests/language-feature/bitfield/repr.slang +++ b/tests/language-feature/bitfield/repr.slang @@ -31,6 +31,6 @@ void computeMain() s.d = 0xDEF0; // Write the struct to memory and read it back as uint - outputBuffer[0] = *((uint*)&s); + outputBuffer[0] = *((uint*)__addressOf(s)); } diff --git a/tests/language-feature/pointer/coherent-load-store-physical-storage-buffer.slang b/tests/language-feature/pointer/coherent-load-store-physical-storage-buffer.slang index b70664d8220..e1ef29a7bfd 100644 --- a/tests/language-feature/pointer/coherent-load-store-physical-storage-buffer.slang +++ b/tests/language-feature/pointer/coherent-load-store-physical-storage-buffer.slang @@ -20,5 +20,5 @@ void computeMain() Ptr ptrIn = inputBuffer; Ptr secondPtrIn = ptrIn; Ptr ptrOut = outputBuffer; - storeCoherent<4, MemoryScope::Device>(ptrOut, loadCoherent<4, MemoryScope::Device>(&secondPtrIn[1])); + storeCoherent<4, MemoryScope::Device>(ptrOut, loadCoherent<4, MemoryScope::Device>(__addressOf(secondPtrIn[1]))); } \ No newline at end of file diff --git a/tests/llvm/inline-llvm-ir.slang b/tests/llvm/inline-llvm-ir.slang index f08e1f16fef..c45f558387f 100644 --- a/tests/llvm/inline-llvm-ir.slang +++ b/tests/llvm/inline-llvm-ir.slang @@ -32,7 +32,7 @@ void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) { float4 a = float4(1,2,3,4); float f1 = reduceAdd(a); - memset(Ptr(&a), 0, 8); + memset(Ptr(__addressOf(a)), 0, 8); float f2 = reduceAdd(a); // CHECK: 10.0 diff --git a/tests/spirv/pointer.slang b/tests/spirv/pointer.slang index f3b086e6a81..fd5543a5d4e 100644 --- a/tests/spirv/pointer.slang +++ b/tests/spirv/pointer.slang @@ -18,7 +18,7 @@ void funcThatTakesPointer(PP* p) } int* funcThatReturnsPointer(PP* p) { - return &p.data; + return __addressOf(p.data); } void funcWithInOutParam(inout PP p)