diff options
author | Ashley Nelson <nashley@google.com> | 2023-12-06 22:25:53 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-06 22:25:53 -0800 |
commit | b8cf38693103127913a12240cbbcabe8ff47c719 (patch) | |
tree | f95493abaeddfbd95bcc3e80edde1a367e556174 /test | |
parent | 89ad929e11b43c0224d32fd6cffb0eb851586f88 (diff) | |
download | binaryen-b8cf38693103127913a12240cbbcabe8ff47c719.tar.gz binaryen-b8cf38693103127913a12240cbbcabe8ff47c719.tar.bz2 binaryen-b8cf38693103127913a12240cbbcabe8ff47c719.zip |
[Outlining] Fix outlining control flow
Changes the controlFlowQueue used in stringify-walker to push values of Expression*, This ensures that we walk the Wasm module in the same order, regardless of whether the control flow expression is outlined.
Reviewers: tlively
Reviewed By: tlively
Pull Request: https://github.com/WebAssembly/binaryen/pull/6139
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/outlining.wast | 186 |
1 files changed, 185 insertions, 1 deletions
diff --git a/test/lit/passes/outlining.wast b/test/lit/passes/outlining.wast index ad712b31a..98cb5a316 100644 --- a/test/lit/passes/outlining.wast +++ b/test/lit/passes/outlining.wast @@ -238,7 +238,59 @@ ) ) -;; Tests that outlining works correctly with If control flow +;; Tests that outlining works correctly with if-condition +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $1 (func (result i32))) + + ;; CHECK: (global $global$1 (mut i32) (i32.const 100)) + (global $global$1 (mut i32) (i32.const 100)) + ;; CHECK: (func $outline$ (type $1) (result i32) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (global.get $global$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + + ;; CHECK: (func $a (type $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $a + (if + (i32.eqz + (global.get $global$1) + ) + (global.set $global$1 + (i32.const 15) + ) + ) + ) + ;; CHECK: (func $b (type $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $b + (if + (i32.eqz + (global.get $global$1) + ) + (global.set $global$1 + (i32.const 20) + ) + ) + ) +) + +;; Outline if-true. (module ;; CHECK: (type $0 (func (param i32))) @@ -288,6 +340,138 @@ ) ) +;; Outline if-false. +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (global $global$1 (mut i32) (i32.const 100)) + (global $global$1 (mut i32) (i32.const 100)) + ;; CHECK: (func $outline$ (type $0) + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + + ;; CHECK: (func $a (type $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (global.get $global$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $a + (if + (i32.eqz + (global.get $global$1) + ) + (global.set $global$1 + (i32.const 15) + ) + (block + (global.set $global$1 + (i32.const 100) + ) + ) + ) + ) + ;; CHECK: (func $b (type $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.ctz + ;; CHECK-NEXT: (global.get $global$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $b + (if + (i32.ctz + (global.get $global$1) + ) + (global.set $global$1 + (i32.const 30) + ) + (block + (global.set $global$1 + (i32.const 100) + ) + ) + ) + ) +) + +;; Outline if control flow, with matching if-condition, if-true, if-false +;; TODO: Ideally outlining would keep the if-true and if-false inline in +;; $outline$, instead of moving them to another outlined function ($outline$_3 +;; & $outline$_4) because of the unique symbol between the if-condition and +;; if-true and the unique symbol between if-true and if-false. +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (global $global$1 (mut i32) (i32.const 100)) + (global $global$1 (mut i32) (i32.const 100)) + ;; CHECK: (func $outline$ (type $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (global.get $global$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $outline$_3) + ;; CHECK-NEXT: (call $outline$_4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + + ;; CHECK: (func $outline$_3 (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + + ;; CHECK: (func $outline$_4 (type $0) + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + + ;; CHECK: (func $a (type $0) + ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: ) + (func $a + (if + (i32.eqz + (global.get $global$1) + ) + (drop + (i32.const 10) + ) + (global.set $global$1 + (i32.const 20) + ) + ) + ) + ;; CHECK: (func $b (type $0) + ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: ) + (func $b + (if + (i32.eqz + (global.get $global$1) + ) + (drop + (i32.const 10) + ) + (global.set $global$1 + (i32.const 20) + ) + ) + ) +) + ;; Tests that local.get instructions are correctly filtered from being outlined. (module ;; CHECK: (type $0 (func (param i32))) |