WebAssembly / simd

Branch of the spec repo scoped to discussion of SIMD in WebAssembly
Other
531 stars 43 forks source link

Extended multiply horizontal add instruction #382

Open omnisip opened 3 years ago

omnisip commented 3 years ago

Introduction

This proposal introduces an extended horizontal multiply and add instruction that is used extensively in colorspace conversion and in the implementation of encoders and decoder for video processing. It mirrors the proposal @Maratyszcza put forth in #127 by adding an additional instruction for u8 -> i16 conversion. It maps to 3 instructions on ARM64, and 4 on ARMv7-a+neon. It's extremely similar to pmaddusbw that is supported on the Intel chipset, except that it's not signed by unsigned multiplication. This provides unsigned by unsigned multiplication.

Applications

Mapping to Common Instruction Sets

This section illustrates how the new WebAssembly instructions can be lowered on common instruction sets. However, these patterns are provided only for convenience, compliant WebAssembly implementations do not have to follow the same code generation patterns.

x86/x86-64 processors with AVX instruction set

Maratyszcza commented 3 years ago

SSSE3 lowering mismatch others. PMADDUBSW does unsigned by signed multiplication.

omnisip commented 3 years ago

SSSE3 lowering mismatch others. PMADDUBSW does unsigned by signed multiplication.

You're totally right. Nice catch.

omnisip commented 3 years ago

@Maratyszcza I think that fixes it... I was stunned when I did the testing about how challenging pmaddusbw was to work with. It treats each operand differently such that unless both operands are guaranteed to be 127 or less, the ordering matters and the results will differ.

Maratyszcza commented 3 years ago

By analogy with #127, this instruction should be named i16x8.dot_i8x16_u

omnisip commented 3 years ago

By analogy with #127, this instruction should be named i16x8.dot_i8x16_u

Haven't forgotten about this. Will take care of it today.

omnisip commented 3 years ago

This proposal is efficient on ARM64, but isn't efficient on x64. The original objective was to see if pmaddubsw could be implemented portably since it would have provided an option to do the RGBA conversions on x64 chips in 1-2 ops. Unfortunately, the behavior of pmaddubsw isn't portable, and the workarounds required to get it to work efficiently, are less efficient than expanding the integer types, multiplying, and adding. As a side effect, I'd like to withdraw this proposal in favor of integer sign/zero extension proposal. If someone else has a need for this proposal before standardization, please write back here. For documentation on the issues with pmaddubsw, please see this thread on stackoverflow