summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai (kripken) <alonzakai@gmail.com>2017-07-28 12:45:19 -0700
committerAlon Zakai (kripken) <alonzakai@gmail.com>2017-07-29 19:18:49 -0700
commit1d67ab02aeb71b1a250a44161c8fdb3e97b04210 (patch)
treeedb0005c065050a6d7aed6aa0aa137b64a4c2035 /src
parent4d46a7e2c37299d5a9b9d9d6323ce9fca3a1cf3a (diff)
downloadbinaryen-1d67ab02aeb71b1a250a44161c8fdb3e97b04210.tar.gz
binaryen-1d67ab02aeb71b1a250a44161c8fdb3e97b04210.tar.bz2
binaryen-1d67ab02aeb71b1a250a44161c8fdb3e97b04210.zip
do not combine a load/store offset with a constant pointer if it would wrap a negative value to a positive one, as trapping is tricky
Diffstat (limited to 'src')
-rw-r--r--src/passes/OptimizeInstructions.cpp11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index de6f96ccc..2930fe9c9 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -908,8 +908,15 @@ private:
// it's better to do the opposite for gzip purposes as well as for readability.
auto* last = ptr->dynCast<Const>();
if (last) {
- last->value = Literal(int32_t(last->value.geti32() + offset));
- offset = 0;
+ // don't do this if it would wrap the pointer
+ uint64_t value64 = last->value.geti32();
+ uint64_t offset64 = offset;
+ if (value64 <= std::numeric_limits<int32_t>::max() &&
+ offset64 <= std::numeric_limits<int32_t>::max() &&
+ value64 + offset64 <= std::numeric_limits<int32_t>::max()) {
+ last->value = Literal(int32_t(value64 + offset64));
+ offset = 0;
+ }
}
}