diff options
author | Thomas Lively <tlively@google.com> | 2022-11-08 15:43:22 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-08 15:43:22 -0800 |
commit | d7920cb9dc07a2efee8abf44d7c1a6a654a88593 (patch) | |
tree | c1d8dd9ebfb1c81edddfd156edc0c366135d200c | |
parent | 85ba74c8162ebf4e659a3450de0fb48a4a7141b0 (diff) | |
download | binaryen-d7920cb9dc07a2efee8abf44d7c1a6a654a88593.tar.gz binaryen-d7920cb9dc07a2efee8abf44d7c1a6a654a88593.tar.bz2 binaryen-d7920cb9dc07a2efee8abf44d7c1a6a654a88593.zip |
Fix possible-contents.h for `array.new_{data,elem}` (#5232)
* Update MemoryPacking for array.new_data
The MemoryPacking pass looks at all instructions that reference memory segments
to determine how they can be optimized. #5214 introduced a new instruction that
references memory segments, array.new_data, but did not update MemoryPacking
accordingly. This omission meant that MemoryPacking could produce invalid or
misoptimized modules in the presence of array.new_data.
Fix the problem by making MemoryPacking aware of array.new_data. Consider
array.new_data when determining whether a segment is used and update
array.new_data to reflect the new, optimized segment numberings afterward. To
keep things simple, do not try to split any segment that is referred to by
a array.new_data instruction.
* fix
* Add test explanations
* Fix possible-contents.h for `array.new_{data,elem}`
This code was not properly updated in #5214, so GUFA would incorrectly optimize
out `array.new_data` and `array.new_elem` instructions. Fix the problem by
making these instructions data flow roots.
* fix
* move tests
-rw-r--r-- | src/ir/possible-contents.cpp | 1 | ||||
-rw-r--r-- | test/lit/passes/gufa-refs.wast | 70 |
2 files changed, 71 insertions, 0 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index 0c4e28568..35e87175a 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -900,6 +900,7 @@ struct InfoCollector if (curr->type == Type::unreachable) { return; } + addRoot(curr, PossibleContents::exactType(curr->type)); auto heapType = curr->type.getHeapType(); switch (curr->op) { case NewData: { diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index e5df2afd4..fc01dd481 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -5393,3 +5393,73 @@ ) ) ) + + +;; Check that array.new_data and array.new_seg are handled properly. +(module + ;; CHECK: (type $array-i8 (array_subtype i8 data)) + (type $array-i8 (array i8)) + ;; CHECK: (type $array-funcref (array_subtype funcref data)) + (type $array-funcref (array funcref)) + ;; CHECK: (type $ref|$array-i8|_ref|$array-funcref|_=>_none (func_subtype (param (ref $array-i8) (ref $array-funcref)) func)) + + ;; CHECK: (data "hello") + (data "hello") + ;; CHECK: (elem func $test) + (elem func $test) + + ;; CHECK: (export "test" (func $test)) + + ;; CHECK: (func $test (type $ref|$array-i8|_ref|$array-funcref|_=>_none) (param $array-i8 (ref $array-i8)) (param $array-funcref (ref $array-funcref)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_data $array-i8 0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_elem $array-funcref 0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.get_u $array-i8 + ;; CHECK-NEXT: (local.get $array-i8) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.get $array-funcref + ;; CHECK-NEXT: (local.get $array-funcref) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (export "test") (param $array-i8 (ref $array-i8)) (param $array-funcref (ref $array-funcref)) + (drop + (array.new_data $array-i8 0 + (i32.const 0) + (i32.const 5) + ) + ) + (drop + (array.new_elem $array-funcref 0 + (i32.const 0) + (i32.const 1) + ) + ) + (drop + (array.get $array-i8 + (local.get $array-i8) + (i32.const 0) + ) + ) + (drop + (array.get $array-funcref + (local.get $array-funcref) + (i32.const 0) + ) + ) + ) +) |