diff options
author | Alon Zakai <azakai@google.com> | 2024-05-14 10:11:40 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-14 10:11:40 -0700 |
commit | 76a2c64402ebcc3ae6bf32f5f1c90f07d42cfa4b (patch) | |
tree | d89d74c2c4c199d1deb6bfb2c2ed50bb579bdb89 /test | |
parent | 4ca05f765ca6ec99b7582d357520ca217265677d (diff) | |
download | binaryen-76a2c64402ebcc3ae6bf32f5f1c90f07d42cfa4b.tar.gz binaryen-76a2c64402ebcc3ae6bf32f5f1c90f07d42cfa4b.tar.bz2 binaryen-76a2c64402ebcc3ae6bf32f5f1c90f07d42cfa4b.zip |
LocalCSE: Ignore traps of code in between (#6588)
Given:
(ORIGINAL)
(in between)
(COPY)
We want to change that to
(local.tee $temp (ORIGINAL))
(in between)
(local.get $temp)
It is fine if "in between" traps: then we never reach the new local.get. This is a safer
situation than most optimizations because we are not reordering anything, only
replacing known-equivalent code.
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/local-cse_all-features.wast | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/test/lit/passes/local-cse_all-features.wast b/test/lit/passes/local-cse_all-features.wast index cbd5c68c2..d943b940f 100644 --- a/test/lit/passes/local-cse_all-features.wast +++ b/test/lit/passes/local-cse_all-features.wast @@ -350,3 +350,55 @@ ) ) ) + +(module + ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct (field i32))) + + ;; CHECK: (type $1 (func (param anyref))) + + ;; CHECK: (type $2 (func (param i32))) + + ;; CHECK: (func $caller (type $1) (param $x anyref) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (call $callee + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (ref.cast (ref $struct) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $callee + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $caller (param $x anyref) + (call $callee + (struct.get $struct 0 + (ref.cast (ref $struct) + (local.get $x) + ) + ) + ) + ;; The call in between the struct.get has effects, but they do not + ;; interfere: the struct.get reads locals and immutable data only, and we + ;; can ignore possible traps in both the call and the struct.get (as if + ;; anything traps we just don't reach the local.get that the optimization + ;; emits). + (call $callee + (struct.get $struct 0 + (ref.cast (ref $struct) + (local.get $x) + ) + ) + ) + ) + + ;; CHECK: (func $callee (type $2) (param $x i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $callee (param $x i32) + ) +) |