From 9a776b56eb10f8aee63be9091614ddcac6856f17 Mon Sep 17 00:00:00 2001 From: "dongyifeng.axis" Date: Fri, 16 Sep 2022 23:49:41 +0800 Subject: [PATCH 1/6] address comment and add unit test --- src/passes/OptimizeAddedConstants.cpp | 26 +++++++++++----- .../optimize-added-constants-memory64.wast | 30 +++++++++++++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 test/lit/passes/optimize-added-constants-memory64.wast diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp index 8256169c121..9c540d5aca7 100644 --- a/src/passes/OptimizeAddedConstants.cpp +++ b/src/passes/OptimizeAddedConstants.cpp @@ -123,11 +123,23 @@ template class MemoryAccessOptimizer { // code may know that is valid, even if we can't. Only handle the // obviously valid case where an overflow can't occur. auto* c = curr->ptr->template cast(); - uint32_t base = c->value.geti32(); - uint32_t offset = curr->offset; - if (uint64_t(base) + uint64_t(offset) < (uint64_t(1) << 32)) { - c->value = c->value.add(Literal(uint32_t(curr->offset))); - curr->offset = 0; + if (memory64) { + uint64_t base = c->value.geti64(); + uint64_t offset = curr->offset; + + uint64_t max = std::numeric_limits::max(); + bool overflow = (base > max - offset) || (offset > max - base); + if (!overflow) { + c->value = c->value.add(Literal(offset)); + curr->offset = 0; + } + } else { + uint32_t base = c->value.geti32(); + uint32_t offset = curr->offset; + if (uint64_t(base) + uint64_t(offset) < (uint64_t(1) << 32)) { + c->value = c->value.add(Literal(uint32_t(curr->offset))); + curr->offset = 0; + } } } } @@ -222,9 +234,9 @@ template class MemoryAccessOptimizer { // Sees if we can optimize a particular constant. Result canOptimizeConstant(Literal literal) { - auto value = literal.geti32(); + uint64_t value = literal.getInteger(); // Avoid uninteresting corner cases with peculiar offsets. - if (value >= 0 && value < PassOptions::LowMemoryBound) { + if (value < PassOptions::LowMemoryBound) { // The total offset must not allow reaching reasonable memory // by overflowing. auto total = curr->offset + value; diff --git a/test/lit/passes/optimize-added-constants-memory64.wast b/test/lit/passes/optimize-added-constants-memory64.wast new file mode 100644 index 00000000000..095ac6ccdc0 --- /dev/null +++ b/test/lit/passes/optimize-added-constants-memory64.wast @@ -0,0 +1,30 @@ +;; RUN: wasm-opt %s -all --roundtrip --optimize-added-constants --low-memory-unused -S -o - | filecheck %s + +(module + (memory $0 i64 1 4294967296) + +;; CHECK: (func $load_i64 (result i64) +;; CHECK-NEXT: (i64.load +;; CHECK-NEXT: (i64.const 579) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (func $store +;; CHECK-NEXT: (i64.store +;; CHECK-NEXT: (i64.const 579) +;; CHECK-NEXT: (i64.const 123) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + + (func $load_i64 (result i64) + (i64.load offset=123 + (i64.const 456) + ) + ) + + (func $store (result) + (i64.store offset=123 + (i64.const 456) + (i64.const 123) + ) + ) +) From 37a53f077a78dd99ef7221b90ff51bf0806d127b Mon Sep 17 00:00:00 2001 From: "dongyifeng.axis" Date: Fri, 16 Sep 2022 00:29:40 +0800 Subject: [PATCH 2/6] add missing chance for memory64 --- src/passes/OptimizeAddedConstants.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp index 9c540d5aca7..b1d4a94750d 100644 --- a/src/passes/OptimizeAddedConstants.cpp +++ b/src/passes/OptimizeAddedConstants.cpp @@ -56,7 +56,7 @@ template class MemoryAccessOptimizer { return false; } if (auto* add = curr->ptr->template dynCast()) { - if (add->op == AddInt32) { + if (add->op == AddInt32 || add->op == AddInt64) { // Look for a constant on both sides. if (tryToOptimizeConstant(add->right, add->left) || tryToOptimizeConstant(add->left, add->right)) { From 71378754ccf90fe27bb2e9582412bfa059da1aa2 Mon Sep 17 00:00:00 2001 From: "dongyifeng.axis" Date: Fri, 16 Sep 2022 00:17:11 +0800 Subject: [PATCH 3/6] [opt] let OptimizeAddedConstants handle memory64 well --- src/passes/OptimizeAddedConstants.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp index b1d4a94750d..8fac2e815cc 100644 --- a/src/passes/OptimizeAddedConstants.cpp +++ b/src/passes/OptimizeAddedConstants.cpp @@ -45,7 +45,9 @@ template class MemoryAccessOptimizer { T* curr, Module* module, LocalGraph* localGraph) - : parent(parent), curr(curr), module(module), localGraph(localGraph) {} + : parent(parent), curr(curr), module(module), localGraph(localGraph) { + memory64 = module->getMemory(curr->memory)->is64(); + } // Tries to optimize, and returns whether we propagated a change. bool optimize() { @@ -110,6 +112,7 @@ template class MemoryAccessOptimizer { T* curr; Module* module; LocalGraph* localGraph; + bool memory64; void optimizeConstantPointer() { // The constant and an offset are interchangeable: From ec94230d66980cc76c7204094450a091a22827d2 Mon Sep 17 00:00:00 2001 From: "dongyifeng.axis" Date: Tue, 20 Sep 2022 20:36:01 +0800 Subject: [PATCH 4/6] update the test --- src/passes/OptimizeAddedConstants.cpp | 2 +- .../optimize-added-constants-memory64.wast | 28 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp index 8fac2e815cc..f48989d5b9f 100644 --- a/src/passes/OptimizeAddedConstants.cpp +++ b/src/passes/OptimizeAddedConstants.cpp @@ -131,7 +131,7 @@ template class MemoryAccessOptimizer { uint64_t offset = curr->offset; uint64_t max = std::numeric_limits::max(); - bool overflow = (base > max - offset) || (offset > max - base); + bool overflow = (base > max - offset); if (!overflow) { c->value = c->value.add(Literal(offset)); curr->offset = 0; diff --git a/test/lit/passes/optimize-added-constants-memory64.wast b/test/lit/passes/optimize-added-constants-memory64.wast index 095ac6ccdc0..939d6957de4 100644 --- a/test/lit/passes/optimize-added-constants-memory64.wast +++ b/test/lit/passes/optimize-added-constants-memory64.wast @@ -3,16 +3,27 @@ (module (memory $0 i64 1 4294967296) -;; CHECK: (func $load_i64 (result i64) -;; CHECK-NEXT: (i64.load +;; CHECK: (func $load_i64 (result i64) +;; CHECK-NEXT: (i64.load ;; CHECK-NEXT: (i64.const 579) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) +;; CHECK-NEXT: (func $load_overflow_i64 (result i64) +;; CHECK-NEXT: (i64.load offset=32 +;; CHECK-NEXT: (i64.const -16) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) ;; CHECK-NEXT: (func $store ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (i64.const 579) ;; CHECK-NEXT: (i64.const 123) ;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (func $store_overflow +;; CHECK-NEXT: (i64.store offset=32 +;; CHECK-NEXT: (i64.const -16) +;; CHECK-NEXT: (i64.const 123) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $load_i64 (result i64) @@ -21,10 +32,23 @@ ) ) + (func $load_overflow_i64 (result i64) + (i64.load offset=32 + (i64.const 0xfffffffffffffff0) + ) + ) + (func $store (result) (i64.store offset=123 (i64.const 456) (i64.const 123) ) ) + + (func $store_overflow (result) + (i64.store offset=32 + (i64.const 0xfffffffffffffff0) + (i64.const 123) + ) + ) ) From cc78ca8b94974e7ebdf11fc67de44e77d4f2ece3 Mon Sep 17 00:00:00 2001 From: Axis Date: Wed, 21 Sep 2022 00:08:15 +0800 Subject: [PATCH 5/6] Update test/lit/passes/optimize-added-constants-memory64.wast Co-authored-by: Alon Zakai --- test/lit/passes/optimize-added-constants-memory64.wast | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/lit/passes/optimize-added-constants-memory64.wast b/test/lit/passes/optimize-added-constants-memory64.wast index 939d6957de4..8db7c5ed393 100644 --- a/test/lit/passes/optimize-added-constants-memory64.wast +++ b/test/lit/passes/optimize-added-constants-memory64.wast @@ -1,3 +1,5 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + ;; RUN: wasm-opt %s -all --roundtrip --optimize-added-constants --low-memory-unused -S -o - | filecheck %s (module From c0f4373d19c9b76e27a84a7bc3b6cf40cbac9d00 Mon Sep 17 00:00:00 2001 From: "dongyifeng.axis" Date: Wed, 21 Sep 2022 08:12:37 +0800 Subject: [PATCH 6/6] update test --- .../optimize-added-constants-memory64.wast | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/test/lit/passes/optimize-added-constants-memory64.wast b/test/lit/passes/optimize-added-constants-memory64.wast index 8db7c5ed393..e44bc414bde 100644 --- a/test/lit/passes/optimize-added-constants-memory64.wast +++ b/test/lit/passes/optimize-added-constants-memory64.wast @@ -3,43 +3,38 @@ ;; RUN: wasm-opt %s -all --roundtrip --optimize-added-constants --low-memory-unused -S -o - | filecheck %s (module + ;; CHECK: (memory $0 i64 1 4294967296) (memory $0 i64 1 4294967296) -;; CHECK: (func $load_i64 (result i64) -;; CHECK-NEXT: (i64.load -;; CHECK-NEXT: (i64.const 579) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (func $load_overflow_i64 (result i64) -;; CHECK-NEXT: (i64.load offset=32 -;; CHECK-NEXT: (i64.const -16) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (func $store -;; CHECK-NEXT: (i64.store -;; CHECK-NEXT: (i64.const 579) -;; CHECK-NEXT: (i64.const 123) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (func $store_overflow -;; CHECK-NEXT: (i64.store offset=32 -;; CHECK-NEXT: (i64.const -16) -;; CHECK-NEXT: (i64.const 123) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) + ;; CHECK: (func $load_i64 (result i64) + ;; CHECK-NEXT: (i64.load + ;; CHECK-NEXT: (i64.const 579) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $load_i64 (result i64) (i64.load offset=123 (i64.const 456) ) ) + ;; CHECK: (func $load_overflow_i64 (result i64) + ;; CHECK-NEXT: (i64.load offset=32 + ;; CHECK-NEXT: (i64.const -16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $load_overflow_i64 (result i64) (i64.load offset=32 (i64.const 0xfffffffffffffff0) ) ) + ;; CHECK: (func $store + ;; CHECK-NEXT: (i64.store + ;; CHECK-NEXT: (i64.const 579) + ;; CHECK-NEXT: (i64.const 123) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $store (result) (i64.store offset=123 (i64.const 456) @@ -47,6 +42,12 @@ ) ) + ;; CHECK: (func $store_overflow + ;; CHECK-NEXT: (i64.store offset=32 + ;; CHECK-NEXT: (i64.const -16) + ;; CHECK-NEXT: (i64.const 123) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $store_overflow (result) (i64.store offset=32 (i64.const 0xfffffffffffffff0)