Simd: Load and extend natural alignment

Created on 15 May 2020  路  14Comments  路  Source: WebAssembly/simd

LLVM currently emits load and extend instructions with alignment parameters up to 3 (i.e. 8-byte aligned), but V8 is throwing errors saying the expected maximum alignment for i16x8.load8x8_s is 0 (i.e. 1-byte alignment). The overview document does not specify either the natural alignment or the maximum, so we should figure out what they should be.

IMO it makes sense for 8-byte alignment to be the natural alignment because these instructions are loading 8 bytes at a time.

Most helpful comment

IIRC, no existing WebAssembly instruction allows overalignment either, so the natural alignment is always the maximum allowed alignment. So if we want to allow 8-byte alignment, it would be most consistent with the rest of WebAssembly to make the natural alignment 8 bytes as well.

All 14 comments

This is a bug in v8, I have a patch at https://chromium-review.googlesource.com/c/v8/v8/+/2202721 which I can hopefully get merged soon.

IMO the alignment of load-extend should match the alignment of the elements being loaded (i.e. 1 for i16x8.load8x8_s).

Hm, I'm not sure what the right semantics here should be:

  • one one hand, we are really loading 8 bytes, so the alignment should be 3 (2^3 = 8 byte)
  • but, these 8 bytes could be 8 1-byte (in an array), so the alignment should be 0 (2^0 = 1 byte)

I looked a bit at Intels arch manual 12.10.8 Packed Integer Format Conversions (in the section about SSE4.1 instruction set):
"When accessing memory, no alignment is required for any of the instructions unless alignment checking is enabled. In which case, all conversions must be aligned to the width of the memory reference. "
And in our cases, the memory reference is always 64-bit since we are loading 8-bytes.
I'm not sure how this information will affect our choice here, just putting it down as reference.

IIRC, no existing WebAssembly instruction allows overalignment either, so the natural alignment is always the maximum allowed alignment. So if we want to allow 8-byte alignment, it would be most consistent with the rest of WebAssembly to make the natural alignment 8 bytes as well.

WebAssembly does 16-byte alignment for 16-byte loads because they are untyped. Intrinsics with typed loads (e.g. ARMv7 NEON) set alignment according to the natural alignment of the loaded type (i.e. vld1q_f32 would set alignment to 4 bytes, not 16). Load-extend intrinsics in WebAssembly are typed, so would be best if they don't break expectations set by platform-specific intrinsics, and set alignment likewise based on element type.

For these instructions the type of the loaded value is an 8-byte vector, though. At least in LLVM, the natural alignment of any 8-byte vector is 8 bytes. I see what you mean about ld1q_f32, although I can't find a documented assumed alignment for that function. I would personally prefer consistency with the rest of WebAssembly over consistency with native platforms since the alignment hint will not be useful for these instructions anyway.

Currently i'm encountering a load+extend instruction in emscripten-compiled code that uses alignLog2=4 and SpiderMonkey does not like that, since the byte size of the item in memory is 8.

@lars-t-hansen huh, do you have the source code that came from or is it in the wild? It sounds like I probably missed a small piece of logic in LLVM for fixing overalignment.

@lars-t-hansen I double checked and LLVM's behavior is correct here, so I'm not sure where an alignLog2=4 would come from.

Yeah, it's mysterious. As I mentioned in the emscripten channel on discord, emcc seems to produce basically garbage when confronted with simd code. That is, the output from -S is sensible but the .wasm is full of bugs - even wasm-objdump is stymied. It's possible the problem is local of course but this is straight up emcc -O1 -msimd128 -o test.wasm test.c with trivial C code. My emscripten is at latest or latest-upstream, but that didn't seem to matter. I can provide more details next week, I'd like to get to the bottom of it.

Are you perhaps using emcc from after the recent opcode renumbering but wasm-objdump from before the renumbering?

I don't think so, I updated and recompiled wabt on Friday (and updated emscripten too, I believe). Will provide version numbers when I'm back on that system...

My problems were probably the result of a rotten emscripten install; better now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

penzn picture penzn  路  9Comments

dtig picture dtig  路  8Comments

tlively picture tlively  路  6Comments

tlively picture tlively  路  8Comments

tlively picture tlively  路  10Comments