summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2025-01-23 00:06:21 -0800
committerGitHub <noreply@github.com>2025-01-23 00:06:21 -0800
commita9ce7520e5f1b97b09e5de69455258bef55e10d2 (patch)
treeab9af31ba0a52cd4dd245e19fa4323864286f551
parent8000e0ede34e920cc7f37d69a335d74a472eff42 (diff)
Fix incorrect resolve of specialization instance (#6162)
* Fix incorrect resolve of specialization instance While checking the uninitialized variables, we were not resolving the specialized instance correctly. This commit repeats the resolve while the result is a specialization instance. A new test is added for this: tests/diagnostics/uninitialized-generic.slang After the problem is fixed, it revealed another problem in existing tests: tests/compute/nested-generics2.slang tests/diagnostics/uninitialized-local-variables.slang When a struct has a member variable whose type is a generic type, we cannot iterate over its member variables yet, because the type is unknown until the generic function/struct is specialized. We will have to give up checking for these cases.
-rw-r--r--source/slang/slang-ir-use-uninitialized-values.cpp15
-rw-r--r--tests/diagnostics/uninitialized-generic.slang30
-rw-r--r--tests/diagnostics/uninitialized-local-variables.slang9
3 files changed, 41 insertions, 13 deletions
diff --git a/source/slang/slang-ir-use-uninitialized-values.cpp b/source/slang/slang-ir-use-uninitialized-values.cpp
index b1db2913e..51de2117c 100644
--- a/source/slang/slang-ir-use-uninitialized-values.cpp
+++ b/source/slang/slang-ir-use-uninitialized-values.cpp
@@ -139,13 +139,6 @@ static bool isDifferentiableFunc(IRInst* func)
return false;
}
-static IRInst* resolveSpecialization(IRSpecialize* spec)
-{
- IRInst* base = spec->getBase();
- IRGeneric* generic = as<IRGeneric>(base);
- return findInnerMostGenericReturnVal(generic);
-}
-
// The `upper` field contains the struct that the type is
// is contained in. It is used to check for empty structs.
static bool canIgnoreType(IRType* type, IRType* upper)
@@ -174,6 +167,10 @@ static bool canIgnoreType(IRType* type, IRType* upper)
if (as<IRInterfaceType>(type))
return true;
+ // We don't know what type it will be yet.
+ if (as<IRParam>(type))
+ return true;
+
// For pointers, check the value type (primarily for globals)
if (auto ptr = as<IRPtrType>(type))
{
@@ -188,7 +185,7 @@ static bool canIgnoreType(IRType* type, IRType* upper)
// In the case of specializations, check returned type
if (auto spec = as<IRSpecialize>(type))
{
- IRInst* inner = resolveSpecialization(spec);
+ IRInst* inner = getResolvedInstForDecorations(spec);
IRType* innerType = as<IRType>(inner);
return canIgnoreType(innerType, upper);
}
@@ -231,7 +228,7 @@ static InstructionUsageType getCallUsageType(IRCall* call, IRInst* inst)
IRFunc* ftn = nullptr;
IRFuncType* ftype = nullptr;
if (auto spec = as<IRSpecialize>(callee))
- ftn = as<IRFunc>(resolveSpecialization(spec));
+ ftn = as<IRFunc>(getResolvedInstForDecorations(spec));
// Differentiable functions are mostly ignored, treated as having inout parameters
else if (as<IRForwardDifferentiate>(callee))
diff --git a/tests/diagnostics/uninitialized-generic.slang b/tests/diagnostics/uninitialized-generic.slang
new file mode 100644
index 000000000..2d6ccd45b
--- /dev/null
+++ b/tests/diagnostics/uninitialized-generic.slang
@@ -0,0 +1,30 @@
+//TEST:SIMPLE(filecheck=CHK): -target spirv -entry computeMain
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<float> outputBuffer;
+
+groupshared float4 gsVar;
+
+__generic<TYPE1 : __BuiltinArithmeticType>
+struct MyContainer
+{
+ __generic<TYPE2 : __BuiltinArithmeticType>
+ void store(__ref vector<TYPE2,4> v)
+ {
+ v[0] = TYPE2(0);
+ v[1] = TYPE2(1);
+ v[2] = TYPE2(2);
+ v[3] = TYPE2(3);
+ }
+};
+
+[Shader("compute")]
+[NumThreads(1, 1, 1)]
+void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
+{
+ MyContainer<float> obj;
+ obj.store(gsVar);
+
+ // CHK-NOT:warning 41017:
+ outputBuffer[0] = gsVar.x;
+}
diff --git a/tests/diagnostics/uninitialized-local-variables.slang b/tests/diagnostics/uninitialized-local-variables.slang
index f7a8ff2c7..9ade4591a 100644
--- a/tests/diagnostics/uninitialized-local-variables.slang
+++ b/tests/diagnostics/uninitialized-local-variables.slang
@@ -38,13 +38,14 @@ int use_undefined_value(int k)
return x;
}
-// Returning uninitialized values
+// We don't know the exact type of T yet.
+// T may not have any members, and it may not need any initialization.
__generic<T>
T generic_undefined_return()
{
- T x;
- //CHK-DAG: warning 41016: use of uninitialized variable 'x'
- return x;
+ T y;
+ //CHK-NOT: warning 41016: use of uninitialized variable 'y'
+ return y;
}
// Array variables