diff options
author | Alon Zakai <azakai@google.com> | 2023-01-26 16:43:35 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-26 16:43:35 -0800 |
commit | 81c136964750e64157963ef41a596c8ae91fb98c (patch) | |
tree | 5e24a1e33ea356c333a43fe8e4d77297f1663524 | |
parent | 0e4712f8dbbc43c6c55041e2359f24aa42ae0fdb (diff) | |
download | binaryen-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.cpp | 6 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-gc-tnh.wast | 78 |
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) |