Skip to content

Commit

Permalink
Prevent hoisting of non-hoistable instructions in non-function values…
Browse files Browse the repository at this point in the history
… with code (#4250)
  • Loading branch information
expipiplus1 authored Jun 2, 2024
1 parent c5a453e commit 0bc89bc
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 2 deletions.
4 changes: 2 additions & 2 deletions source/slang/slang-ir-redundancy-removal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ struct RedundancyRemovalContext
for (UInt i = 0; i < inst->getOperandCount(); i++)
{
auto operand = inst->getOperand(i);
if (getParentFunc(operand) != func)
if (!hasDescendent(func, operand))
{
// Global value won't prevent hoisting.
// Only prevent hoisting from operands local to this function
continue;
}
auto operandParent = as<IRBlock>(operand->getParent());
Expand Down
12 changes: 12 additions & 0 deletions source/slang/slang-ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8530,6 +8530,18 @@ namespace Slang
return nullptr;
}

bool hasDescendent(IRInst* inst, IRInst* child)
{
auto parent = child->getParent();
while (parent)
{
if (inst == parent)
return true;
parent = parent->getParent();
}
return false;
}

IRInst* getGenericReturnVal(IRInst* inst)
{
if (auto gen = as<IRGeneric>(inst))
Expand Down
3 changes: 3 additions & 0 deletions source/slang/slang-ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -2538,6 +2538,9 @@ bool isBuiltin(IRInst* inst);
// Get the enclosuing function of an instruction.
IRFunc* getParentFunc(IRInst* inst);

// Is child a descendent of inst
bool hasDescendent(IRInst* inst, IRInst* child);

// True if moving this inst will not change the semantics of the program
bool isMovableInst(IRInst* inst);

Expand Down
33 changes: 33 additions & 0 deletions tests/bugs/generic-initializer-inlining.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-cpu

// CHECK: 1
// CHECK-NEXT: 0
// CHECK-NEXT: 0
// CHECK-NEXT: 0

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

struct C<T>
{
[ForceInline]
__init<U>(U value)
{
for (int i = 0; i < 1; ++i)
{}
}
}

static C<int> c = C<int>(1);

int use<T>(T x)
{
return 1;
}

[numthreads(1, 1, 1)]
void computeMain(uint i : SV_GroupIndex)
{
outputBuffer[0] = use(c);
}

0 comments on commit 0bc89bc

Please sign in to comment.