diff options
author | Alon Zakai <azakai@google.com> | 2021-05-26 14:10:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-26 14:10:03 -0700 |
commit | 27a18f990e022cfe5b6a5485fd2eaca73b6dfbaa (patch) | |
tree | 9c37ba9241483c12ca511ee3b0d6cadf003cd68d /test | |
parent | 7f31823120ba25075d783df863f6be536543f805 (diff) | |
download | binaryen-27a18f990e022cfe5b6a5485fd2eaca73b6dfbaa.tar.gz binaryen-27a18f990e022cfe5b6a5485fd2eaca73b6dfbaa.tar.bz2 binaryen-27a18f990e022cfe5b6a5485fd2eaca73b6dfbaa.zip |
[Wasm GC] Implement CFGWalker support for BrOn* (#3908)
Without adding logic there, it simply ignored the branch, which could
lead to bad optimizations (thinking code is unreachable when it was).
There isn't a trivial way to add a static error to force us to add new
classes to CFGWalker. But this PR generalizes the code there to
handle all branches and all unreachable instructions in a generic
way. The only thing we'll need to remember to do in the future is to
add control flow structures. (And normally the fuzzer should quickly
find such bugs, but we don't have full fuzzing enabled for GC yet.)
Fixes #3907
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/coalesce-locals-gc.wast | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/test/lit/passes/coalesce-locals-gc.wast b/test/lit/passes/coalesce-locals-gc.wast index 5bad35001..173ad02be 100644 --- a/test/lit/passes/coalesce-locals-gc.wast +++ b/test/lit/passes/coalesce-locals-gc.wast @@ -3,6 +3,9 @@ ;; RUN: | filecheck %s (module + (type $array (array (mut i8))) + (global $global (ref null $array) (ref.null $array)) + ;; CHECK: (func $test-dead-get-non-nullable (param $0 dataref) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (drop @@ -18,4 +21,40 @@ (local.get $func) ) ) + + ;; CHECK: (func $br_on_null (param $0 (ref null $array)) (result (ref null $array)) + ;; CHECK-NEXT: (block $label$1 (result (ref null $array)) + ;; CHECK-NEXT: (block $label$2 + ;; CHECK-NEXT: (br $label$1 + ;; CHECK-NEXT: (br_on_null $label$2 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (global.get $global) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br_on_null (param $ref (ref null $array)) (result (ref null $array)) + (local $1 (ref null $array)) + (block $label$1 (result (ref null $array)) + (block $label$2 + (br $label$1 + ;; Test that we properly model the basic block connections around a + ;; BrOnNull. There should be a branch to $label$2, and also a fallthrough. + ;; As a result, the local.set below is reachable, and should not be + ;; eliminated (turned into a drop). + (br_on_null $label$2 + (local.get $ref) + ) + ) + ) + (local.set $1 + (global.get $global) + ) + (local.get $1) + ) + ) ) |