summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorGangzheng Tong <tonggangzheng@gmail.com>2025-09-23 09:39:39 -0700
committerGitHub <noreply@github.com>2025-09-23 16:39:39 +0000
commitd61d6b57dfb0788ebf3449bfde6db288fe4e44a8 (patch)
treef95d543f962a75917e401a44dfdc0fe18df4efdd /source/slang
parent21c663605330d629e9022314a4720b86b017f295 (diff)
Legalize type as well in legalizeOperand (#8483)
This fixes a type mismatch issue. See the generated cuda code ```cuda struct Query_0 { EmptyExample_0 query_0; uint hasNonEmptyAbsorbingBoundary_0; }; struct Query_1 { uint hasNonEmptyAbsorbingBoundary_0; }; struct GlobalParams_0 { Query_0* gQuery_0; RWStructuredBuffer<float3 > gInput_0; RWStructuredBuffer<float> gOutput_0; }; ... Query_1 _S4 = *globalParams_0->gQuery_0; // ==> type mismatch at call site! ``` **Root Cause:** During the empty type legalization pass in Slang's IR processing, struct types were being optimized. e.g., `Query_0` → `Query_1` with empty type removed), but this created an inconsistency: **Function parameters were updated:** When Query_compute_0 function was legalized, its parameter type was correctly updated from `Query_0` to the optimized `Query_1` **Global parameter types were NOT updated:** The `ParameterBlock<Struct>` type in globalParams still referenced the old `Query_0` type The PR adds special handling for type operands in the `legalizeInst` function. This triggers the legalization of the `StructType` from the original `legalizeOperand` call site. The leaglized result will be saved in the type-to-legal-type map and be re-used when the same type requires legalization again (e.g. in the `IRFunc` as parameter) Fixes: https://github.com/shader-slang/slang/issues/7905
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-ir-legalize-types.cpp20
1 files changed, 17 insertions, 3 deletions
diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp
index dd7107b18..085c3d933 100644
--- a/source/slang/slang-ir-legalize-types.cpp
+++ b/source/slang/slang-ir-legalize-types.cpp
@@ -179,14 +179,27 @@ static LegalVal maybeMaterializeWrappedValue(IRTypeLegalizationContext* context,
static LegalVal legalizeOperand(IRTypeLegalizationContext* context, IRInst* irValue)
{
LegalVal legalVal;
+
+ // Special handling for type operands
+ if (auto oldType = as<IRType>(irValue))
+ {
+ // e.g. ParameterBlock<Struct>, the inst. ParameterBlockType holds the operand `StructType`,
+ // if we don't legalize it here and the same structType is legalized somewhere else, the
+ // operand of ParameterBlockType might not get updated, and it would result in a type
+ // mismatch.
+ auto legalType = legalizeType(context, oldType);
+ if (legalType.flavor == LegalType::Flavor::simple)
+ return LegalVal::simple(legalType.getSimple());
+ // legalType is not simple, fallback to the original value
+ }
+
if (context->mapValToLegalVal.tryGetValue(irValue, legalVal))
{
return maybeMaterializeWrappedValue(context, legalVal);
}
// For now, assume that anything not covered
- // by the mapping is legal as-is.
-
+ // by the type legalization or val mapping is legal as-is.
return LegalVal::simple(irValue);
}
@@ -2386,7 +2399,8 @@ static LegalVal legalizeInst(IRTypeLegalizationContext* context, IRInst* inst)
for (UInt aa = 0; aa < argCount; ++aa)
{
auto oldArg = inst->getOperand(aa);
- auto legalArg = legalizeOperand(context, oldArg);
+
+ LegalVal legalArg = legalizeOperand(context, oldArg);
legalArgs.add(legalArg);
if (legalArg.flavor != LegalVal::Flavor::simple)