Commit 9ace39e02a for aom

commit 9ace39e02a34992b83fc7f7f2bfbbd2e79348c74
Author: Steven Robertson <strobe@google.com>
Date:   Wed Oct 21 07:19:04 2026 +0000

    Add an option to build the x86 intrinsics for wasm32

    Emscripten translates the x86 SSE intrinsics to WebAssembly SIMD128.
    With -DENABLE_WASM_X86_INTRINSICS=1 (and SIMD128 enabled), wasm32 builds
    compile the existing SSE2 through SSE4.1 intrinsics kernels and select
    them statically through RTCD; x86 assembly is skipped. SSE4.2 is left
    out because it is only used for CRC32, which Emscripten cannot
    translate. Native SIMD128 kernels, where present, take priority over the
    translated ones.

    av1_warped_filter is now int16_t whenever SSE4.1 is enabled, since the
    SSE4.1 warp kernels read it as int16_t; it was int8_t on non-ARM, non-x86
    targets.

    In an end-to-end test (a 10-bit 4:2:2 AV1 intra encoder linking libaom,
    4K, Node on an Apple M5), this sped up encoding by 1.5x to 1.8x over the
    C kernels, with bit-identical output.

    Change-Id: Ib626f69f9851a34c59a83567ccb0ea9bde3fbd70

diff --git a/av1/common/warped_motion.h b/av1/common/warped_motion.h
index fbd24d1adc..16a22fccbf 100644
--- a/av1/common/warped_motion.h
+++ b/av1/common/warped_motion.h
@@ -33,7 +33,10 @@
 #define WARP_ERROR_BLOCK_LOG 5
 #define WARP_ERROR_BLOCK (1 << WARP_ERROR_BLOCK_LOG)

-#if AOM_ARCH_ARM || AOM_ARCH_AARCH64 || AOM_ARCH_X86 || AOM_ARCH_X86_64
+// The x86 SSE4.1 kernels, which can also be built for wasm32, read the table as
+// int16_t.
+#if AOM_ARCH_ARM || AOM_ARCH_AARCH64 || AOM_ARCH_X86 || AOM_ARCH_X86_64 || \
+    HAVE_SSE4_1
 typedef int16_t WarpedFilterCoeff;
 #else
 typedef int8_t WarpedFilterCoeff;
diff --git a/cmake/aom_config_defaults.cmake b/cmake/aom_config_defaults.cmake
index c5c3c3d3cc..dd9b94639e 100644
--- a/cmake/aom_config_defaults.cmake
+++ b/cmake/aom_config_defaults.cmake
@@ -274,3 +274,6 @@ set_aom_option_var(ENABLE_RVV "Enables RVV optimizations on RISC-V targets." ON)
 # WebAssembly SIMD128 intrinsics flags.
 set_aom_option_var(ENABLE_SIMD128
                    "Enables SIMD128 optimizations on wasm32 targets." ON)
+set_aom_option_var(
+  ENABLE_WASM_X86_INTRINSICS
+  "Builds the x86 SSE intrinsics kernels for wasm32 (requires SIMD128)." OFF)
diff --git a/cmake/cpu.cmake b/cmake/cpu.cmake
index 7b988bd71f..d7affea9ac 100644
--- a/cmake/cpu.cmake
+++ b/cmake/cpu.cmake
@@ -145,6 +145,31 @@ elseif("${AOM_TARGET_CPU}" STREQUAL "wasm32")
     set(HAVE_SIMD128 0)
     set(AOM_RTCD_FLAGS ${AOM_RTCD_FLAGS} --disable-simd128)
   endif()
+
+  # Emscripten translates x86 SSE intrinsics to SIMD128, so the x86 intrinsics
+  # kernels can be built for wasm32; x86 assembly cannot. SSE4.2 is excluded:
+  # libaom only uses it for CRC32, which has no SIMD128 equivalent.
+  if(ENABLE_WASM_X86_INTRINSICS AND HAVE_SIMD128)
+    # Emscripten only accepts the -msse* flags along with -msimd128, so it is
+    # added to the base flags of all targets (this also lets the compiler flag
+    # checks see it).
+    string(APPEND CMAKE_C_FLAGS " ${AOM_SIMD128_FLAG}")
+    string(APPEND CMAKE_CXX_FLAGS " ${AOM_SIMD128_FLAG}")
+  endif()
+  set(WASM_X86_FLAVORS "SSE;SSE2;SSE3;SSSE3;SSE4_1")
+  foreach(flavor ${WASM_X86_FLAVORS})
+    if(ENABLE_WASM_X86_INTRINSICS
+       AND HAVE_SIMD128
+       AND ENABLE_${flavor}
+       AND NOT disable_remaining_flavors)
+      set(HAVE_${flavor} 1)
+    else()
+      set(disable_remaining_flavors 1)
+      set(HAVE_${flavor} 0)
+      string(TOLOWER ${flavor} flavor)
+      set(AOM_RTCD_FLAGS ${AOM_RTCD_FLAGS} --disable-${flavor})
+    endif()
+  endforeach()
 elseif("${AOM_TARGET_CPU}" MATCHES "riscv")
   set(AOM_ARCH_RISCV64 1)

diff --git a/cmake/rtcd.pl b/cmake/rtcd.pl
index c2319588c6..e573ef2365 100755
--- a/cmake/rtcd.pl
+++ b/cmake/rtcd.pl
@@ -500,11 +500,13 @@ if ($opts{arch} eq 'x86') {
   @ALL_ARCHS = filter(qw/rvv/);
   riscv;
 } elsif ($opts{arch} eq 'wasm32') {
-  @ALL_ARCHS = filter(qw/simd128/);
+  # The x86 flavors are Emscripten translations of x86 intrinsics to SIMD128;
+  # native SIMD128 kernels are preferred over them.
+  @ALL_ARCHS = filter(qw/sse sse2 sse3 ssse3 sse4_1 simd128/);
   # SIMD128 is a compile-time property of a Wasm module, so when enabled it is
   # always available: resolve dispatch statically, as for neon on arm64.
   if (keys %required == 0) {
-    @REQUIRES = filter(qw/simd128/);
+    @REQUIRES = @ALL_ARCHS;
     &require(@REQUIRES);
   }
   wasm;