diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index a8a2c6bf5bc..eb302298719 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -562,12 +562,13 @@ struct OptimizeInstructions { // unsigned(x) >= 0 => i32(1) Const* c; - Expression* x; - if (matches(curr, binary(GeU, any(&x), ival(&c))) && + if (curr->op == Abstract::getBinary(curr->left->type, Abstract::GeU) && + (c = getFallthrough(curr->right)->dynCast()) && c->value.isZero()) { - c->value = Literal::makeOne(Type::i32); - c->type = Type::i32; - return replaceCurrent(getDroppedChildrenAndAppend(curr, c)); + // We could reuse c here, if we checked it had no more uses + auto one = + Builder(*getModule()).makeConst(Literal::makeOne(Type::i32)); + return replaceCurrent(getDroppedChildrenAndAppend(curr, one)); } // unsigned(x) < 0 => i32(0) if (curr->op == Abstract::getBinary(curr->left->type, Abstract::LtU) && diff --git a/test/lit/passes/optimize-instructions-mvp.wast b/test/lit/passes/optimize-instructions-mvp.wast index 7b5551a67a9..71f04e82dae 100644 --- a/test/lit/passes/optimize-instructions-mvp.wast +++ b/test/lit/passes/optimize-instructions-mvp.wast @@ -11550,6 +11550,44 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i64) + ;; CHECK-NEXT: (i64.store + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -11884,6 +11922,34 @@ ) (i64.const 0) )) + ;; Add side effects on both arms of the i32.ge_u, which force us to + ;; look at the fallthrough in order to optimize. + (drop (i32.ge_u + (i32.load + (i32.const 0) + ) + (block (result i32) + (i32.store + (i32.const 0) + (i32.const 0) + ) + (i32.const 0) + ) + ) + ) + (drop (i64.ge_u + (i64.load + (i32.const 0) + ) + (block (result i64) + (i64.store + (i32.const 0) + (i64.const 0) + ) + (i64.const 0) + ) + ) + ) ;; (unsigned)x < 0 => i32(0) (drop (i32.lt_u