From c834ac4c11ecbb4e17e81d3ebcb64a6c6f453818 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 22 Nov 2022 14:17:30 -0800 Subject: [Wasm GC] Fix CoalesceLocals on tees that receive a refined type (#5289) Same testcase as in #5287 but in another pass. --- src/passes/CoalesceLocals.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp index 558be07ff..062449e95 100644 --- a/src/passes/CoalesceLocals.cpp +++ b/src/passes/CoalesceLocals.cpp @@ -523,7 +523,10 @@ void CoalesceLocals::applyIndices(std::vector& indices, } } if (auto* subSet = set->value->dynCast()) { - if (subSet->index == set->index) { + // Only do so if not only the index matches but also the type. If the + // inner type is more refined, leave that for other passes. + if (subSet->index == set->index && + subSet->value->type == subSet->type) { set->value = subSet->value; continue; } @@ -550,12 +553,28 @@ void CoalesceLocals::applyIndices(std::vector& indices, if (!action.effective) { // value may have no side effects, further optimizations can eliminate // it - *action.origin = set->value; + auto* value = set->value; if (!set->isTee()) { // we need to drop it Drop* drop = ExpressionManipulator::convert(set); - drop->value = *action.origin; + drop->value = value; *action.origin = drop; + } else { + // This is a tee, and so, as earlier in this function, we must be + // careful of subtyping. Above we simply avoided the problem by + // leaving it for other passes, but we do want to remove ineffective + // stores - nothing else does that as well as this pass. Instead, + // create a block to cast back to the original type, which avoids + // changing types here, and leave it to other passes to refine types + // and remove the block. + auto originalType = (*action.origin)->type; + if (originalType != set->value->type) { + (*action.origin) = + Builder(*getModule()).makeBlock({set->value}, originalType); + } else { + // No special handling, just use the value. + *action.origin = set->value; + } } continue; } -- cgit v1.2.3