Skip to content

Commit a8da896

Browse files
authored
fix ssaify bug where we failed to update the location of values as we moved them around, causing us to zero out the wrong thing in another place and ensuing hilarity (#1212)
1 parent f0d858b commit a8da896

File tree

4 files changed

+89
-6
lines changed

4 files changed

+89
-6
lines changed

src/ast/LocalGraph.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,26 @@
1717
#include <iterator>
1818

1919
#include <wasm-builder.h>
20+
#include <wasm-printing.h>
2021
#include <ast/find_all.h>
2122
#include <ast/local-graph.h>
2223

2324
namespace wasm {
2425

2526
LocalGraph::LocalGraph(Function* func, Module* module) {
2627
walkFunctionInModule(func, module);
28+
29+
#ifdef LOCAL_GRAPH_DEBUG
30+
std::cout << "LocalGraph::dump\n";
31+
for (auto& pair : getSetses) {
32+
auto* get = pair.first;
33+
auto& sets = pair.second;
34+
std::cout << "GET\n" << get << " is influenced by\n";
35+
for (auto* set : sets) {
36+
std::cout << set << '\n';
37+
}
38+
}
39+
#endif
2740
}
2841

2942
void LocalGraph::computeInfluences() {

src/passes/SSAify.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct SSAify : public Pass {
6060
LocalGraph graph(func, module);
6161
// create new local indexes, one for each set
6262
createNewIndexes(graph);
63-
// we now know the sets for each get
63+
// we now know the sets for each get, and can compute get indexes and handle phis
6464
computeGetsAndPhis(graph);
6565
// add prepends to function
6666
addPrepends();
@@ -75,7 +75,6 @@ struct SSAify : public Pass {
7575
}
7676
}
7777

78-
// After we traversed it all, we can compute gets and phis
7978
void computeGetsAndPhis(LocalGraph& graph) {
8079
for (auto& iter : graph.getSetses) {
8180
auto* get = iter.first;
@@ -84,8 +83,7 @@ struct SSAify : public Pass {
8483
continue; // unreachable, ignore
8584
}
8685
if (sets.size() == 1) {
87-
// TODO: add tests for this case
88-
// easy, just one set, use it's index
86+
// easy, just one set, use its index
8987
auto* set = *sets.begin();
9088
if (set) {
9189
get->index = set->index;
@@ -138,10 +136,18 @@ struct SSAify : public Pass {
138136
for (auto* set : sets) {
139137
if (set) {
140138
// a set exists, just add a tee of its value
141-
set->value = builder.makeTeeLocal(
139+
auto* value = set->value;
140+
auto* tee = builder.makeTeeLocal(
142141
new_,
143-
set->value
142+
value
144143
);
144+
set->value = tee;
145+
// the value may have been something we tracked the location
146+
// of. if so, update that, since we moved it into the tee
147+
if (graph.locations.count(value) > 0) {
148+
assert(graph.locations[value] == &set->value);
149+
graph.locations[value] = &tee->value;
150+
}
145151
} else {
146152
// this is a param or the zero init value.
147153
if (func->isParam(old)) {

test/passes/ssa.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
(module
22
(type $0 (func (param i32)))
33
(type $1 (func))
4+
(type $2 (func (result i32)))
5+
(global $global$0 (mut i32) (i32.const 1))
46
(memory $0 0)
57
(func $basics (type $0) (param $x i32)
68
(local $y i32)
@@ -691,4 +693,38 @@
691693
)
692694
)
693695
)
696+
(func $func_6 (type $2) (result i32)
697+
(local $result i32)
698+
(local $zero i32)
699+
(local $2 i32)
700+
(local $3 i32)
701+
(local $4 i32)
702+
(loop $label$1
703+
(if
704+
(i32.eqz
705+
(get_global $global$0)
706+
)
707+
(return
708+
(get_local $4)
709+
)
710+
)
711+
(set_global $global$0
712+
(i32.const 0)
713+
)
714+
(set_local $2
715+
(tee_local $4
716+
(i32.const 1)
717+
)
718+
)
719+
(br_if $label$1
720+
(i32.const 0)
721+
)
722+
(set_local $3
723+
(tee_local $4
724+
(i32.const 0)
725+
)
726+
)
727+
(br $label$1)
728+
)
729+
)
694730
)

test/passes/ssa.wast

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
(module
2+
(global $global$0 (mut i32) (i32.const 1))
23
(func $basics (param $x i32)
34
(local $y i32)
45
(local $z f32)
@@ -311,5 +312,32 @@
311312
)
312313
(drop (get_local $x)) ;; can receive from either set, or input param
313314
)
315+
(func $func_6 (result i32)
316+
(local $result i32)
317+
(local $zero i32)
318+
(loop $label$1
319+
(if
320+
(i32.eqz
321+
(get_global $global$0)
322+
)
323+
(return
324+
(get_local $result) ;; we eventually reach here
325+
)
326+
)
327+
(set_global $global$0
328+
(i32.const 0) ;; tell next iteration to return
329+
)
330+
(set_local $result
331+
(i32.const 1) ;; set the return value to 1, temporarily
332+
)
333+
(br_if $label$1
334+
(i32.const 0) ;; don't do anything here
335+
)
336+
(set_local $result
337+
(get_local $zero) ;; set it to zero instead
338+
)
339+
(br $label$1) ;; back to the top, where we will return the zero
340+
)
341+
)
314342
)
315343

0 commit comments

Comments
 (0)