diff options
Diffstat (limited to 'src/passes/OptimizeAddedConstants.cpp')
-rw-r--r-- | src/passes/OptimizeAddedConstants.cpp | 33 |
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; |