blob: a9161a853c8490fd393428251902bdc549aca1bc (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
;; RUN: wasm-opt %s --simplify-locals --rse -S -o - \
;; RUN: | filecheck %s
(module
;; CHECK: (func $no (param $x i32) (result i32)
;; CHECK-NEXT: (i32.add
;; CHECK-NEXT: (block $block (result i32)
;; CHECK-NEXT: (local.tee $x
;; CHECK-NEXT: (br_if $block
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (local.tee $x
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $no (param $x i32) (result i32)
(i32.add
(block $block (result i32)
;; This local.tee is necessary. It might seem that the br_if flows out
;; $x, so we don't need to write that same value to $x once more.
;; SimplifyLocals and RedundantSetElimination try to find such sets and
;; remove them. But this set is necessary, since a tee of $x executes
;; after that local.get. That is, the br_if flows out the *old* value of
;; $x. What happens in practice is that we branch (since the condition
;; is 42), and flow out the old $x, which gets tee'd into $x once more.
;; As a result, the block flows out the original value of $x, and the
;; local.get reads that same value, so the final add returns 2 times the
;; original value of $x. For all that to happen, we need those
;; optimization passes to *not* remove the outer local.tee.
(local.tee $x
(br_if $block
(local.get $x)
(local.tee $x
(i32.const 42)
)
)
)
)
(local.get $x)
)
)
)
|