summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-lower-to-ir.cpp18
-rw-r--r--tests/spirv/ptr-vector-member.slang19
-rw-r--r--tests/spirv/vector-member-atomic.slang19
3 files changed, 55 insertions, 1 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 0d666306b..429660cac 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -2516,7 +2516,15 @@ void addArg(
// pass in the actual pointer.
//
IRInst* argPtr = getAddress(context, argVal, loc);
- addInArg(context, ioArgs, LoweredValInfo::simple(argPtr));
+ if (argPtr)
+ addInArg(context, ioArgs, LoweredValInfo::simple(argPtr));
+ else
+ {
+ // If arg can't be converted to a pointer, we have already
+ // reported an error, so just pass a null pointer to allow
+ // the remaining lowering steps to finish.
+ addInArg(context, ioArgs, LoweredValInfo::simple(context->irBuilder->getNullVoidPtrValue()));
+ }
}
break;
@@ -6741,6 +6749,14 @@ LoweredValInfo tryGetAddress(
UInt elementCount = originalSwizzleInfo->elementCount;
auto newBase = tryGetAddress(context, originalBase, TryGetAddressMode::Aggressive);
+ if (newBase.flavor == LoweredValInfo::Flavor::Ptr && elementCount == 1)
+ {
+ // A special case is when we have a single element swizzle,
+ // we can just emit an element address.
+ auto elementPtr = context->irBuilder->emitElementAddress(newBase.val, originalSwizzleInfo->elementIndices[0]);
+ return LoweredValInfo::ptr(elementPtr);
+ }
+
RefPtr<SwizzledLValueInfo> newSwizzleInfo = new SwizzledLValueInfo();
context->shared->extValues.add(newSwizzleInfo);
diff --git a/tests/spirv/ptr-vector-member.slang b/tests/spirv/ptr-vector-member.slang
new file mode 100644
index 000000000..0683d8838
--- /dev/null
+++ b/tests/spirv/ptr-vector-member.slang
@@ -0,0 +1,19 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv
+
+// CHECK: %[[PTR:[0-9a-zA-Z_]+]] = OpAccessChain %_ptr_PhysicalStorageBuffer_uint %16 %int_0
+// CHECK: %{{.*}} = OpAtomicIAdd %uint %[[PTR]] %uint_1 %uint_0 %uint_1
+
+struct Push2
+{
+ uint4 * value;
+};
+
+[[vk::push_constant]] Push2 push2;
+
+[shader("compute")]
+[numthreads(1, 1, 1)]
+void main()
+{
+ uint * v = &push2.value[0].x;
+ InterlockedAdd(*v, 1);
+} \ No newline at end of file
diff --git a/tests/spirv/vector-member-atomic.slang b/tests/spirv/vector-member-atomic.slang
new file mode 100644
index 000000000..439cfce9c
--- /dev/null
+++ b/tests/spirv/vector-member-atomic.slang
@@ -0,0 +1,19 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv
+
+// CHECK: %[[PTR:[0-9a-zA-Z_]+]] = OpAccessChain %_ptr_PhysicalStorageBuffer_uint %16 %int_0
+// CHECK: %{{.*}} = OpAtomicIAdd %uint %[[PTR]] %uint_1 %uint_0 %uint_1
+
+
+struct Push2
+{
+ uint4 * value;
+};
+
+[[vk::push_constant]] Push2 push2;
+
+[shader("compute")]
+[numthreads(1, 1, 1)]
+void main()
+{
+ InterlockedAdd(push2.value[0].x, 1);
+} \ No newline at end of file