summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-ir-legalize-types.cpp19
-rw-r--r--tests/spirv/debug-var-generic-param.slang62
2 files changed, 80 insertions, 1 deletions
diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp
index 9363bc882..dd7107b18 100644
--- a/source/slang/slang-ir-legalize-types.cpp
+++ b/source/slang/slang-ir-legalize-types.cpp
@@ -13,6 +13,7 @@
#include "../compiler-core/slang-name.h"
#include "../core/slang-performance-profiler.h"
#include "slang-ir-clone.h"
+#include "slang-ir-insert-debug-value-store.h"
#include "slang-ir-insts.h"
#include "slang-ir-util.h"
#include "slang-ir.h"
@@ -842,8 +843,17 @@ static LegalVal legalizeDebugVar(
{
case LegalType::Flavor::simple:
{
+ auto pointedToType = tryGetPointedToType(context->builder, type.getSimple());
+
+ // Check if the type is debuggable before creating DebugVar
+ DebugValueStoreContext debugContext;
+ if (!debugContext.isDebuggableType(pointedToType))
+ {
+ return LegalVal();
+ }
+
auto legalVal = context->builder->emitDebugVar(
- tryGetPointedToType(context->builder, type.getSimple()),
+ pointedToType,
originalInst->getSource(),
originalInst->getLine(),
originalInst->getCol(),
@@ -881,6 +891,9 @@ static LegalVal legalizeDebugValue(
LegalVal debugValue,
IRDebugValue* originalInst)
{
+ if (debugVar.flavor == LegalVal::Flavor::none)
+ return LegalVal();
+
// For now we just discard any special part and keep the ordinary part.
switch (debugValue.flavor)
{
@@ -2114,6 +2127,10 @@ static LegalVal legalizeInst(
break;
case kIROp_DebugVar:
result = legalizeDebugVar(context, type, (IRDebugVar*)inst);
+ if (result.flavor == LegalVal::Flavor::none)
+ {
+ return result;
+ }
break;
case kIROp_DebugValue:
result = legalizeDebugValue(context, args[0], args[1], (IRDebugValue*)inst);
diff --git a/tests/spirv/debug-var-generic-param.slang b/tests/spirv/debug-var-generic-param.slang
new file mode 100644
index 000000000..85049eefe
--- /dev/null
+++ b/tests/spirv/debug-var-generic-param.slang
@@ -0,0 +1,62 @@
+//TEST:SIMPLE(filecheck=CHECK):-target spirv -entry main -stage compute -g2 -emit-spirv-directly
+
+// Test for debug variable handling with generic parameters and structs containing resources
+// This test ensures that structs containing StructuredBuffer fields don't get invalid DebugVar instructions
+
+StructuredBuffer<uint4> gData;
+
+interface IGeometryReader
+{
+ float4 read(uint attributeIndex);
+}
+
+struct PositionReader : IGeometryReader
+{
+ float4 read(uint vertexIndex)
+ {
+ return m_geometryBuffer[vertexIndex];
+ }
+
+ __init(StructuredBuffer<uint4> geometryBuffer)
+ {
+ m_geometryBuffer = geometryBuffer;
+ }
+
+ StructuredBuffer<uint4> m_geometryBuffer;
+}
+
+float4 test<Reader: IGeometryReader>(Reader reader)
+{
+ float4 pos = reader.read(0);
+ return pos;
+}
+
+RWStructuredBuffer<float4> result;
+
+[numthreads(1,1,1)]
+void main()
+{
+ let reader = PositionReader(gData);
+ float4 pos = test(reader);
+
+ result[0] = pos;
+}
+
+// Verify that debug info is generated but no invalid DebugVar for struct with StructuredBuffer
+// CHECK: OpExtInst %void {{.*}} DebugExpression
+
+// Ensure we have the expected legitimate debug variables
+// CHECK: pos{{.*}}DebugLocalVariable{{.*}}
+// CHECK: vertexIndex{{.*}}DebugLocalVariable{{.*}}
+
+// After legitimate debug vars, ensure we don't create debug vars for non-debuggable types
+// Specifically check that we don't create debug vars for variables containing StructuredBuffer:
+// - No debug var for 'reader' (PositionReader struct instance)
+// - No debug var for 'm_geometryBuffer' (StructuredBuffer field)
+// The absence of these variables in the output proves the fix is working
+// CHECK-NOT: reader{{.*}}DebugLocalVariable{{.*}}
+// CHECK-NOT: m_geometryBuffer{{.*}}DebugLocalVariable{{.*}}
+// CHECK-NOT: geometryBuffer{{.*}}DebugLocalVariable{{.*}}
+
+// Verify the function ends properly
+// CHECK: OpFunctionEnd \ No newline at end of file