From 5df39e3bbddaefcb0d0c4d1f10412c508b120aca Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 9 Aug 2022 09:49:04 -0700 Subject: RedundantSetElimination: ReFinalize when needed (#4877) --- src/passes/RedundantSetElimination.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/passes/RedundantSetElimination.cpp b/src/passes/RedundantSetElimination.cpp index 90925edf2..0b4cad056 100644 --- a/src/passes/RedundantSetElimination.cpp +++ b/src/passes/RedundantSetElimination.cpp @@ -67,6 +67,9 @@ struct RedundantSetElimination Index numLocals; + // In rare cases we make a change to a type that requires a refinalize. + bool refinalize = false; + // cfg traversal work static void doVisitLocalSet(RedundantSetElimination* self, @@ -94,6 +97,10 @@ struct RedundantSetElimination flowValues(func); // remove redundant sets optimize(); + + if (refinalize) { + ReFinalize().walkFunctionInModule(func, this->getModule()); + } } // Use a value numbering for the values of expressions. @@ -346,6 +353,20 @@ struct RedundantSetElimination drop->value = value; drop->finalize(); } else { + // If we are replacing the set with something of a more specific type, + // then we need to refinalize, for example: + // + // (struct.get $X 0 + // (local.tee $x + // (..something of type $Y, a subtype of $X..) + // ) + // ) + // + // After the replacement the struct.get will read from $Y, whose field may + // have a more refined type. + if (value->type != set->type) { + refinalize = true; + } *setp = value; } } -- cgit v1.2.3