summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-10-25 16:48:30 -0700
committerGitHub <noreply@github.com>2022-10-25 16:48:30 -0700
commit2741c003422fffbf276a521a773521c951c03221 (patch)
tree75e045722de6fd3678236a09b73a573fd0f70ffc /test
parent79e032ac1124f82729bb21684f370044612c7124 (diff)
downloadbinaryen-2741c003422fffbf276a521a773521c951c03221.tar.gz
binaryen-2741c003422fffbf276a521a773521c951c03221.tar.bz2
binaryen-2741c003422fffbf276a521a773521c951c03221.zip
Move removable code in CodePushing (#5187)
This is safe since we "partially remove" it: we don't move it to a place it might execute more, but make it possibly execute less. See the new comment for more details. Motivated by wasm GC but this can help wasm MVP as well. In both cases loads from memory can trap, which limits what the VM can do to optimize them past conditions, but in trapsNeverHappens we can do that at the toolchain level: x = read(); if () { .. } use(x); => if () { .. } x = read(); // moved to here, and might not execute if the if did a break/return use(x);
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/code-pushing_tnh.wast48
1 files changed, 48 insertions, 0 deletions
diff --git a/test/lit/passes/code-pushing_tnh.wast b/test/lit/passes/code-pushing_tnh.wast
new file mode 100644
index 000000000..9993c686b
--- /dev/null
+++ b/test/lit/passes/code-pushing_tnh.wast
@@ -0,0 +1,48 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up.
+
+;; RUN: foreach %s %t wasm-opt --code-pushing -tnh -S -o - | filecheck %s
+
+(module
+ ;; CHECK: (type $i32_i32_=>_none (func (param i32 i32)))
+
+ ;; CHECK: (func $div (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (local $temp i32)
+ ;; CHECK-NEXT: (block $block
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: (return)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $temp
+ ;; CHECK-NEXT: (i32.div_u
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $temp)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $div (param $x i32) (param $y i32)
+ (local $temp i32)
+ (block $block
+ ;; This division might trap (if x is 0). But with tnh we can assume that
+ ;; won't happen, and push it past the condition.
+ (local.set $temp
+ (i32.div_u
+ (i32.const 1)
+ (local.get $x)
+ )
+ )
+ (if
+ (local.get $y)
+ (return)
+ )
+ (drop
+ (local.get $temp)
+ )
+ )
+ )
+)
+