Skip to content

Commit

Permalink
Fix AvoidReinterprets on reinterpreted loads of fewer than the full s…
Browse files Browse the repository at this point in the history
…ize (#2123)

* fix

* fix style
  • Loading branch information
kripken authored May 18, 2019
1 parent d6a6188 commit 677808a
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/passes/AvoidReinterprets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@

namespace wasm {

static bool canReplaceWithReinterpret(Load* load) {
// We can replace a full-size load with a valid pointer with
// a reinterpret of the same address. A partial load would see
// more bytes and possibly invalid data, and an unreachable
// pointer is just not interesting to handle.
return load->type != unreachable && load->bytes == getTypeSize(load->type);
}

static Load* getSingleLoad(LocalGraph* localGraph, GetLocal* get) {
std::set<GetLocal*> seen;
seen.insert(get);
Expand Down Expand Up @@ -104,7 +112,7 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> {
for (auto& pair : infos) {
auto* load = pair.first;
auto& info = pair.second;
if (info.reinterpreted && load->type != unreachable) {
if (info.reinterpreted && canReplaceWithReinterpret(load)) {
// We should use another load here, to avoid reinterprets.
info.ptrLocal = Builder::addVar(func, i32);
info.reinterpretedLocal =
Expand All @@ -131,8 +139,10 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> {
if (isReinterpret(curr)) {
auto* value = Properties::getFallthrough(curr->value);
if (auto* load = value->dynCast<Load>()) {
// A reinterpret of a load - flip it right here.
replaceCurrent(makeReinterpretedLoad(load, load->ptr));
// A reinterpret of a load - flip it right here if we can.
if (canReplaceWithReinterpret(load)) {
replaceCurrent(makeReinterpretedLoad(load, load->ptr));
}
} else if (auto* get = value->dynCast<GetLocal>()) {
if (auto* load = getSingleLoad(localGraph, get)) {
auto iter = infos.find(load);
Expand Down
15 changes: 15 additions & 0 deletions test/passes/avoid-reinterprets.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
(module
(type $0 (func))
(type $1 (func (result f32)))
(memory $0 1)
(func $simple (; 0 ;) (type $0)
(drop
Expand Down Expand Up @@ -148,4 +149,18 @@
(local.get $3)
)
)
(func $partial1 (; 6 ;) (type $1) (result f32)
(f32.reinterpret_i32
(i32.load16_u
(i32.const 3)
)
)
)
(func $partial2 (; 7 ;) (type $1) (result f32)
(f32.reinterpret_i32
(i32.load8_u
(i32.const 3)
)
)
)
)
14 changes: 14 additions & 0 deletions test/passes/avoid-reinterprets.wast
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,18 @@
(local.set $y (local.get $x))
(drop (f32.reinterpret_i32 (local.get $y)))
)
(func $partial1 (result f32)
(f32.reinterpret_i32
(i32.load16_u
(i32.const 3)
)
)
)
(func $partial2 (result f32)
(f32.reinterpret_i32
(i32.load8_u
(i32.const 3)
)
)
)
)

0 comments on commit 677808a

Please sign in to comment.