summaryrefslogtreecommitdiff
path: root/test/lit/passes
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-03-22 13:20:47 -0700
committerGitHub <noreply@github.com>2024-03-22 20:20:47 +0000
commitf40e90aa2ae7c56d534d1c2b74ea173a85ce4039 (patch)
tree0876efcf61f9aeedb191b5ff350b07e5308acf58 /test/lit/passes
parent2471301a5209724b1ea32fab36b13410e96c0af9 (diff)
downloadbinaryen-f40e90aa2ae7c56d534d1c2b74ea173a85ce4039.tar.gz
binaryen-f40e90aa2ae7c56d534d1c2b74ea173a85ce4039.tar.bz2
binaryen-f40e90aa2ae7c56d534d1c2b74ea173a85ce4039.zip
Precompute: Mark StringEncode as non-removable, just like ArrayCopy (#6423)
The only StringEncode we support is the one that writes into an array, so it has the same effects as ArrayCopy. Precompute needs to be made aware of such side effects in a manual manner (as we already do for ArrayCopy etc.): it simply tries to execute code in the interpreter, and if it succeeds it replaces; it does not check for side effects (checking for side effects would prevent optimizing cases where the side effects do not happen, as we check them statically, e.g. dividing by a non-zero constant does not trap but a division would be seen as having a potential trap effect). I verified no other string operation is hit by this: all the others emit or operate on immutable strings; it is just StringEncode that is basically an Array operation that appears in the Strings proposal.)
Diffstat (limited to 'test/lit/passes')
-rw-r--r--test/lit/passes/precompute-strings.wast66
1 files changed, 60 insertions, 6 deletions
diff --git a/test/lit/passes/precompute-strings.wast b/test/lit/passes/precompute-strings.wast
index c9facfe36..197e62c7a 100644
--- a/test/lit/passes/precompute-strings.wast
+++ b/test/lit/passes/precompute-strings.wast
@@ -1,17 +1,21 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
-;; RUN: wasm-opt %s --precompute -all -S -o - | filecheck %s
+;; RUN: wasm-opt %s --precompute-propagate -all -S -o - | filecheck %s
(module
;; CHECK: (type $0 (func (result i32)))
- ;; CHECK: (type $1 (func (result (ref string))))
-
;; CHECK: (type $array16 (array (mut i16)))
(type $array16 (array (mut i16)))
+ ;; CHECK: (type $2 (func (result (ref string))))
+
+ ;; CHECK: (type $3 (func (result (ref any))))
+
;; CHECK: (export "get_codepoint-bad" (func $get_codepoint-bad))
+ ;; CHECK: (export "test" (func $encode-stashed))
+
;; CHECK: (export "slice" (func $slice))
;; CHECK: (export "slice-bad" (func $slice-bad))
@@ -124,9 +128,17 @@
)
;; CHECK: (func $encode (type $0) (result i32)
- ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: (string.encode_wtf16_array
+ ;; CHECK-NEXT: (string.const "$_")
+ ;; CHECK-NEXT: (array.new_default $array16
+ ;; CHECK-NEXT: (i32.const 20)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $encode (result i32)
+ ;; We could optimize away the encode operation here as the reference does not
+ ;; escape, but we do not do escape analysis here.
(string.encode_wtf16_array
(string.const "$_")
(array.new_default $array16
@@ -156,7 +168,49 @@
)
)
- ;; CHECK: (func $slice (type $1) (result (ref string))
+ ;; CHECK: (func $encode-stashed (type $3) (result (ref any))
+ ;; CHECK-NEXT: (local $1 (ref $array16))
+ ;; CHECK-NEXT: (local.set $1
+ ;; CHECK-NEXT: (array.new_default $array16
+ ;; CHECK-NEXT: (i32.const 10)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (string.encode_wtf16_array
+ ;; CHECK-NEXT: (string.as_wtf16
+ ;; CHECK-NEXT: (string.const "0123456789")
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ (func $encode-stashed (export "test") (result (ref any))
+ (local $1 (ref $array16))
+ ;; Create a zero-filled array.
+ (local.set $1
+ (array.new_default $array16
+ (i32.const 10)
+ )
+ )
+ ;; Fill it with some string data.
+ (drop
+ (string.encode_wtf16_array
+ (string.as_wtf16
+ (string.const "0123456789")
+ )
+ (local.get $1)
+ (i32.const 0)
+ )
+ )
+ ;; Return the modified array. We must not have removed the encode operation
+ ;; above us (it has the side effect of modifying the array, just like an
+ ;; array.copy does).
+ (local.get $1)
+ )
+
+ ;; CHECK: (func $slice (type $2) (result (ref string))
;; CHECK-NEXT: (string.const "def")
;; CHECK-NEXT: )
(func $slice (export "slice") (result (ref string))
@@ -168,7 +222,7 @@
)
)
- ;; CHECK: (func $slice-bad (type $1) (result (ref string))
+ ;; CHECK: (func $slice-bad (type $2) (result (ref string))
;; CHECK-NEXT: (stringview_wtf16.slice
;; CHECK-NEXT: (string.const "abcd\c2\a3fgh")
;; CHECK-NEXT: (i32.const 3)