blob: ef2cf62e06cf2f2d36e039a5d680eb8fb259e0d2 [file] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects | filecheck %s --check-prefix CHECK_0
;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects -O1 | filecheck %s --check-prefix CHECK_1
;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects -O3 | filecheck %s --check-prefix CHECK_3
;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects -Os | filecheck %s --check-prefix CHECK_s
;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects -O | filecheck %s --check-prefix CHECK_O
;; Test that global effects benefit -O1 and related modes.
(module
;; CHECK_0: (type $0 (func))
;; CHECK_0: (type $1 (func (param i32) (result i32)))
;; CHECK_0: (export "main" (func $main))
;; CHECK_1: (type $0 (func))
;; CHECK_1: (type $1 (func (param i32) (result i32)))
;; CHECK_1: (export "main" (func $main))
;; CHECK_3: (type $0 (func))
;; CHECK_3: (type $1 (func (param i32) (result i32)))
;; CHECK_3: (export "main" (func $main))
;; CHECK_s: (type $0 (func))
;; CHECK_s: (type $1 (func (param i32) (result i32)))
;; CHECK_s: (export "main" (func $main))
;; CHECK_O: (type $0 (func))
;; CHECK_O: (type $1 (func (param i32) (result i32)))
;; CHECK_O: (export "main" (func $main))
(export "main" (func $main))
;; CHECK_0: (export "main-infinite" (func $main-infinite))
;; CHECK_1: (export "main-infinite" (func $main-infinite))
;; CHECK_3: (export "main-infinite" (func $main-infinite))
;; CHECK_s: (export "main-infinite" (func $main-infinite))
;; CHECK_O: (export "main-infinite" (func $main-infinite))
(export "main-infinite" (func $main-infinite))
;; CHECK_0: (export "pointless-work" (func $pointless-work))
;; CHECK_1: (export "pointless-work" (func $pointless-work))
;; CHECK_3: (export "pointless-work" (func $pointless-work))
;; CHECK_s: (export "pointless-work" (func $pointless-work))
;; CHECK_O: (export "pointless-work" (func $pointless-work))
(export "pointless-work" (func $pointless-work))
;; CHECK_0: (func $main (type $0)
;; CHECK_0-NEXT: (if
;; CHECK_0-NEXT: (call $pointless-work
;; CHECK_0-NEXT: (i32.const 0)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: (then
;; CHECK_0-NEXT: (drop
;; CHECK_0-NEXT: (call $pointless-work
;; CHECK_0-NEXT: (i32.const 1)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_1: (func $main (type $0)
;; CHECK_1-NEXT: (nop)
;; CHECK_1-NEXT: )
;; CHECK_3: (func $main (type $0)
;; CHECK_3-NEXT: (nop)
;; CHECK_3-NEXT: )
;; CHECK_s: (func $main (type $0)
;; CHECK_s-NEXT: (nop)
;; CHECK_s-NEXT: )
;; CHECK_O: (func $main (type $0)
;; CHECK_O-NEXT: (nop)
;; CHECK_O-NEXT: )
(func $main
;; This calls a function that does pointless work. After generating global
;; effects we can see that it is pointless and remove this entire if (except
;; for -O0).
(if
(call $pointless-work
(i32.const 0)
)
(then
(drop
(call $pointless-work
(i32.const 1)
)
)
)
)
)
;; CHECK_0: (func $main-infinite (type $0)
;; CHECK_0-NEXT: (if
;; CHECK_0-NEXT: (call $infinite-work
;; CHECK_0-NEXT: (i32.const 0)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: (then
;; CHECK_0-NEXT: (drop
;; CHECK_0-NEXT: (call $infinite-work
;; CHECK_0-NEXT: (i32.const 1)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_1: (func $main-infinite (type $0)
;; CHECK_1-NEXT: (if
;; CHECK_1-NEXT: (call $infinite-work
;; CHECK_1-NEXT: (i32.const 0)
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: (then
;; CHECK_1-NEXT: (drop
;; CHECK_1-NEXT: (call $infinite-work
;; CHECK_1-NEXT: (i32.const 1)
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_3: (func $main-infinite (type $0)
;; CHECK_3-NEXT: (if
;; CHECK_3-NEXT: (call $infinite-work
;; CHECK_3-NEXT: (i32.const 0)
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: (then
;; CHECK_3-NEXT: (drop
;; CHECK_3-NEXT: (call $infinite-work
;; CHECK_3-NEXT: (i32.const 1)
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_s: (func $main-infinite (type $0)
;; CHECK_s-NEXT: (if
;; CHECK_s-NEXT: (call $infinite-work
;; CHECK_s-NEXT: (i32.const 0)
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: (then
;; CHECK_s-NEXT: (drop
;; CHECK_s-NEXT: (call $infinite-work
;; CHECK_s-NEXT: (i32.const 1)
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_O: (func $main-infinite (type $0)
;; CHECK_O-NEXT: (if
;; CHECK_O-NEXT: (call $infinite-work
;; CHECK_O-NEXT: (i32.const 0)
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: (then
;; CHECK_O-NEXT: (drop
;; CHECK_O-NEXT: (call $infinite-work
;; CHECK_O-NEXT: (i32.const 1)
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
(func $main-infinite
;; We cannot remove in this case as the pointless work may have an infinite
;; loop, which we do not eliminate.
(if
(call $infinite-work
(i32.const 0)
)
(then
(drop
(call $infinite-work
(i32.const 1)
)
)
)
)
)
;; CHECK_0: (func $pointless-work (type $1) (param $x i32) (result i32)
;; CHECK_0-NEXT: (local.set $x
;; CHECK_0-NEXT: (i32.add
;; CHECK_0-NEXT: (local.get $x)
;; CHECK_0-NEXT: (i32.const 1)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: (if
;; CHECK_0-NEXT: (i32.ge_u
;; CHECK_0-NEXT: (local.get $x)
;; CHECK_0-NEXT: (i32.const 12345678)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: (then
;; CHECK_0-NEXT: (local.set $x
;; CHECK_0-NEXT: (i32.add
;; CHECK_0-NEXT: (local.get $x)
;; CHECK_0-NEXT: (i32.const 1)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: (return
;; CHECK_0-NEXT: (local.get $x)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_1: (func $pointless-work (type $1) (param $0 i32) (result i32)
;; CHECK_1-NEXT: (if (result i32)
;; CHECK_1-NEXT: (i32.ge_u
;; CHECK_1-NEXT: (local.tee $0
;; CHECK_1-NEXT: (i32.add
;; CHECK_1-NEXT: (local.get $0)
;; CHECK_1-NEXT: (i32.const 1)
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: (i32.const 12345678)
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: (then
;; CHECK_1-NEXT: (i32.add
;; CHECK_1-NEXT: (local.get $0)
;; CHECK_1-NEXT: (i32.const 1)
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: (else
;; CHECK_1-NEXT: (local.get $0)
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_3: (func $pointless-work (type $1) (param $0 i32) (result i32)
;; CHECK_3-NEXT: (if (result i32)
;; CHECK_3-NEXT: (i32.ge_u
;; CHECK_3-NEXT: (local.tee $0
;; CHECK_3-NEXT: (i32.add
;; CHECK_3-NEXT: (local.get $0)
;; CHECK_3-NEXT: (i32.const 1)
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: (i32.const 12345678)
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: (then
;; CHECK_3-NEXT: (i32.add
;; CHECK_3-NEXT: (local.get $0)
;; CHECK_3-NEXT: (i32.const 1)
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: (else
;; CHECK_3-NEXT: (local.get $0)
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_s: (func $pointless-work (type $1) (param $0 i32) (result i32)
;; CHECK_s-NEXT: (if (result i32)
;; CHECK_s-NEXT: (i32.ge_u
;; CHECK_s-NEXT: (local.tee $0
;; CHECK_s-NEXT: (i32.add
;; CHECK_s-NEXT: (local.get $0)
;; CHECK_s-NEXT: (i32.const 1)
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: (i32.const 12345678)
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: (then
;; CHECK_s-NEXT: (i32.add
;; CHECK_s-NEXT: (local.get $0)
;; CHECK_s-NEXT: (i32.const 1)
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: (else
;; CHECK_s-NEXT: (local.get $0)
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_O: (func $pointless-work (type $1) (param $0 i32) (result i32)
;; CHECK_O-NEXT: (if (result i32)
;; CHECK_O-NEXT: (i32.ge_u
;; CHECK_O-NEXT: (local.tee $0
;; CHECK_O-NEXT: (i32.add
;; CHECK_O-NEXT: (local.get $0)
;; CHECK_O-NEXT: (i32.const 1)
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: (i32.const 12345678)
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: (then
;; CHECK_O-NEXT: (i32.add
;; CHECK_O-NEXT: (local.get $0)
;; CHECK_O-NEXT: (i32.const 1)
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: (else
;; CHECK_O-NEXT: (local.get $0)
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
(func $pointless-work (param $x i32) (result i32)
;; Some pointless work, with no side effects, that cannot be inlined. (The
;; changes here are not important for this test.)
(local.set $x
(i32.add
(local.get $x)
(i32.const 1)
)
)
(if
(i32.ge_u
(local.get $x)
(i32.const 12345678)
)
(then
(local.set $x
(i32.add
(local.get $x)
(i32.const 1)
)
)
)
)
(return
(local.get $x)
)
)
;; CHECK_0: (func $infinite-work (type $1) (param $x i32) (result i32)
;; CHECK_0-NEXT: (loop $loop
;; CHECK_0-NEXT: (local.set $x
;; CHECK_0-NEXT: (i32.add
;; CHECK_0-NEXT: (local.get $x)
;; CHECK_0-NEXT: (i32.const 1)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: (br_if $loop
;; CHECK_0-NEXT: (local.get $x)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: (return
;; CHECK_0-NEXT: (local.get $x)
;; CHECK_0-NEXT: )
;; CHECK_0-NEXT: )
;; CHECK_1: (func $infinite-work (type $1) (param $0 i32) (result i32)
;; CHECK_1-NEXT: (loop $loop
;; CHECK_1-NEXT: (br_if $loop
;; CHECK_1-NEXT: (local.tee $0
;; CHECK_1-NEXT: (i32.add
;; CHECK_1-NEXT: (local.get $0)
;; CHECK_1-NEXT: (i32.const 1)
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: )
;; CHECK_1-NEXT: (local.get $0)
;; CHECK_1-NEXT: )
;; CHECK_3: (func $infinite-work (type $1) (param $0 i32) (result i32)
;; CHECK_3-NEXT: (loop $loop
;; CHECK_3-NEXT: (br_if $loop
;; CHECK_3-NEXT: (local.tee $0
;; CHECK_3-NEXT: (i32.add
;; CHECK_3-NEXT: (local.get $0)
;; CHECK_3-NEXT: (i32.const 1)
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: )
;; CHECK_3-NEXT: (local.get $0)
;; CHECK_3-NEXT: )
;; CHECK_s: (func $infinite-work (type $1) (param $0 i32) (result i32)
;; CHECK_s-NEXT: (loop $loop
;; CHECK_s-NEXT: (br_if $loop
;; CHECK_s-NEXT: (local.tee $0
;; CHECK_s-NEXT: (i32.add
;; CHECK_s-NEXT: (local.get $0)
;; CHECK_s-NEXT: (i32.const 1)
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: )
;; CHECK_s-NEXT: (local.get $0)
;; CHECK_s-NEXT: )
;; CHECK_O: (func $infinite-work (type $1) (param $0 i32) (result i32)
;; CHECK_O-NEXT: (loop $loop
;; CHECK_O-NEXT: (br_if $loop
;; CHECK_O-NEXT: (local.tee $0
;; CHECK_O-NEXT: (i32.add
;; CHECK_O-NEXT: (local.get $0)
;; CHECK_O-NEXT: (i32.const 1)
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: )
;; CHECK_O-NEXT: (local.get $0)
;; CHECK_O-NEXT: )
(func $infinite-work (param $x i32) (result i32)
;; Some work with no side effects aside from that it appears to potentially
;; do infinite work, due to a loop. (The changes here are not important for
;; this test.)
(loop $loop
(local.set $x
(i32.add
(local.get $x)
(i32.const 1)
)
)
(br_if $loop
(local.get $x)
)
)
(return
(local.get $x)
)
)
)