diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 8c13663deba..585072e99c3 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -570,11 +570,13 @@ struct OptimizeInstructions return replaceCurrent(getDroppedChildrenAndAppend(curr, c)); } // unsigned(x) < 0 => i32(0) - if (matches(curr, binary(LtU, any(&x), ival(&c))) && + if (curr->op == Abstract::getBinary(curr->left->type, Abstract::LtU) && + (c = getFallthrough(curr->right)->dynCast()) && c->value.isZero()) { - c->value = Literal::makeZero(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 zero = + Builder(*getModule()).makeConst(Literal::makeZero(Type::i32)); + return replaceCurrent(getDroppedChildrenAndAppend(curr, zero)); } } } diff --git a/test/lit/passes/optimize-instructions-mvp.wast b/test/lit/passes/optimize-instructions-mvp.wast index 9f505a7586f..4c184a852c3 100644 --- a/test/lit/passes/optimize-instructions-mvp.wast +++ b/test/lit/passes/optimize-instructions-mvp.wast @@ -175,6 +175,7 @@ ) ) ) + ;; CHECK: (func $eqz-gt_s (result i32) ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.const 0) @@ -11531,6 +11532,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 0) + ;; 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 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.ne ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (i32.const 0) @@ -11803,6 +11842,33 @@ ) (i64.const 0) )) + (drop (i32.lt_u + (i32.load + (i32.const 0) + ) + (block (result i32) + (i32.store + (i32.const 0) + (i32.const 0) + ) + (i32.const 0) + ) + ) + ) + (drop (i64.lt_u + (i64.load + (i32.const 0) + ) + (block (result i64) + (i64.store + (i32.const 0) + (i64.const 0) + ) + (i64.const 0) + ) + ) + ) + ;; (unsigned)x > 0 => x != 0 (drop (i32.gt_u