summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeAddedConstants.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/OptimizeAddedConstants.cpp')
-rw-r--r--src/passes/OptimizeAddedConstants.cpp33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp
index 8256169c1..f48989d5b 100644
--- a/src/passes/OptimizeAddedConstants.cpp
+++ b/src/passes/OptimizeAddedConstants.cpp
@@ -45,7 +45,9 @@ public:
T* curr,
Module* module,
LocalGraph* localGraph)
- : parent(parent), curr(curr), module(module), localGraph(localGraph) {}
+ : parent(parent), curr(curr), module(module), localGraph(localGraph) {
+ memory64 = module->getMemory(curr->memory)->is64();
+ }
// Tries to optimize, and returns whether we propagated a change.
bool optimize() {
@@ -56,7 +58,7 @@ public:
return false;
}
if (auto* add = curr->ptr->template dynCast<Binary>()) {
- if (add->op == AddInt32) {
+ if (add->op == AddInt32 || add->op == AddInt64) {
// Look for a constant on both sides.
if (tryToOptimizeConstant(add->right, add->left) ||
tryToOptimizeConstant(add->left, add->right)) {
@@ -110,6 +112,7 @@ private:
T* curr;
Module* module;
LocalGraph* localGraph;
+ bool memory64;
void optimizeConstantPointer() {
// The constant and an offset are interchangeable:
@@ -123,11 +126,23 @@ private:
// code may know that is valid, even if we can't. Only handle the
// obviously valid case where an overflow can't occur.
auto* c = curr->ptr->template cast<Const>();
- uint32_t base = c->value.geti32();
- uint32_t offset = curr->offset;
- if (uint64_t(base) + uint64_t(offset) < (uint64_t(1) << 32)) {
- c->value = c->value.add(Literal(uint32_t(curr->offset)));
- curr->offset = 0;
+ if (memory64) {
+ uint64_t base = c->value.geti64();
+ uint64_t offset = curr->offset;
+
+ uint64_t max = std::numeric_limits<uint64_t>::max();
+ bool overflow = (base > max - offset);
+ if (!overflow) {
+ c->value = c->value.add(Literal(offset));
+ curr->offset = 0;
+ }
+ } else {
+ uint32_t base = c->value.geti32();
+ uint32_t offset = curr->offset;
+ if (uint64_t(base) + uint64_t(offset) < (uint64_t(1) << 32)) {
+ c->value = c->value.add(Literal(uint32_t(curr->offset)));
+ curr->offset = 0;
+ }
}
}
}
@@ -222,9 +237,9 @@ private:
// Sees if we can optimize a particular constant.
Result canOptimizeConstant(Literal literal) {
- auto value = literal.geti32();
+ uint64_t value = literal.getInteger();
// Avoid uninteresting corner cases with peculiar offsets.
- if (value >= 0 && value < PassOptions::LowMemoryBound) {
+ if (value < PassOptions::LowMemoryBound) {
// The total offset must not allow reaching reasonable memory
// by overflowing.
auto total = curr->offset + value;