summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-01-26 16:43:35 -0800
committerGitHub <noreply@github.com>2023-01-26 16:43:35 -0800
commit81c136964750e64157963ef41a596c8ae91fb98c (patch)
tree5e24a1e33ea356c333a43fe8e4d77297f1663524
parent0e4712f8dbbc43c6c55041e2359f24aa42ae0fdb (diff)
downloadbinaryen-81c136964750e64157963ef41a596c8ae91fb98c.tar.gz
binaryen-81c136964750e64157963ef41a596c8ae91fb98c.tar.bz2
binaryen-81c136964750e64157963ef41a596c8ae91fb98c.zip
[Wasm GC] Refinalize fuzz fix in OptimizeInstructions cast optimizations (#5460)
-rw-r--r--src/passes/OptimizeInstructions.cpp6
-rw-r--r--test/lit/passes/optimize-instructions-gc-tnh.wast78
2 files changed, 84 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 6537e9b56..41f7a9e11 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1566,11 +1566,17 @@ struct OptimizeInstructions
if (auto* iff = ref->dynCast<If>()) {
if (iff->ifFalse) {
if (iff->ifTrue->type.isNull()) {
+ if (ref->type != iff->ifFalse->type) {
+ refinalize = true;
+ }
ref = builder.makeSequence(builder.makeDrop(iff->condition),
iff->ifFalse);
return false;
}
if (iff->ifFalse->type.isNull()) {
+ if (ref->type != iff->ifTrue->type) {
+ refinalize = true;
+ }
ref = builder.makeSequence(builder.makeDrop(iff->condition),
iff->ifTrue);
return false;
diff --git a/test/lit/passes/optimize-instructions-gc-tnh.wast b/test/lit/passes/optimize-instructions-gc-tnh.wast
index c6aab6c88..2307362ff 100644
--- a/test/lit/passes/optimize-instructions-gc-tnh.wast
+++ b/test/lit/passes/optimize-instructions-gc-tnh.wast
@@ -525,6 +525,84 @@
)
)
+ ;; TNH: (func $cast-if-null (type $none_=>_ref|$struct|) (result (ref $struct))
+ ;; TNH-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; TNH-NEXT: (drop
+ ;; TNH-NEXT: (block
+ ;; TNH-NEXT: (drop
+ ;; TNH-NEXT: (i32.const 1)
+ ;; TNH-NEXT: )
+ ;; TNH-NEXT: (unreachable)
+ ;; TNH-NEXT: )
+ ;; TNH-NEXT: )
+ ;; TNH-NEXT: (unreachable)
+ ;; TNH-NEXT: )
+ ;; TNH-NEXT: )
+ ;; NO_TNH: (func $cast-if-null (type $none_=>_ref|$struct|) (result (ref $struct))
+ ;; NO_TNH-NEXT: (drop
+ ;; NO_TNH-NEXT: (if (result (ref none))
+ ;; NO_TNH-NEXT: (i32.const 1)
+ ;; NO_TNH-NEXT: (unreachable)
+ ;; NO_TNH-NEXT: (ref.as_non_null
+ ;; NO_TNH-NEXT: (ref.null none)
+ ;; NO_TNH-NEXT: )
+ ;; NO_TNH-NEXT: )
+ ;; NO_TNH-NEXT: )
+ ;; NO_TNH-NEXT: (unreachable)
+ ;; NO_TNH-NEXT: )
+ (func $cast-if-null (result (ref $struct))
+ ;; We can remove the unreachable arm of the if here in TNH mode. While doing
+ ;; so we must refinalize properly or else we'll hit an error in pass-debug
+ ;; mode.
+ (ref.cast $struct
+ (if (result (ref none))
+ (i32.const 1)
+ (unreachable)
+ (ref.as_non_null
+ (ref.null none)
+ )
+ )
+ )
+ )
+
+ ;; TNH: (func $cast-if-null-flip (type $none_=>_ref|$struct|) (result (ref $struct))
+ ;; TNH-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; TNH-NEXT: (drop
+ ;; TNH-NEXT: (block
+ ;; TNH-NEXT: (drop
+ ;; TNH-NEXT: (i32.const 1)
+ ;; TNH-NEXT: )
+ ;; TNH-NEXT: (unreachable)
+ ;; TNH-NEXT: )
+ ;; TNH-NEXT: )
+ ;; TNH-NEXT: (unreachable)
+ ;; TNH-NEXT: )
+ ;; TNH-NEXT: )
+ ;; NO_TNH: (func $cast-if-null-flip (type $none_=>_ref|$struct|) (result (ref $struct))
+ ;; NO_TNH-NEXT: (drop
+ ;; NO_TNH-NEXT: (if (result (ref none))
+ ;; NO_TNH-NEXT: (i32.const 1)
+ ;; NO_TNH-NEXT: (ref.as_non_null
+ ;; NO_TNH-NEXT: (ref.null none)
+ ;; NO_TNH-NEXT: )
+ ;; NO_TNH-NEXT: (unreachable)
+ ;; NO_TNH-NEXT: )
+ ;; NO_TNH-NEXT: )
+ ;; NO_TNH-NEXT: (unreachable)
+ ;; NO_TNH-NEXT: )
+ (func $cast-if-null-flip (result (ref $struct))
+ ;; As above but with arms flipped.
+ (ref.cast $struct
+ (if (result (ref none))
+ (i32.const 1)
+ (ref.as_non_null
+ (ref.null none)
+ )
+ (unreachable)
+ )
+ )
+ )
+
;; Helper functions.
;; TNH: (func $get-i32 (type $none_=>_i32) (result i32)