diff options
| -rw-r--r-- | source/slang/slang-ir-legalize-types.cpp | 19 | ||||
| -rw-r--r-- | tests/spirv/debug-var-generic-param.slang | 62 |
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 |
