PR #22746 opened by valadaptive
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22746
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22746.patch

This PR is "stacked" atop #22745.

This mirrors the existing SIMD128 support, and doesn't do any runtime feature 
detection since WebAssembly doesn't support it.

Unlike SIMD128, it is *disabled* by default, since browser support is currently 
a lot worse (Safari doesn't support it). I believe this is the first 
disabled-by-default CPU feature in ffmpeg, but I think it's justified 
considering the lack of runtime feature detection.

There is nothing using relaxed SIMD currently, but I expect the relaxed 
multiply-add operation to be particularly useful, and I want to try it out in 
the FFT/MDCT code.

Let me know if I've missed any spots--I tried to follow the structure of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/commit/2dc55f5993.


>From ba6301a6aeb076b899fddac2d6900b90115c9fa9 Mon Sep 17 00:00:00 2001
From: valadaptive <[email protected]>
Date: Tue, 7 Apr 2026 22:52:43 -0400
Subject: [PATCH 1/2] configure: set wasm SIMD128 cflags automatically

When commit 2dc55f5993 added support for SIMD128, it *also* required
users to pass `-msimd128` in --extra-cflags. This is a bit awkward and
unintuitive.

By changing this so that the requisite flags are added whenever the
feature is enabled via the configure script, we make things a lot more
intuitive.

This technically affects compatibility since SIMD128 is enabled by
default, and WebAssembly does not have runtime feature detection.
However, SIMD128 is widely supported (the last browser to support it was
Safari 16.4, released March 2023).

The ffmpegwasm project also enables SIMD128 explicitly:
https://github.com/ffmpegwasm/ffmpeg.wasm/blob/f876f90/Makefile#L9

I do later plan to add support for the relaxed SIMD extension. I'll make
that one disabled-by-default (since Safari/JSC does not yet support it).

Signed-off-by: valadaptive <[email protected]>
---
 configure | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index ff5f7935cd..b39c9d3187 100755
--- a/configure
+++ b/configure
@@ -6801,7 +6801,10 @@ elif enabled riscv; then
 
 elif enabled wasm; then
 
-    enabled simd128 && check_cc simd128 wasm_simd128.h  "v128_t v = 
wasm_v128_load(0);"
+    if enabled simd128; then
+        check_cflags -msimd128 &&
+        check_cc simd128 wasm_simd128.h "v128_t v = wasm_v128_load(0);"
+    fi
 
 elif enabled x86; then
 
-- 
2.52.0


>From af4d7abb755180b5506780d72c2369d0e6f2d205 Mon Sep 17 00:00:00 2001
From: valadaptive <[email protected]>
Date: Tue, 7 Apr 2026 21:55:32 -0400
Subject: [PATCH 2/2] configure: add wasm relaxed SIMD support

This mirrors the existing SIMD128 support, and doesn't do any runtime
feature detection since WebAssembly doesn't support it.

Unlike SIMD128, it is *disabled* by default, since browser support is
currently a lot worse (Safari doesn't support it). I believe this is the
first disabled-by-default CPU feature in ffmpeg, but I think it's
justified considering the lack of runtime feature detection.

There is nothing using relaxed SIMD currently, but I expect the relaxed
multiply-add operation to be particularly useful, and I want to try it
out in the FFT/MDCT code.

Signed-off-by: valadaptive <[email protected]>
---
 Makefile                  |  2 +-
 configure                 | 15 +++++++++++++++
 ffbuild/arch.mak          |  3 ++-
 libavutil/cpu.c           |  3 ++-
 libavutil/cpu.h           |  1 +
 libavutil/tests/cpu.c     |  3 ++-
 libavutil/wasm/cpu.c      |  3 +++
 tests/checkasm/checkasm.c |  3 ++-
 8 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index f296e87ed4..eb8f6dddb5 100644
--- a/Makefile
+++ b/Makefile
@@ -113,7 +113,7 @@ SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS  
             \
                MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS         \
                MMI-OBJS LSX-OBJS LASX-OBJS RV-OBJS RVV-OBJS RVVB-OBJS    \
                OBJS SHLIBOBJS STLIBOBJS HOSTOBJS TESTOBJS SIMD128-OBJS   \
-               SVE-OBJS SVE2-OBJS SME-OBJS SME2-OBJS
+               RELAXED_SIMD-OBJS SVE-OBJS SVE2-OBJS SME-OBJS SME2-OBJS
 
 define RESET
 $(1) :=
diff --git a/configure b/configure
index b39c9d3187..894732cdcf 100755
--- a/configure
+++ b/configure
@@ -502,6 +502,10 @@ Optimization options (experts only):
   --disable-rvv            disable RISC-V Vector optimizations
   --disable-fast-unaligned consider unaligned accesses slow
   --disable-simd128        disable WebAssembly simd128 optimizations
+  --enable-relaxed-simd    enable WebAssembly relaxed SIMD optimizations.
+                           Modules built with this enabled will fail to
+                           instantiate on runtimes that do not support the
+                           Relaxed SIMD proposal (e.g. Safari/JSC) [no]
 
 Developer options (useful when working on FFmpeg itself):
   --disable-debug          disable debugging symbols
@@ -2379,6 +2383,7 @@ ARCH_EXT_LIST_LOONGSON="
 
 ARCH_EXT_LIST_WASM="
     simd128
+    relaxed_simd
 "
 
 ARCH_EXT_LIST_X86_SIMD="
@@ -3009,6 +3014,7 @@ mipsdspr2_deps="mips"
 msa_deps="mipsfpu"
 
 simd128_deps="wasm"
+relaxed_simd_deps="simd128"
 
 x86_64_select="i686"
 x86_64_suggest="fast_cmov"
@@ -4617,6 +4623,9 @@ done
 
 enable $ARCH_EXT_LIST
 
+# Relaxed SIMD is disabled by default
+disable relaxed_simd
+
 die_unknown(){
     echo "Unknown option \"$1\"."
     echo "See $0 --help for available options."
@@ -6806,6 +6815,12 @@ elif enabled wasm; then
         check_cc simd128 wasm_simd128.h "v128_t v = wasm_v128_load(0);"
     fi
 
+    if enabled relaxed_simd; then
+        check_cflags -mrelaxed-simd &&
+        check_cc relaxed_simd wasm_simd128.h \
+            "v128_t v = wasm_f32x4_relaxed_madd(wasm_f32x4_splat(0), 
wasm_f32x4_splat(0), wasm_f32x4_splat(0));"
+    fi
+
 elif enabled x86; then
 
     check_builtin rdtsc    intrin.h   "__rdtsc()"
diff --git a/ffbuild/arch.mak b/ffbuild/arch.mak
index 13e1eb33bc..a910235588 100644
--- a/ffbuild/arch.mak
+++ b/ffbuild/arch.mak
@@ -23,6 +23,7 @@ OBJS-$(HAVE_RV)      += $(RV-OBJS)      $(RV-OBJS-yes)
 OBJS-$(HAVE_RVV)     += $(RVV-OBJS)     $(RVV-OBJS-yes)
 OBJS-$(HAVE_RV_ZVBB) += $(RVVB-OBJS)    $(RVVB-OBJS-yes)
 
-OBJS-$(HAVE_SIMD128) += $(SIMD128-OBJS) $(SIMD128-OBJS-yes)
+OBJS-$(HAVE_SIMD128)      += $(SIMD128-OBJS)      $(SIMD128-OBJS-yes)
+OBJS-$(HAVE_RELAXED_SIMD) += $(RELAXED_SIMD-OBJS) $(RELAXED_SIMD-OBJS-yes)
 
 OBJS-$(HAVE_X86ASM)  += $(X86ASM-OBJS)  $(X86ASM-OBJS-yes)
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 00029f81ca..0c9e77e32d 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -210,7 +210,8 @@ int av_parse_cpu_caps(unsigned *flags, const char *s)
         { "zvbb",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RV_ZVBB 
},   .unit = "flags" },
         { "misaligned", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 
AV_CPU_FLAG_RV_MISALIGNED },   .unit = "flags" },
 #elif ARCH_WASM
-        { "simd128",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SIMD128 
 },    .unit = "flags" },
+        { "simd128",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 
AV_CPU_FLAG_SIMD128      },    .unit = "flags" },
+        { "relaxed_simd", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 
AV_CPU_FLAG_RELAXED_SIMD },    .unit = "flags" },
 #endif
         { NULL },
     };
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 07076dafb8..53029618bb 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -112,6 +112,7 @@
 
 // WASM extensions
 #define AV_CPU_FLAG_SIMD128      (1 << 0)
+#define AV_CPU_FLAG_RELAXED_SIMD (1 << 1)
 
 /**
  * Return the flags which specify extensions supported by the CPU.
diff --git a/libavutil/tests/cpu.c b/libavutil/tests/cpu.c
index f74d02270e..24545ac68b 100644
--- a/libavutil/tests/cpu.c
+++ b/libavutil/tests/cpu.c
@@ -112,7 +112,8 @@ static const struct {
     { AV_CPU_FLAG_RV_ZVBB,   "zvbb"       },
     { AV_CPU_FLAG_RV_MISALIGNED, "misaligned" },
 #elif ARCH_WASM
-    { AV_CPU_FLAG_SIMD128,   "simd128"    },
+    { AV_CPU_FLAG_SIMD128,      "simd128"      },
+    { AV_CPU_FLAG_RELAXED_SIMD, "relaxed_simd" },
 #endif
     { 0 }
 };
diff --git a/libavutil/wasm/cpu.c b/libavutil/wasm/cpu.c
index 71978cc5ef..677ea0452e 100644
--- a/libavutil/wasm/cpu.c
+++ b/libavutil/wasm/cpu.c
@@ -27,6 +27,9 @@ int ff_get_cpu_flags_wasm(void)
     int flags = 0;
 #if HAVE_SIMD128
     flags |= AV_CPU_FLAG_SIMD128;
+#endif
+#if HAVE_RELAXED_SIMD
+    flags |= AV_CPU_FLAG_RELAXED_SIMD;
 #endif
     return flags;
 }
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index 8629f26788..5f50c64601 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -438,7 +438,8 @@ static const struct {
     { "LSX",      "lsx",      AV_CPU_FLAG_LSX },
     { "LASX",     "lasx",     AV_CPU_FLAG_LASX },
 #elif ARCH_WASM
-    { "SIMD128",    "simd128",  AV_CPU_FLAG_SIMD128 },
+    { "SIMD128",      "simd128",      AV_CPU_FLAG_SIMD128 },
+    { "RELAXED_SIMD", "relaxed_simd", AV_CPU_FLAG_RELAXED_SIMD },
 #endif
     { NULL }
 };
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to