Skip to content

Commit

Permalink
Memory64Lowering: Handle -1 return value from memory.grow (#6733)
Browse files Browse the repository at this point in the history
This edge case make the lowering a little more tricky.
  • Loading branch information
sbc100 committed Jul 11, 2024
1 parent 363edc7 commit 22c28bd
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
27 changes: 25 additions & 2 deletions src/passes/Memory64Lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,32 @@ struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {
if (memory->is64()) {
wrapAddress64(curr->delta, curr->memory);
auto* size = static_cast<Expression*>(curr);
extendAddress64(size, curr->memory);
// MemoryGrow returns -1 in case of failure. We cannot just use
// extend_32_u in this case so we handle it as follows:
//
// (if (result i64)
// (i32.eq (i32.const -1) (local.tee $tmp (memory.grow X)))
// (then
// (i64.const -1)
// )
// (else
// (i32.extend_32_u (local.get $tmp))
// )
// )
Builder builder(module);
auto tmp = builder.addVar(getFunction(), Type::i32);
Expression* isMinusOne =
builder.makeBinary(EqInt32,
builder.makeConst(int32_t(-1)),
builder.makeLocalTee(tmp, size, Type::i32));
auto* newSize = builder.makeLocalGet(tmp, Type::i32);
builder.makeUnary(UnaryOp::ExtendUInt32, newSize);
Expression* ifExp =
builder.makeIf(isMinusOne,
builder.makeConst(int64_t(-1)),
builder.makeUnary(UnaryOp::ExtendUInt32, newSize));
curr->type = Type::i32;
replaceCurrent(size);
replaceCurrent(ifExp);
}
}

Expand Down
22 changes: 18 additions & 4 deletions test/lit/passes/memory64-lowering.wast
Original file line number Diff line number Diff line change
Expand Up @@ -225,16 +225,30 @@

;; CHECK: (func $other
;; CHECK-NEXT: (local $0 i64)
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (i64.extend_i32_u
;; CHECK-NEXT: (memory.size)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (i64.extend_i32_u
;; CHECK-NEXT: (memory.grow
;; CHECK-NEXT: (i32.wrap_i64
;; CHECK-NEXT: (i64.const 1)
;; CHECK-NEXT: (if (result i64)
;; CHECK-NEXT: (i32.eq
;; CHECK-NEXT: (i32.const -1)
;; CHECK-NEXT: (local.tee $1
;; CHECK-NEXT: (memory.grow
;; CHECK-NEXT: (i32.wrap_i64
;; CHECK-NEXT: (i64.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (i64.const -1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (else
;; CHECK-NEXT: (i64.extend_i32_u
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
Expand Down

0 comments on commit 22c28bd

Please sign in to comment.