Skip to content
Open
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
5 changes: 2 additions & 3 deletions source/slang/slang-check-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6681,9 +6681,8 @@ bool SemanticsVisitor::trySynthesizeEnumTypeMethodRequirementWitness(
context->parentDecl->addDirectMemberDecl(synFunc);

addModifier(synFunc, intrinsicOpModifier);
witnessTable->add(
funcDeclRef.getDecl(),
RequirementWitness(m_astBuilder->getDirectDeclRef(synFunc)));
DeclRef<Decl> memberDeclRef = getDefaultDeclRef(synFunc);
witnessTable->add(funcDeclRef.getDecl(), RequirementWitness(memberDeclRef));
return true;
}

Expand Down
19 changes: 12 additions & 7 deletions source/slang/slang-ir-dce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,17 +587,22 @@ bool shouldInstBeLiveIfParentIsLive(IRInst* inst, IRDeadCodeEliminationOptions o
break;
}
}
for (auto decor : innerInst->getDecorations())

if (innerInst)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we think this conditional is still good/necessary?

Unless we have a reason to believe that innerInst could be null for valid input code, I would rather see a SLANG_ASSERT(innerInst) than an if(innerInst). Either way, this code seems unrelated to the actual fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we still need to keep this conditional check.
As the innerInst = findInnerMostGenericReturnVal(genInst); could return nullptr for the generic that doesn't have return val ( enum in this case?)

The genInst causing the trouble has only a basic block contains a T Op_Param.
We would have to keep check, unless this inst should not be here in the first place..

{
switch (decor->getOp())
for (auto decor : innerInst->getDecorations())
{
case kIROp_ForwardDerivativeDecoration:
case kIROp_UserDefinedBackwardDerivativeDecoration:
case kIROp_PrimalSubstituteDecoration:
shouldKeptAliveIfImported = true;
break;
switch (decor->getOp())
{
case kIROp_ForwardDerivativeDecoration:
case kIROp_UserDefinedBackwardDerivativeDecoration:
case kIROp_PrimalSubstituteDecoration:
shouldKeptAliveIfImported = true;
break;
}
}
}

if (isImported && shouldKeptAliveIfImported)
return true;
}
Expand Down
25 changes: 3 additions & 22 deletions source/slang/slang-ir-specialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,9 @@ struct SpecializationContext
IRInst* satisfyingVal = nullptr;

if (witnessTable)
satisfyingVal = findWitnessVal(witnessTable, requirementKey);
{
satisfyingVal = findWitnessTableEntry(witnessTable, requirementKey);
}
else
{
// If we are specializing ThisTypeWitness, the result of the specialization
Expand Down Expand Up @@ -935,27 +937,6 @@ struct SpecializationContext
return instChanged;
}

// The above subroutine needed a way to look up
// the satisfying value for a given requirement
// key in a concrete witness table, so let's
// define that now.
//
IRInst* findWitnessVal(IRWitnessTable* witnessTable, IRInst* requirementKey)
{
// A witness table is basically just a container
// for key-value pairs, and so the best we can
// do for now is a naive linear search.
//
for (auto entry : witnessTable->getEntries())
{
if (requirementKey == entry->getRequirementKey())
{
return entry->getSatisfyingVal();
}
}
return nullptr;
}

template<typename TDict>
void _readSpecializationDictionaryImpl(TDict& dict, IRInst* dictInst)
{
Expand Down
2 changes: 1 addition & 1 deletion source/slang/slang-ir-strip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void stripImportedWitnessTable(IRModule* module)
default:
continue;
}
if (inst->getOp() != kIROp_WitnessTable)
if (!inst || inst->getOp() != kIROp_WitnessTable)
continue;
if (!globalInst->findDecoration<IRImportDecoration>())
continue;
Expand Down
29 changes: 29 additions & 0 deletions tests/language-feature/enums/nested-enum.slang
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,33 @@ int test(int val)
return result;
}

struct OuterGeneric<T>
{
enum Channel
{
Red,
Green,
Blue,
Alpha,
};
T value;
Channel channel;
}

int testGeneric(int val)
{
OuterGeneric<int> outer;
outer.value = val;
outer.channel = OuterGeneric<int>.Channel(val);
int result = 0;
if (outer.channel == OuterGeneric<int>.Channel.Red) result += 1;
if (outer.channel == OuterGeneric<int>.Channel.Green) result += 2;
if (outer.channel == OuterGeneric<int>.Channel.Blue) result += 3;
if (outer.channel == OuterGeneric<int>.Channel.Alpha) result += 4;

return result;
}

//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
RWStructuredBuffer<int> outputBuffer;

Expand All @@ -80,5 +107,7 @@ void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
int tid = dispatchThreadID.x;
int inVal = tid;
int outVal = test(inVal) + value * 2 + int(anotherValue) * 4;

outVal += testGeneric(inVal);
outputBuffer[tid] = outVal;
}
8 changes: 4 additions & 4 deletions tests/language-feature/enums/nested-enum.slang.expected.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
1071
1060
1170
70
1072
1062
1173
74