summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2025-07-24 16:47:21 -0700
committerGitHub <noreply@github.com>2025-07-24 23:47:21 +0000
commit138efb9c25aadd319db6e6300a263574d90e3391 (patch)
tree505bedcf8272be97184c7d03a54ada38c33e6157 /source/slang
parenta9d1cc5daaf2cf72be88f7ebf4a2e3c3da68abc9 (diff)
Avoid early specialization for witness tables in SimplifyIR (#7636)
* Avoid early specialization for witness tables in SimplifyIR Prevents SimplifyIR from prematurely specializing witness tables before the main specialization pass. Witness tables are hoistable immutable objects that must maintain consistent signatures to avoid incorrect deduplication. SimplifyIR was incorrectly transforming expressions like "witness_table_t(%IFoo)(specialize(%7, %GenericValue4))" into "witness_table_t(%IFoo)(%Foo)" even when %GenericValue4 was unused. Fixes #7233 * Add a missing test file
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-ir-remove-unused-generic-param.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/source/slang/slang-ir-remove-unused-generic-param.cpp b/source/slang/slang-ir-remove-unused-generic-param.cpp
index dd4efeddd..c79e236b8 100644
--- a/source/slang/slang-ir-remove-unused-generic-param.cpp
+++ b/source/slang/slang-ir-remove-unused-generic-param.cpp
@@ -72,17 +72,38 @@ struct RemoveUnusedGenericParamContext : InstPassBase
child = next;
}
SLANG_ASSERT(returnVal);
- List<IRUse*> uses;
+
+ // Collect all specialize uses that we might optimize
+ List<IRUse*> specializeUses;
for (auto use = genInst->firstUse; use; use = use->nextUse)
- uses.add(use);
- for (auto use : uses)
{
if (use->getUser()->getOp() == kIROp_Specialize &&
use == use->getUser()->getOperands())
{
- use->getUser()->replaceUsesWith(returnVal);
+ specializeUses.add(use);
+ }
+ }
+
+ // Check if any of these specialize uses are used by witness tables
+ // If so, we cannot apply the optimization because witness tables are immutable
+ for (auto use : specializeUses)
+ {
+ for (auto specializeUse = use->getUser()->firstUse; specializeUse;
+ specializeUse = specializeUse->nextUse)
+ {
+ auto userOp = specializeUse->getUser()->getOp();
+ if (userOp == kIROp_WitnessTable)
+ {
+ goto skipOptimization;
+ }
}
}
+
+ // Apply the optimization: replace all specialize uses with the return value
+ for (auto use : specializeUses)
+ {
+ use->getUser()->replaceUsesWith(returnVal);
+ }
genInst->replaceUsesWith(returnVal);
genInst->removeAndDeallocate();
}
@@ -118,6 +139,7 @@ struct RemoveUnusedGenericParamContext : InstPassBase
for (auto param : paramsToRemove)
param->removeAndDeallocate();
}
+ skipOptimization:;
}
}
return changed;