summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2019-05-17 19:12:01 -0700
committerGitHub <noreply@github.com>2019-05-17 19:12:01 -0700
commit677808afb18a059d3dadcf2be7bd8daade5b77f9 (patch)
treea047c7c6070c47924587ad7c23aa6d53da23168d /src
parentd6a6188493031c5f6bbe2ca49860c9d9df962752 (diff)
downloadbinaryen-677808afb18a059d3dadcf2be7bd8daade5b77f9.tar.gz
binaryen-677808afb18a059d3dadcf2be7bd8daade5b77f9.tar.bz2
binaryen-677808afb18a059d3dadcf2be7bd8daade5b77f9.zip
Fix AvoidReinterprets on reinterpreted loads of fewer than the full size (#2123)
* fix * fix style
Diffstat (limited to 'src')
-rw-r--r--src/passes/AvoidReinterprets.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/passes/AvoidReinterprets.cpp b/src/passes/AvoidReinterprets.cpp
index 823de53ba..d9b93b188 100644
--- a/src/passes/AvoidReinterprets.cpp
+++ b/src/passes/AvoidReinterprets.cpp
@@ -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);
@@ -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 =
@@ -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);