From 368e223adabd95f587573f87e6027c47c5e0e513 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 20 Feb 2026 10:45:47 -0800 Subject: [PATCH 1/2] opt --- src/passes/OptimizeInstructions.cpp | 34 +++++++---------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index fca53446d1f..f0e56c5f0f9 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -2826,31 +2826,9 @@ struct OptimizeInstructions return !Properties::isGenerative(left); } - // Similar to areConsecutiveInputsEqual() but also checks if we can remove - // them (but we do not assume the caller will always remove them). - bool areConsecutiveInputsEqualAndRemovable(Expression* left, - Expression* right) { - // First, check for side effects. If there are any, then we can't even - // assume things like local.get's of the same index being identical. (It is - // also ok to have removable side effects here, see the function - // description.) - auto& passOptions = getPassOptions(); - if (EffectAnalyzer(passOptions, *getModule(), left) - .hasUnremovableSideEffects() || - EffectAnalyzer(passOptions, *getModule(), right) - .hasUnremovableSideEffects()) { - return false; - } - - return areConsecutiveInputsEqual(left, right); - } - // Check if two consecutive inputs to an instruction are equal and can also be // folded into the first of the two (but we do not assume the caller will - // always fold them). This is similar to areConsecutiveInputsEqualAndRemovable - // but also identifies reads from the same local variable when the first of - // them is a "tee" operation and the second is a get (in which case, it is - // fine to remove the get, but not the tee). + // always fold them). // // The inputs here must be consecutive, but it is also ok to have code with no // side effects at all in the middle. For example, a Const in between is ok. @@ -2862,9 +2840,13 @@ struct OptimizeInstructions return true; } - // stronger property than we need - we can not only fold - // them but remove them entirely. - return areConsecutiveInputsEqualAndRemovable(left, right); + // To fold the right side into the left, it must have no effects. + if (EffectAnalyzer(getPassOptions(), *getModule(), right) + .hasUnremovableSideEffects()) { + return false; + } + + return areConsecutiveInputsEqual(left, right); } // Canonicalizing the order of a symmetric binary helps us From 6534777af53de1b294276a67fe61a260414bd127 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 20 Feb 2026 10:53:33 -0800 Subject: [PATCH 2/2] update --- .../lit/passes/optimize-instructions-mvp.wast | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/test/lit/passes/optimize-instructions-mvp.wast b/test/lit/passes/optimize-instructions-mvp.wast index 61afa766927..8a4b729fa9c 100644 --- a/test/lit/passes/optimize-instructions-mvp.wast +++ b/test/lit/passes/optimize-instructions-mvp.wast @@ -16141,17 +16141,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (call $send-i32 - ;; CHECK-NEXT: (i32.const 1337) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $x - ;; CHECK-NEXT: (local.get $param) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (call $send-i32 + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (local.get $param) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -16179,7 +16175,9 @@ ) ) ) - ;; Side effect on the ifTrue - same outcome, we cannot optimize yet. + ;; Side effect on the ifTrue - we handle this case, as we can easily see + ;; that those effects are not a problem. We keep those effects around, of + ;; course. (drop (select (block (result i32)