Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect resolve of specialization instance #6162

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading