diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir-cleanup-void.cpp | 93 |
2 files changed, 98 insertions, 0 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index a1a9690f4..50ca8e3ae 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -2486,6 +2486,11 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO emitSimpleValue(inst); break; + case kIROp_VoidLit: + // VoidLit represents a "nothing" value (e.g., zero derivative for no_diff params). + // Nothing to emit for void values. + break; + case kIROp_MakeCoopVector: case kIROp_MakeVector: case kIROp_MakeMatrix: diff --git a/source/slang/slang-ir-cleanup-void.cpp b/source/slang/slang-ir-cleanup-void.cpp index 3a776fc4f..b6f9c94d1 100644 --- a/source/slang/slang-ir-cleanup-void.cpp +++ b/source/slang/slang-ir-cleanup-void.cpp @@ -67,6 +67,99 @@ struct CleanUpVoidContext } } break; + case kIROp_MakeMatrix: + { + // Replace void arguments with zero-initialized vectors. + // This can happen from autodiff with no_diff params. + auto matrixType = as<IRMatrixType>(inst->getDataType()); + if (!matrixType) + break; + auto elementType = matrixType->getElementType(); + auto rowCount = matrixType->getRowCount(); + IRType* rowType = nullptr; + { + IRBuilder builder(module); + builder.setInsertBefore(inst); + rowType = builder.getVectorType(elementType, rowCount); + } + + List<IRInst*> newArgs; + bool changed = false; + for (UInt i = 0; i < inst->getOperandCount(); i++) + { + auto arg = inst->getOperand(i); + if (arg->getDataType() && arg->getDataType()->getOp() == kIROp_VoidType) + { + // Replace void with zero-initialized row vector. + IRBuilder builder(module); + builder.setInsertBefore(inst); + auto zero = builder.emitDefaultConstruct(rowType); + newArgs.add(zero); + changed = true; + } + else + { + newArgs.add(arg); + } + } + if (changed) + { + IRBuilder builder(module); + builder.setInsertBefore(inst); + auto newInst = builder.emitIntrinsicInst( + inst->getFullType(), + inst->getOp(), + newArgs.getCount(), + newArgs.getBuffer()); + inst->replaceUsesWith(newInst); + inst->removeAndDeallocate(); + inst = newInst; + } + } + break; + case kIROp_MakeVector: + { + // Replace void arguments with zero values. + // This can happen from autodiff with no_diff params. + auto vectorType = as<IRVectorType>(inst->getDataType()); + if (!vectorType) + break; + auto elementType = vectorType->getElementType(); + + List<IRInst*> newArgs; + bool changed = false; + for (UInt i = 0; i < inst->getOperandCount(); i++) + { + auto arg = inst->getOperand(i); + if (arg->getDataType() && arg->getDataType()->getOp() == kIROp_VoidType) + { + // Replace void with zero element. + IRBuilder builder(module); + builder.setInsertBefore(inst); + auto zero = builder.emitDefaultConstruct(elementType); + newArgs.add(zero); + changed = true; + } + else + { + newArgs.add(arg); + } + } + if (changed) + { + IRBuilder builder(module); + builder.setInsertBefore(inst); + auto newInst = builder.emitIntrinsicInst( + inst->getFullType(), + inst->getOp(), + newArgs.getCount(), + newArgs.getBuffer()); + inst->replaceUsesWith(newInst); + inst->removeAndDeallocate(); + inst = newInst; + } + } + break; case kIROp_Func: { // Remove void parameter. |
