diff options
| author | Jay Kwak <82421531+jkwak-work@users.noreply.github.com> | 2025-07-24 16:47:21 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-24 23:47:21 +0000 |
| commit | 138efb9c25aadd319db6e6300a263574d90e3391 (patch) | |
| tree | 505bedcf8272be97184c7d03a54ada38c33e6157 /source/slang | |
| parent | a9d1cc5daaf2cf72be88f7ebf4a2e3c3da68abc9 (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.cpp | 30 |
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; |
