emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.67k stars 3.29k forks source link

Is it possible to compile a SIMD codebase for a baseline wasm runtime? #22470

Closed tangobravo closed 1 month ago

tangobravo commented 1 month ago

The havoc physics engine in Babylon.js uses wasm SIMD for performance. Their codebase (which is unfortunately not open-source) requires SIMD, see https://forum.babylonjs.com/t/havok-cannot-be-loaded-in-any-safari-browser/41481/17.

Unfortunately this means it doesn't run on iOS before 16.4, which still impacts a fair number of people.

I was wondering if there's any built-in emscripten / LLVM mechanisms to compile SIMD code but to lower it to "standard" wasm? Or some headers that implement one of the set of wasm intrinsics without requiring wasm simd? I was thinking something like that might have been used during the wasm-simd specification and testing process...

I don't have any access to the Havoc source code, I just want to use it in projects. However if there was an easy way (compile flags or a header-based emulation) for them to provide a baseline wasm build then I'd hope they would consider it.

Thanks!

kripken commented 1 month ago

cc @tlively @juj

I know there are portability-related projects like https://github.com/simd-everywhere/simde but I'm not sure if they can actually polyfill SIMD into non-SIMD.

tlively commented 1 month ago

I don't know of any tool or header for lowering away SIMD right now, unfortunately.

juj commented 1 month ago

We could think about implementing the whole SSEx or NEONx or Wasm Simd intrinsic functions as scalar emulated implementations in Emscripten (as a xmmintrin.h et al. header replacements - I think actually simde already does this), however ..

I don't have any access to the Havoc source code

.. if you have an extra restriction that it is not possible to recompile the code from source, then an Emscripten header based solution would not work, but it would have to be a project that is undertaken in LLVM itself.

The big difficulty with lowering in LLVM land, to my understanding is that it is a very late stage to do such lowering, as code is already compiled to wasm object files. Therefore after such a lowering takes place, the set of optimizations that could be applied to the post-lowered code is much narrower, as only Binaryen optimization passes remain. The general high-level LLVM IR/"bitcode level" optimization passes would not be applicable then. My understanding is that would be quite a limitation in optimization capability.

tangobravo commented 1 month ago

Thanks for the mention of simde - at a glance that looks potentially ideal.

I don't personally have access to the Havok source but it's still an actively maintained codebase and if there's a relatively painless way for them to get a baseline wasm build to work then we can ask them to try it. Latest stats I could find from April this year still had over 8% of iOS users on <16.4.

tangobravo commented 1 month ago

I did a bit of playing around in compiler explorer: https://godbolt.org/z/z6nMG7ojP.

LLVM's vector extensions work out of the box already, and it looks like SIMDe offers a great solution for intrinsics. @kripken the portable/scalar implementations are actually the main target, and some are specialized to translate SSE -> NEON or whatever too.

Closing this now as that's exactly what I was after - thanks for the suggestion (and all your awesome work on emscripten in general!)