diff options
author | Thomas Lively <tlively@google.com> | 2024-06-11 13:11:04 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-11 13:11:04 -0700 |
commit | cdd94a01ad02e944eaa9ba5e20a1129bef9ac305 (patch) | |
tree | b4d59b21019dea59776b6f6e8347c0eef4b98022 /test/lit/exec | |
parent | 3d0e687447be426c4157dbe9c6d2626b147f85bf (diff) | |
download | binaryen-cdd94a01ad02e944eaa9ba5e20a1129bef9ac305.tar.gz binaryen-cdd94a01ad02e944eaa9ba5e20a1129bef9ac305.tar.bz2 binaryen-cdd94a01ad02e944eaa9ba5e20a1129bef9ac305.zip |
Fix scratch local optimizations when emitting string slice (#6649)
The binary writing of `stringview_wtf16.slice` requires scratch locals to store
the `start` and `end` operands while the string operand is converted to a
stringview. To avoid unbounded binary bloat when round-tripping, we detect the
case that `start` and `end` are already `local.get`s and avoid using scratch
locals by deferring the binary writing of the `local.get` operands until after
the stringview conversoins is emitted.
We previously optimized the scratch locals for `start` and `end` independently,
but this could produce incorrect code in the case where the `local.get` for
`start` is deferred but its value is changed by a `local.set` in the code for
`end`. Fix the problem by only optimizing to avoid scratch locals in the case
where both `start` and `end` are already `local.get`s, so they will still be
emitted in the original relative order and they cannot interfere with each other
anyway.
Diffstat (limited to 'test/lit/exec')
-rw-r--r-- | test/lit/exec/strings.wast | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/test/lit/exec/strings.wast b/test/lit/exec/strings.wast index ca77f9882..f0c659d19 100644 --- a/test/lit/exec/strings.wast +++ b/test/lit/exec/strings.wast @@ -284,6 +284,21 @@ ) ) + ;; CHECK: [fuzz-exec] calling slice-ordering + ;; CHECK-NEXT: [fuzz-exec] note result: slice-ordering => string("h") + (func $slice-ordering (export "slice-ordering") (result (ref string)) + (local $0 i32) + (stringview_wtf16.slice + (string.const "hello") + ;; If we were to defer emitting this get in the binary writer, it would + ;; end up with the wrong value. + (local.get $0) + (local.tee $0 + (i32.const 1) + ) + ) + ) + ;; CHECK: [fuzz-exec] calling new_empty ;; CHECK-NEXT: [fuzz-exec] note result: new_empty => string("") (func $new_empty (export "new_empty") (result stringref) @@ -536,6 +551,9 @@ ;; CHECK: [fuzz-exec] calling slice-big ;; CHECK-NEXT: [fuzz-exec] note result: slice-big => string("defgh") +;; CHECK: [fuzz-exec] calling slice-ordering +;; CHECK-NEXT: [fuzz-exec] note result: slice-ordering => string("h") + ;; CHECK: [fuzz-exec] calling new_empty ;; CHECK-NEXT: [fuzz-exec] note result: new_empty => string("") @@ -620,6 +638,7 @@ ;; CHECK-NEXT: [fuzz-exec] comparing new_wtf16_array ;; CHECK-NEXT: [fuzz-exec] comparing slice ;; CHECK-NEXT: [fuzz-exec] comparing slice-big +;; CHECK-NEXT: [fuzz-exec] comparing slice-ordering ;; CHECK-NEXT: [fuzz-exec] comparing slice-unicode ;; CHECK-NEXT: [fuzz-exec] comparing string.from_code_point ;; CHECK-NEXT: [fuzz-exec] comparing string.measure |