Skip to content

Commit 183d4b0

Browse files
authored
OptimizeInstructions: Simplify tuple.extract of tuple.make (#5938)
E.g. (tuple.extract 1 (tuple.make (A) (B) (C)) => (B) Modify some existing tests to not be in this trivial form, so that they do not stop testing what they should.
1 parent 2cbe448 commit 183d4b0

File tree

2 files changed

+90
-32
lines changed

2 files changed

+90
-32
lines changed

src/passes/OptimizeInstructions.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,25 @@ struct OptimizeInstructions
22662266
}
22672267
}
22682268

2269+
void visitTupleExtract(TupleExtract* curr) {
2270+
if (curr->type == Type::unreachable) {
2271+
return;
2272+
}
2273+
2274+
if (auto* make = curr->tuple->dynCast<TupleMake>()) {
2275+
Builder builder(*getModule());
2276+
2277+
// Store the value of the lane we want in a tee, and return that after a
2278+
// drop of the tuple (which might have side effects).
2279+
auto valueType = make->type[curr->index];
2280+
Index tempLocal = builder.addVar(getFunction(), valueType);
2281+
make->operands[curr->index] =
2282+
builder.makeLocalTee(tempLocal, make->operands[curr->index], valueType);
2283+
auto* get = builder.makeLocalGet(tempLocal, valueType);
2284+
replaceCurrent(getDroppedChildrenAndAppend(make, get));
2285+
}
2286+
}
2287+
22692288
Index getMaxBitsForLocal(LocalGet* get) {
22702289
// check what we know about the local
22712290
return localInfo[get->index].maxBits;

test/lit/passes/optimize-instructions-multivalue.wast

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,72 +3,111 @@
33

44
(module
55
;; CHECK: (func $if-identical-arms-tuple (param $x i32) (result i32)
6+
;; CHECK-NEXT: (local $tuple (i32 i32))
7+
;; CHECK-NEXT: (local $tuple2 (i32 i32))
68
;; CHECK-NEXT: (tuple.extract 0
79
;; CHECK-NEXT: (if (result i32 i32)
810
;; CHECK-NEXT: (local.get $x)
9-
;; CHECK-NEXT: (tuple.make
10-
;; CHECK-NEXT: (i32.const 0)
11-
;; CHECK-NEXT: (i32.const 1)
12-
;; CHECK-NEXT: )
13-
;; CHECK-NEXT: (tuple.make
14-
;; CHECK-NEXT: (i32.const 2)
15-
;; CHECK-NEXT: (i32.const 3)
16-
;; CHECK-NEXT: )
11+
;; CHECK-NEXT: (local.get $tuple)
12+
;; CHECK-NEXT: (local.get $tuple2)
1713
;; CHECK-NEXT: )
1814
;; CHECK-NEXT: )
1915
;; CHECK-NEXT: )
2016
(func $if-identical-arms-tuple (param $x i32) (result i32)
17+
(local $tuple (i32 i32))
18+
(local $tuple2 (i32 i32))
2119
(if (result i32)
2220
(local.get $x)
2321
;; The tuple.extract can be hoisted out.
2422
(tuple.extract 0
25-
(tuple.make
26-
(i32.const 0)
27-
(i32.const 1)
28-
)
23+
(local.get $tuple)
2924
)
3025
(tuple.extract 0
31-
(tuple.make
32-
(i32.const 2)
33-
(i32.const 3)
34-
)
26+
(local.get $tuple2)
3527
)
3628
)
3729
)
3830
;; CHECK: (func $select-identical-arms-tuple (param $x i32) (result i32)
31+
;; CHECK-NEXT: (local $tuple (i32 i32))
32+
;; CHECK-NEXT: (local $tuple2 (i32 i32))
3933
;; CHECK-NEXT: (select
4034
;; CHECK-NEXT: (tuple.extract 0
41-
;; CHECK-NEXT: (tuple.make
42-
;; CHECK-NEXT: (i32.const 0)
43-
;; CHECK-NEXT: (i32.const 1)
44-
;; CHECK-NEXT: )
35+
;; CHECK-NEXT: (local.get $tuple)
4536
;; CHECK-NEXT: )
4637
;; CHECK-NEXT: (tuple.extract 0
47-
;; CHECK-NEXT: (tuple.make
48-
;; CHECK-NEXT: (i32.const 2)
49-
;; CHECK-NEXT: (i32.const 3)
50-
;; CHECK-NEXT: )
38+
;; CHECK-NEXT: (local.get $tuple2)
5139
;; CHECK-NEXT: )
5240
;; CHECK-NEXT: (local.get $x)
5341
;; CHECK-NEXT: )
5442
;; CHECK-NEXT: )
5543
(func $select-identical-arms-tuple (param $x i32) (result i32)
44+
(local $tuple (i32 i32))
45+
(local $tuple2 (i32 i32))
5646
(select
5747
;; The tuple.extract cannot be hoisted out, as the spec disallows a
5848
;; select with multiple values in its arms.
5949
(tuple.extract 0
60-
(tuple.make
61-
(i32.const 0)
62-
(i32.const 1)
63-
)
50+
(local.get $tuple)
6451
)
6552
(tuple.extract 0
66-
(tuple.make
67-
(i32.const 2)
68-
(i32.const 3)
69-
)
53+
(local.get $tuple2)
7054
)
7155
(local.get $x)
7256
)
7357
)
58+
59+
;; CHECK: (func $extract-make (param $x i32) (param $y i32) (result i32)
60+
;; CHECK-NEXT: (local $2 i32)
61+
;; CHECK-NEXT: (drop
62+
;; CHECK-NEXT: (local.tee $2
63+
;; CHECK-NEXT: (local.get $x)
64+
;; CHECK-NEXT: )
65+
;; CHECK-NEXT: )
66+
;; CHECK-NEXT: (local.get $2)
67+
;; CHECK-NEXT: )
68+
(func $extract-make (param $x i32) (param $y i32) (result i32)
69+
;; An extraction from a make can be simplified to just get the right lane.
70+
(tuple.extract 0
71+
(tuple.make
72+
(local.get $x)
73+
(local.get $y)
74+
)
75+
)
76+
)
77+
78+
;; CHECK: (func $extract-make-2 (param $x i32) (param $y i32) (result i32)
79+
;; CHECK-NEXT: (local $2 i32)
80+
;; CHECK-NEXT: (drop
81+
;; CHECK-NEXT: (local.tee $2
82+
;; CHECK-NEXT: (local.get $y)
83+
;; CHECK-NEXT: )
84+
;; CHECK-NEXT: )
85+
;; CHECK-NEXT: (local.get $2)
86+
;; CHECK-NEXT: )
87+
(func $extract-make-2 (param $x i32) (param $y i32) (result i32)
88+
;; As above, but the second lane.
89+
(tuple.extract 1
90+
(tuple.make
91+
(local.get $x)
92+
(local.get $y)
93+
)
94+
)
95+
)
96+
97+
;; CHECK: (func $extract-make-unreachable (param $x i32) (param $y i32) (result i32)
98+
;; CHECK-NEXT: (tuple.extract 0
99+
;; CHECK-NEXT: (tuple.make
100+
;; CHECK-NEXT: (unreachable)
101+
;; CHECK-NEXT: (local.get $y)
102+
;; CHECK-NEXT: )
103+
;; CHECK-NEXT: )
104+
;; CHECK-NEXT: )
105+
(func $extract-make-unreachable (param $x i32) (param $y i32) (result i32)
106+
(tuple.extract 0
107+
(tuple.make
108+
(unreachable) ;; because of this we should do nothing
109+
(local.get $y)
110+
)
111+
)
112+
)
74113
)

0 commit comments

Comments
 (0)