summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-08-08 16:04:25 -0700
committerGitHub <noreply@github.com>2023-08-08 16:04:25 -0700
commit0fc7b883d373924717ceccf71a6a759c97a8fb08 (patch)
tree610dc2ca3dd656f3ff5aa8cfa2ce7135099c67fa /test
parentef17febfd7106ee5330c01c66fbf8d3f6fdc0e03 (diff)
downloadbinaryen-0fc7b883d373924717ceccf71a6a759c97a8fb08.tar.gz
binaryen-0fc7b883d373924717ceccf71a6a759c97a8fb08.tar.bz2
binaryen-0fc7b883d373924717ceccf71a6a759c97a8fb08.zip
OptimizeCasts: Connect adjacent blocks in LinearExecutionWalker (#5866)
Followup to #5860, this does the same for (part of) OptimizeCasts. As there, this is valid because it's ok if we branch away. This part of the pass picks a different local to get when it knows locals have the same values but one is more refined. It is ok to add a tee earlier even if it isn't used later.
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/optimize-casts-noeh.wast18
-rw-r--r--test/lit/passes/optimize-casts.wast83
2 files changed, 80 insertions, 21 deletions
diff --git a/test/lit/passes/optimize-casts-noeh.wast b/test/lit/passes/optimize-casts-noeh.wast
index 46d92953d..6cd6fa704 100644
--- a/test/lit/passes/optimize-casts-noeh.wast
+++ b/test/lit/passes/optimize-casts-noeh.wast
@@ -34,26 +34,28 @@
)
)
- ;; CHECK: (func $not-past-return_call (type $ref|struct|_=>_none) (param $x (ref struct))
+ ;; CHECK: (func $yes-past-return_call (type $ref|struct|_=>_none) (param $x (ref struct))
+ ;; CHECK-NEXT: (local $1 (ref $A))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast $A
- ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.tee $1
+ ;; CHECK-NEXT: (ref.cast $A
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (return_call $none)
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $not-past-return_call (param $x (ref struct))
+ (func $yes-past-return_call (param $x (ref struct))
(drop
(ref.cast $A
(local.get $x)
)
)
- ;; The call_return in the middle stops us from helping the last get. We
- ;; could still optimize in this case, however, with more precision (since
- ;; after we branch out it doesn't matter what we have below).
+ ;; The call_return in the middle does not stop us from optimizing, since
+ ;; after we branch out it doesn't matter what we have below.
(return_call $none)
(drop
(local.get $x)
diff --git a/test/lit/passes/optimize-casts.wast b/test/lit/passes/optimize-casts.wast
index 83cde8a4b..254daedc4 100644
--- a/test/lit/passes/optimize-casts.wast
+++ b/test/lit/passes/optimize-casts.wast
@@ -177,28 +177,30 @@
)
)
- ;; CHECK: (func $not-past-call (type $ref|struct|_=>_none) (param $x (ref struct))
+ ;; CHECK: (func $yes-past-call (type $ref|struct|_=>_none) (param $x (ref struct))
+ ;; CHECK-NEXT: (local $1 (ref $A))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast $A
- ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.tee $1
+ ;; CHECK-NEXT: (ref.cast $A
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $get)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $not-past-call (param $x (ref struct))
+ (func $yes-past-call (param $x (ref struct))
(drop
(ref.cast $A
(local.get $x)
)
)
- ;; The call in the middle stops us from helping the last get, since a call
- ;; might branch out. TODO we could still optimize in this case, with more
- ;; precision (since if we branch out it doesn't matter what we have below).
+ ;; The call in the middle does not stops us from helping the last get, since
+ ;; if we branch out it doesn't matter what we have below.
(drop
(call $get)
)
@@ -208,16 +210,19 @@
)
;; CHECK: (func $not-past-call_ref (type $ref|struct|_=>_none) (param $x (ref struct))
+ ;; CHECK-NEXT: (local $1 (ref $A))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.cast $A
- ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.tee $1
+ ;; CHECK-NEXT: (ref.cast $A
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_ref $void
;; CHECK-NEXT: (ref.func $void)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $not-past-call_ref (param $x (ref struct))
@@ -226,8 +231,7 @@
(local.get $x)
)
)
- ;; As in the last function, the call in the middle stops us from helping the
- ;; last get (this time with a call_ref).
+ ;; As in the last function, but a call_ref.
(call_ref $void
(ref.func $void)
)
@@ -236,6 +240,59 @@
)
)
+ ;; CHECK: (func $not-backwards-past-call (type $ref|struct|_=>_none) (param $x (ref struct))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $void)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.cast $A
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $not-backwards-past-call (param $x (ref struct))
+ ;; As above, but here we would like to move a cast *earlier*. We must not do
+ ;; that past a possible branch.
+ (drop
+ (local.get $x)
+ )
+ (call $void)
+ (drop
+ (ref.cast $A
+ (local.get $x)
+ )
+ )
+ )
+
+ ;; CHECK: (func $not-backwards-past-call_ref (type $ref|struct|_=>_none) (param $x (ref struct))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call_ref $void
+ ;; CHECK-NEXT: (ref.func $void)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.cast $A
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $not-backwards-past-call_ref (param $x (ref struct))
+ ;; As above, but with a call_ref.
+ (drop
+ (local.get $x)
+ )
+ (call_ref $void
+ (ref.func $void)
+ )
+ (drop
+ (ref.cast $A
+ (local.get $x)
+ )
+ )
+ )
+
;; CHECK: (func $best (type $ref|struct|_=>_none) (param $x (ref struct))
;; CHECK-NEXT: (local $1 (ref $A))
;; CHECK-NEXT: (local $2 (ref $B))