Commit b3ee0acd authored by Ben L. Titzer's avatar Ben L. Titzer Committed by Commit Bot

[wasm] Omit alignment check for static index

If the input memory index into an atomic operation is a constant, we can
statically check if the {index+offset} is aligned.

R=herhut@chromium.org

Change-Id: Ia830d7c7df10d50ed4ee3382acfef776306f249c
Reviewed-on: https://chromium-review.googlesource.com/c/1362872
Commit-Queue: Ben Titzer <titzer@chromium.org>
Reviewed-by: 's avatarStephan Herhut <herhut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58043}
parent 49c4c3e6
......@@ -3150,19 +3150,33 @@ Node* WasmGraphBuilder::SetGlobal(uint32_t index, Node* val) {
Node* WasmGraphBuilder::CheckBoundsAndAlignment(
uint8_t access_size, Node* index, uint32_t offset,
wasm::WasmCodePosition position) {
// Atomic operations access the memory, need to be bound checked till
// TrapHandlers are enabled on atomic operations
// Atomic operations need bounds checks until the backend can emit protected
// loads.
index =
BoundsCheckMem(access_size, index, offset, position, kNeedsBoundsCheck);
Node* effective_address =
graph()->NewNode(mcgraph()->machine()->IntAdd(), MemBuffer(offset),
Uint32ToUintptr(index));
// Unlike regular memory accesses, unaligned memory accesses for atomic
// operations should trap
// Access sizes are in powers of two, calculate mod without using division
Node* cond =
graph()->NewNode(mcgraph()->machine()->WordAnd(), effective_address,
IntPtrConstant(access_size - 1));
const uintptr_t align_mask = access_size - 1;
// Don't emit an alignment check if the index is a constant.
// TODO(wasm): a constant match is also done above in {BoundsCheckMem}.
UintPtrMatcher match(index);
if (match.HasValue()) {
uintptr_t effective_offset = match.Value() + offset;
if ((effective_offset & align_mask) != 0) {
// statically known to be unaligned; trap.
TrapIfEq32(wasm::kTrapUnalignedAccess, Int32Constant(0), 0, position);
}
return index;
}
// Unlike regular memory accesses, atomic memory accesses should trap if
// the effective offset is misaligned.
// TODO(wasm): this addition is redundant with one inserted by {MemBuffer}.
Node* effective_offset = graph()->NewNode(mcgraph()->machine()->IntAdd(),
MemBuffer(offset), index);
Node* cond = graph()->NewNode(mcgraph()->machine()->WordAnd(),
effective_offset, IntPtrConstant(align_mask));
TrapIfFalse(wasm::kTrapUnalignedAccess,
graph()->NewNode(mcgraph()->machine()->Word32Equal(), cond,
mcgraph()->Int32Constant(0)),
......@@ -3170,6 +3184,9 @@ Node* WasmGraphBuilder::CheckBoundsAndAlignment(
return index;
}
// Insert code to bounds check a memory access if necessary. Return the
// bounds-checked index, which is guaranteed to have (the equivalent of)
// {uintptr_t} representation.
Node* WasmGraphBuilder::BoundsCheckMem(uint8_t access_size, Node* index,
uint32_t offset,
wasm::WasmCodePosition position,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment