summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-07-08 14:18:31 -0700
committerGitHub <noreply@github.com>2024-07-08 14:18:31 -0700
commite93babcd71a89bd8c8e170d11652ca7375ef01f3 (patch)
treeb1c9bbcd1a13db9051838e9f13ab85292c5c439b /test
parent4179603f8c21f5676cf4826ec4e41a1513c41540 (diff)
downloadbinaryen-e93babcd71a89bd8c8e170d11652ca7375ef01f3.tar.gz
binaryen-e93babcd71a89bd8c8e170d11652ca7375ef01f3.tar.bz2
binaryen-e93babcd71a89bd8c8e170d11652ca7375ef01f3.zip
StackIR: Optimize away a drop before an unreachable (#6719)
Anything else right before an unreachable is removed by the main DCE pass anyhow, but because of the structured form of BinaryenIR we can't remove a drop. That is, this is the difference between (i32.eqz (i32.const 42) (unreachable) ) and (drop (call $foo) ) (unreachable) In both cases the unreachable is preceded by something we don't need, but in the latter case it must remain in BinaryenIR for validation. To optimize this, add a rule in StackIR. Fixes #6715
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/stack-ir-dce.wast118
1 files changed, 118 insertions, 0 deletions
diff --git a/test/lit/passes/stack-ir-dce.wast b/test/lit/passes/stack-ir-dce.wast
new file mode 100644
index 000000000..24afb4840
--- /dev/null
+++ b/test/lit/passes/stack-ir-dce.wast
@@ -0,0 +1,118 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
+
+;; RUN: wasm-opt %s --generate-stack-ir --optimize-stack-ir -all --print-stack-ir | filecheck %s
+;; Also verify we roundtrip the output here properly.
+;; RUN: wasm-opt %s --generate-stack-ir --optimize-stack-ir -all --roundtrip --print | filecheck %s --check-prefix=ROUNDTRIP
+
+(module
+ ;; CHECK: (func $drop-unreachable (type $0) (result i32)
+ ;; CHECK-NEXT: call $drop-unreachable
+ ;; CHECK-NEXT: unreachable
+ ;; CHECK-NEXT: )
+ ;; ROUNDTRIP: (func $drop-unreachable (type $0) (result i32)
+ ;; ROUNDTRIP-NEXT: (drop
+ ;; ROUNDTRIP-NEXT: (call $drop-unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ ;; ROUNDTRIP-NEXT: (unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ (func $drop-unreachable (result i32)
+ ;; This drop can be removed.
+ (drop
+ (call $drop-unreachable)
+ )
+ (unreachable)
+ )
+
+ ;; CHECK: (func $unreachable (type $0) (result i32)
+ ;; CHECK-NEXT: unreachable
+ ;; CHECK-NEXT: )
+ ;; ROUNDTRIP: (func $unreachable (type $0) (result i32)
+ ;; ROUNDTRIP-NEXT: (unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ (func $unreachable (result i32)
+ ;; An unreachable with nothing before it. Check we do not error here.
+ (unreachable)
+ )
+
+ ;; CHECK: (func $unreachable-non-drop (type $1)
+ ;; CHECK-NEXT: call $unreachable-non-drop
+ ;; CHECK-NEXT: unreachable
+ ;; CHECK-NEXT: )
+ ;; ROUNDTRIP: (func $unreachable-non-drop (type $1)
+ ;; ROUNDTRIP-NEXT: (call $unreachable-non-drop)
+ ;; ROUNDTRIP-NEXT: (unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ (func $unreachable-non-drop
+ ;; An unreachable with something other than a drop before it. Check we do
+ ;; not error here.
+ (call $unreachable-non-drop)
+ (unreachable)
+ )
+
+ ;; CHECK: (func $many-drop-unreachable (type $0) (result i32)
+ ;; CHECK-NEXT: i32.const 1
+ ;; CHECK-NEXT: if (result i32)
+ ;; CHECK-NEXT: call $drop-unreachable
+ ;; CHECK-NEXT: unreachable
+ ;; CHECK-NEXT: else
+ ;; CHECK-NEXT: call $drop-unreachable
+ ;; CHECK-NEXT: unreachable
+ ;; CHECK-NEXT: end
+ ;; CHECK-NEXT: drop
+ ;; CHECK-NEXT: call $drop-unreachable
+ ;; CHECK-NEXT: unreachable
+ ;; CHECK-NEXT: )
+ ;; ROUNDTRIP: (func $many-drop-unreachable (type $0) (result i32)
+ ;; ROUNDTRIP-NEXT: (drop
+ ;; ROUNDTRIP-NEXT: (if (result i32)
+ ;; ROUNDTRIP-NEXT: (i32.const 1)
+ ;; ROUNDTRIP-NEXT: (then
+ ;; ROUNDTRIP-NEXT: (drop
+ ;; ROUNDTRIP-NEXT: (call $drop-unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ ;; ROUNDTRIP-NEXT: (unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ ;; ROUNDTRIP-NEXT: (else
+ ;; ROUNDTRIP-NEXT: (drop
+ ;; ROUNDTRIP-NEXT: (call $drop-unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ ;; ROUNDTRIP-NEXT: (unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ ;; ROUNDTRIP-NEXT: )
+ ;; ROUNDTRIP-NEXT: )
+ ;; ROUNDTRIP-NEXT: (drop
+ ;; ROUNDTRIP-NEXT: (call $drop-unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ ;; ROUNDTRIP-NEXT: (unreachable)
+ ;; ROUNDTRIP-NEXT: )
+ (func $many-drop-unreachable (result i32)
+ ;; Two drop-unreachables in an if. The drop on the if can remain, but all
+ ;; others are removable.
+ (drop
+ (if (result i32)
+ (i32.const 1)
+ (then
+ (drop
+ (call $drop-unreachable)
+ )
+ (unreachable)
+ )
+ (else
+ (drop
+ (call $drop-unreachable)
+ )
+ (unreachable)
+ )
+ )
+ )
+ ;; Two more outside the if.
+ (drop
+ (call $drop-unreachable)
+ )
+ (unreachable)
+ (drop
+ (call $drop-unreachable)
+ )
+ (unreachable)
+ )
+)