Skip to content

Commit

Permalink
Fix incorrect resolve of specialization instance (#6162)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
jkwak-work authored Jan 23, 2025
1 parent 8000e0e commit a9ce752
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
15 changes: 6 additions & 9 deletions source/slang/slang-ir-use-uninitialized-values.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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))
{
Expand All @@ -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);
}
Expand Down Expand Up @@ -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))
Expand Down
30 changes: 30 additions & 0 deletions tests/diagnostics/uninitialized-generic.slang
Original file line number Diff line number Diff line change
@@ -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;
}
9 changes: 5 additions & 4 deletions tests/diagnostics/uninitialized-local-variables.slang
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit a9ce752

Please sign in to comment.