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

(There is still stuff left to do; e.g. there are still unnecessary intermediate 
stores. And I haven't even started what I initially wanted to do: No longer use 
MMX.)


>From 7c3096636b40acda3b41ec37518755c506f471f5 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Sun, 5 Jul 2026 10:07:02 +0200
Subject: [PATCH 1/8] avcodec/x86/vp9lpf: Combine comparisons

The VP9 loop filter involves comparing several unsigned
values against the same value and combines the results:
a <= I && b <= I && ...
This is equivalent to max(a,b,...) <= I and using this
form is beneficial: Each comparison needs one pxor*
and one pcmpgtb and every comparison except the first
uses one por to combine the result. Switching to max
instead results in one comparison and (operands - 1)
pmaxub to create the maximum; the latter can be relaxed
to por if the final comparator is one**, as it is for
flat8{in,out}.

Doing so saves 4113B of .text here and is beneficial
for performance:

Old benchmarks:
  vp9_loop_filter_h_4_8_8bpp_c:                78.0
  vp9_loop_filter_h_4_8_8bpp_mmxext:           74.2 ( 1.05x)
  vp9_loop_filter_h_8_8_8bpp_c:                85.0
  vp9_loop_filter_h_8_8_8bpp_mmxext:          101.9 ( 0.83x)
  vp9_loop_filter_h_16_8_8bpp_c:              140.3
  vp9_loop_filter_h_16_16_8bpp_c:             250.7
  vp9_loop_filter_h_16_16_8bpp_sse2:          176.1 ( 1.39x)
  vp9_loop_filter_h_16_16_8bpp_ssse3:         172.9 ( 1.38x)
  vp9_loop_filter_h_16_16_8bpp_avx:           165.5 ( 1.46x)
  vp9_loop_filter_mix2_h_44_16_8bpp_c:        167.5
  vp9_loop_filter_mix2_h_44_16_8bpp_sse2:      70.5 ( 2.32x)
  vp9_loop_filter_mix2_h_44_16_8bpp_ssse3:     69.7 ( 2.40x)
  vp9_loop_filter_mix2_h_44_16_8bpp_avx:       70.3 ( 2.38x)
  vp9_loop_filter_mix2_h_48_16_8bpp_c:        175.5
  vp9_loop_filter_mix2_h_48_16_8bpp_sse2:      93.3 ( 1.87x)
  vp9_loop_filter_mix2_h_48_16_8bpp_ssse3:     93.3 ( 1.87x)
  vp9_loop_filter_mix2_h_48_16_8bpp_avx:       90.1 ( 1.95x)
  vp9_loop_filter_mix2_h_84_16_8bpp_c:        177.1
  vp9_loop_filter_mix2_h_84_16_8bpp_sse2:      94.3 ( 1.82x)
  vp9_loop_filter_mix2_h_84_16_8bpp_ssse3:     90.6 ( 1.92x)
  vp9_loop_filter_mix2_h_84_16_8bpp_avx:       88.8 ( 1.99x)
  vp9_loop_filter_mix2_h_88_16_8bpp_c:        186.4
  vp9_loop_filter_mix2_h_88_16_8bpp_sse2:      94.7 ( 1.95x)
  vp9_loop_filter_mix2_h_88_16_8bpp_ssse3:     93.7 ( 1.98x)
  vp9_loop_filter_mix2_h_88_16_8bpp_avx:       89.7 ( 2.07x)
  vp9_loop_filter_mix2_v_44_16_8bpp_c:        176.0
  vp9_loop_filter_mix2_v_44_16_8bpp_sse2:      29.7 ( 5.92x)
  vp9_loop_filter_mix2_v_44_16_8bpp_ssse3:     29.3 ( 6.02x)
  vp9_loop_filter_mix2_v_44_16_8bpp_avx:       30.5 ( 5.76x)
  vp9_loop_filter_mix2_v_48_16_8bpp_c:        187.7
  vp9_loop_filter_mix2_v_48_16_8bpp_sse2:      65.1 ( 2.82x)
  vp9_loop_filter_mix2_v_48_16_8bpp_ssse3:     65.2 ( 2.84x)
  vp9_loop_filter_mix2_v_48_16_8bpp_avx:       56.0 ( 3.35x)
  vp9_loop_filter_mix2_v_84_16_8bpp_c:        188.3
  vp9_loop_filter_mix2_v_84_16_8bpp_sse2:      60.7 ( 3.03x)
  vp9_loop_filter_mix2_v_84_16_8bpp_ssse3:     64.8 ( 2.80x)
  vp9_loop_filter_mix2_v_84_16_8bpp_avx:       56.8 ( 3.21x)
  vp9_loop_filter_mix2_v_88_16_8bpp_c:        199.4
  vp9_loop_filter_mix2_v_88_16_8bpp_sse2:      65.8 ( 3.01x)
  vp9_loop_filter_mix2_v_88_16_8bpp_ssse3:     57.6 ( 3.46x)
  vp9_loop_filter_mix2_v_88_16_8bpp_avx:       56.3 ( 3.53x)
  vp9_loop_filter_v_4_8_8bpp_c:                82.8
  vp9_loop_filter_v_4_8_8bpp_mmxext:           32.4 ( 2.50x)
  vp9_loop_filter_v_8_8_8bpp_c:                91.9
  vp9_loop_filter_v_8_8_8bpp_mmxext:           65.6 ( 1.40x)
  vp9_loop_filter_v_16_8_8bpp_c:              156.2
  vp9_loop_filter_v_16_16_8bpp_c:             291.3
  vp9_loop_filter_v_16_16_8bpp_sse2:          125.7 ( 2.25x)
  vp9_loop_filter_v_16_16_8bpp_ssse3:         123.1 ( 2.31x)
  vp9_loop_filter_v_16_16_8bpp_avx:           115.3 ( 2.51x)

New benchmarks:
  vp9_loop_filter_h_4_8_8bpp_c:                78.8
  vp9_loop_filter_h_4_8_8bpp_mmxext:           62.4 ( 1.26x)
  vp9_loop_filter_h_8_8_8bpp_c:                85.8
  vp9_loop_filter_h_8_8_8bpp_mmxext:           86.5 ( 0.97x)
  vp9_loop_filter_h_16_8_8bpp_c:              139.3
  vp9_loop_filter_h_16_16_8bpp_c:             251.3
  vp9_loop_filter_h_16_16_8bpp_sse2:          164.7 ( 1.45x)
  vp9_loop_filter_h_16_16_8bpp_ssse3:         164.2 ( 1.49x)
  vp9_loop_filter_h_16_16_8bpp_avx:           155.2 ( 1.56x)
  vp9_loop_filter_mix2_h_44_16_8bpp_c:        168.3
  vp9_loop_filter_mix2_h_44_16_8bpp_sse2:      60.1 ( 2.80x)
  vp9_loop_filter_mix2_h_44_16_8bpp_ssse3:     60.1 ( 2.80x)
  vp9_loop_filter_mix2_h_44_16_8bpp_avx:       60.4 ( 2.79x)
  vp9_loop_filter_mix2_h_48_16_8bpp_c:        178.1
  vp9_loop_filter_mix2_h_48_16_8bpp_sse2:      83.5 ( 2.07x)
  vp9_loop_filter_mix2_h_48_16_8bpp_ssse3:     84.0 ( 2.02x)
  vp9_loop_filter_mix2_h_48_16_8bpp_avx:       78.0 ( 2.28x)
  vp9_loop_filter_mix2_h_84_16_8bpp_c:        181.7
  vp9_loop_filter_mix2_h_84_16_8bpp_sse2:      78.3 ( 2.20x)
  vp9_loop_filter_mix2_h_84_16_8bpp_ssse3:     85.1 ( 2.12x)
  vp9_loop_filter_mix2_h_84_16_8bpp_avx:       79.8 ( 2.27x)
  vp9_loop_filter_mix2_h_88_16_8bpp_c:        184.8
  vp9_loop_filter_mix2_h_88_16_8bpp_sse2:      85.6 ( 2.14x)
  vp9_loop_filter_mix2_h_88_16_8bpp_ssse3:     85.1 ( 2.09x)
  vp9_loop_filter_mix2_h_88_16_8bpp_avx:       77.6 ( 2.38x)
  vp9_loop_filter_mix2_v_44_16_8bpp_c:        176.0
  vp9_loop_filter_mix2_v_44_16_8bpp_sse2:      28.1 ( 6.27x)
  vp9_loop_filter_mix2_v_44_16_8bpp_ssse3:     32.3 ( 5.42x)
  vp9_loop_filter_mix2_v_44_16_8bpp_avx:       27.4 ( 6.43x)
  vp9_loop_filter_mix2_v_48_16_8bpp_c:        187.4
  vp9_loop_filter_mix2_v_48_16_8bpp_sse2:      55.3 ( 3.39x)
  vp9_loop_filter_mix2_v_48_16_8bpp_ssse3:     54.7 ( 3.42x)
  vp9_loop_filter_mix2_v_48_16_8bpp_avx:       53.7 ( 3.48x)
  vp9_loop_filter_mix2_v_84_16_8bpp_c:        189.6
  vp9_loop_filter_mix2_v_84_16_8bpp_sse2:      62.5 ( 3.00x)
  vp9_loop_filter_mix2_v_84_16_8bpp_ssse3:     61.3 ( 3.07x)
  vp9_loop_filter_mix2_v_84_16_8bpp_avx:       54.3 ( 3.47x)
  vp9_loop_filter_mix2_v_88_16_8bpp_c:        199.5
  vp9_loop_filter_mix2_v_88_16_8bpp_sse2:      55.1 ( 3.52x)
  vp9_loop_filter_mix2_v_88_16_8bpp_ssse3:     54.4 ( 3.66x)
  vp9_loop_filter_mix2_v_88_16_8bpp_avx:       53.0 ( 3.69x)
  vp9_loop_filter_v_4_8_8bpp_c:                84.3
  vp9_loop_filter_v_4_8_8bpp_mmxext:           32.0 ( 2.62x)
  vp9_loop_filter_v_8_8_8bpp_c:                94.3
  vp9_loop_filter_v_8_8_8bpp_mmxext:           63.7 ( 1.48x)
  vp9_loop_filter_v_16_8_8bpp_c:              155.8
  vp9_loop_filter_v_16_16_8bpp_c:             292.0
  vp9_loop_filter_v_16_16_8bpp_sse2:          119.5 ( 2.39x)
  vp9_loop_filter_v_16_16_8bpp_ssse3:         119.1 ( 2.39x)
  vp9_loop_filter_v_16_16_8bpp_avx:           111.0 ( 2.61x)

*: to shift unsigned values to signed ones for pcmpgtb
**: or any comparison like <= 2^n-1

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/vp9lpf.asm | 101 ++++++++++++++++----------------------
 1 file changed, 43 insertions(+), 58 deletions(-)

diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm
index 92e5d03ad7..8509b61ebc 100644
--- a/libavcodec/x86/vp9lpf.asm
+++ b/libavcodec/x86/vp9lpf.asm
@@ -89,12 +89,6 @@ SECTION .text
     pcmpgtb             %1, %2
 %endmacro
 
-; %1 = abs(%2-%3) > %4
-%macro ABSSUB_GT 5-6 [pb_80]; dst, src1, src2, cmp, tmp, [pb_80]
-    ABSSUB              %1, %2, %3, %5      ; dst = abs(src1-src2)
-    CMP_GT              %1, %4, %6          ; dst > cmp
-%endmacro
-
 %macro MASK_APPLY 4 ; %1=new_data/dst %2=old_data %3=mask %4=tmp
     pand                %1, %3              ; new &= mask
     pandn               %4, %3, %2          ; tmp = ~mask & old
@@ -618,17 +612,18 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
 %define rq2 [Q2]
 %define rq3 [Q3]
 %endif
-    ABSSUB_GT           m5, rp3, rp2, m2, m7, m0        ; m5 = abs(p3-p2) <= I
-    ABSSUB_GT           m1, rp2, rp1, m2, m7, m0        ; m1 = abs(p2-p1) <= I
-    por                 m5, m1
-    ABSSUB_GT           m1, rp1, rp0, m2, m7, m0        ; m1 = abs(p1-p0) <= I
-    por                 m5, m1
-    ABSSUB_GT           m1, rq0, rq1, m2, m7, m0        ; m1 = abs(q1-q0) <= I
-    por                 m5, m1
-    ABSSUB_GT           m1, rq1, rq2, m2, m7, m0        ; m1 = abs(q2-q1) <= I
-    por                 m5, m1
-    ABSSUB_GT           m1, rq2, rq3, m2, m7, m0        ; m1 = abs(q3-q2) <= I
-    por                 m5, m1
+    ABSSUB              m5, rp3, rp2, m7                ; m5 = abs(p3-p2)
+    ABSSUB              m1, rp2, rp1, m7                ; m1 = abs(p2-p1)
+    pmaxub              m5, m1
+    ABSSUB              m1, rp1, rp0, m7                ; m1 = abs(p1-p0)
+    pmaxub              m5, m1
+    ABSSUB              m1, rq0, rq1, m7                ; m1 = abs(q1-q0)
+    pmaxub              m5, m1
+    ABSSUB              m1, rq1, rq2, m7                ; m1 = abs(q2-q1)
+    pmaxub              m5, m1
+    ABSSUB              m1, rq2, rq3, m7                ; m1 = abs(q3-q2)
+    pmaxub              m5, m1
+    CMP_GT              m5, m2, m0
     ABSSUB              m1, rp0, rq0, m7                ; abs(p0-q0)
     paddusb             m1, m1                          ; abs(p0-q0) * 2
     ABSSUB              m2, rp1, rq1, m7                ; abs(p1-q1)
@@ -641,44 +636,35 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     SWAP                 1, 3
     pxor                m3, [pb_ff]
 
-    ; (m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3)
+    ; (m0: pb_80, m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3)
     ; calc flat8in (if not 44_16) and hev masks
 %if %2 != 44 && %2 != 4
     mova                m6, [pb_81]                     ; [1 1 1 1 ...] ^ 0x80
-    ABSSUB_GT           m2, rp3, rp0, m6, m5            ; abs(p3 - p0) <= 1
-%ifdef m8
-    mova                m8, [pb_80]
-%define rb80 m8
-%else
-%define rb80 [pb_80]
-%endif
-    ABSSUB_GT           m1, rp2, rp0, m6, m5, rb80      ; abs(p2 - p0) <= 1
-    por                 m2, m1
-    ABSSUB              m4, rp1, rp0, m5                ; abs(p1 - p0)
+    ABSSUB              m2, rp1, rp0, m5                ; abs(p1 - p0)
 %if %2 <= 16
 %if cpuflag(ssse3)
-    pxor                m0, m0
+    pxor                m5, m5
 %endif
-    SPLATB_REG          m7, H, m0                       ; H H H H ...
+    SPLATB_REG          m7, H, m5                       ; H H H H ...
 %else
     movd                m7, Hd
     SPLATB_MIX          m7
 %endif
-    pxor                m7, rb80
-    pxor                m4, rb80
-    pcmpgtb             m0, m4, m7                      ; abs(p1 - p0) > H 
(1/2 hev condition)
-    CMP_GT              m4, m6                          ; abs(p1 - p0) <= 1
-    por                 m2, m4                          ; (flat8in)
-    ABSSUB              m4, rq1, rq0, m1                ; abs(q1 - q0)
-    pxor                m4, rb80
-    pcmpgtb             m5, m4, m7                      ; abs(q1 - q0) > H 
(2/2 hev condition)
-    por                 m0, m5                          ; hev final value
-    CMP_GT              m4, m6                          ; abs(q1 - q0) <= 1
-    por                 m2, m4                          ; (flat8in)
-    ABSSUB_GT           m1, rq2, rq0, m6, m5, rb80      ; abs(q2 - q0) <= 1
+    ABSSUB              m4, rq1, rq0, m5                ; abs(q1 - q0)
+    pmaxub              m4, m2                          ; max(abs(q1 - q0), 
abs(p1 - p0))
+    ABSSUB              m2, rp2, rp0, m5                ; abs(p2 - p0)
+    pxor                m7, m0
+    por                 m2, m4
+    pxor                m4, m0
+    pcmpgtb             m4, m7                          ; hev: max(abs(q1 - 
q0), abs(p1 - p0)) > H
+    ABSSUB              m1, rp3, rp0, m5                ; abs(p3 - p0)
     por                 m2, m1
-    ABSSUB_GT           m1, rq3, rq0, m6, m5, rb80      ; abs(q3 - q0) <= 1
-    por                 m2, m1                          ; flat8in final value
+    ABSSUB              m1, rq2, rq0, m5                ; abs(q2 - q0)
+    por                 m2, m1
+    ABSSUB              m1, rq3, rq0, m5                ; abs(q3 - q0)
+    por                 m2, m1
+    CMP_GT              m2, m6, m0                      ; flat8in
+    SWAP                0, 4
     pxor                m2, [pb_ff]
 %if %2 == 84 || %2 == 48
     pand                m2, [mask_mix%2]
@@ -695,13 +681,11 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     SPLATB_REG          m7, H, m0                       ; H H H H ...
 %endif
     pxor                m7, m6
-    ABSSUB              m4, rp1, rp0, m1                ; abs(p1 - p0)
-    pxor                m4, m6
-    pcmpgtb             m0, m4, m7                      ; abs(p1 - p0) > H 
(1/2 hev condition)
+    ABSSUB              m0, rp1, rp0, m1                ; abs(p1 - p0)
     ABSSUB              m4, rq1, rq0, m1                ; abs(q1 - q0)
-    pxor                m4, m6
-    pcmpgtb             m5, m4, m7                      ; abs(q1 - q0) > H 
(2/2 hev condition)
-    por                 m0, m5                          ; hev final value
+    pmaxub              m0, m4                          ; max(abs(p1 - p0), 
abs(q1 - q0))
+    pxor                m0, m6
+    pcmpgtb             m0, m7                          ; max > H; hev final 
value
 %endif
 
 %if %2 == 16
@@ -716,8 +700,8 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
 %define rp7 [P7]
 %define rp6 [P6]
 %endif
-    ABSSUB_GT           m1, rp7, rp0, m6, m5            ; abs(p7 - p0) <= 1
-    ABSSUB_GT           m7, rp6, rp0, m6, m5            ; abs(p6 - p0) <= 1
+    ABSSUB              m7, rp7, rp0, m5                ; abs(p7 - p0)
+    ABSSUB              m1, rp6, rp0, m5                ; abs(p6 - p0)
     por                 m1, m7
 %ifdef m8
     mova                m8, [P5]
@@ -728,9 +712,9 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
 %define rp5 [P5]
 %define rp4 [P4]
 %endif
-    ABSSUB_GT           m7, rp5, rp0, m6, m5            ; abs(p5 - p0) <= 1
+    ABSSUB              m7, rp5, rp0, m5                ; abs(p5 - p0)
     por                 m1, m7
-    ABSSUB_GT           m7, rp4, rp0, m6, m5            ; abs(p4 - p0) <= 1
+    ABSSUB              m7, rp4, rp0, m5                ; abs(p4 - p0)
     por                 m1, m7
 %ifdef m8
     mova                m14, [Q4]
@@ -741,9 +725,9 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
 %define rq4 [Q4]
 %define rq5 [Q5]
 %endif
-    ABSSUB_GT           m7, rq4, rq0, m6, m5            ; abs(q4 - q0) <= 1
+    ABSSUB              m7, rq4, rq0, m5                ; abs(q4 - q0)
     por                 m1, m7
-    ABSSUB_GT           m7, rq5, rq0, m6, m5            ; abs(q5 - q0) <= 1
+    ABSSUB              m7, rq5, rq0, m5                ; abs(q5 - q0)
     por                 m1, m7
 %ifdef m8
     mova                m14, [Q6]
@@ -754,10 +738,11 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
 %define rq6 [Q6]
 %define rq7 [Q7]
 %endif
-    ABSSUB_GT           m7, rq6, rq0, m6, m5            ; abs(q4 - q0) <= 1
+    ABSSUB              m7, rq6, rq0, m5                ; abs(q4 - q0)
     por                 m1, m7
-    ABSSUB_GT           m7, rq7, rq0, m6, m5            ; abs(q5 - q0) <= 1
+    ABSSUB              m7, rq7, rq0, m5                ; abs(q5 - q0)
     por                 m1, m7                          ; flat8out final value
+    CMP_GT              m1, m6, [pb_80]
     pxor                m1, [pb_ff]
 %endif
 
-- 
2.52.0


>From 2e269d0f70817ba41a75bf54abaf257feb8a4d32 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Sun, 5 Jul 2026 20:41:52 +0200
Subject: [PATCH 2/8] avcodec/x86/vp9lpf: Don't do work twice

max(abs(p1-p0),abs(q1-q0)) is currently computed twice.
Stop doing so. This saves 1681B of .text and gives
a small performance boost.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/vp9lpf.asm | 29 ++++++++++++-----------------
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm
index 8509b61ebc..8ccba1f09b 100644
--- a/libavcodec/x86/vp9lpf.asm
+++ b/libavcodec/x86/vp9lpf.asm
@@ -616,9 +616,9 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
     ABSSUB              m1, rp2, rp1, m7                ; m1 = abs(p2-p1)
     pmaxub              m5, m1
     ABSSUB              m1, rp1, rp0, m7                ; m1 = abs(p1-p0)
-    pmaxub              m5, m1
-    ABSSUB              m1, rq0, rq1, m7                ; m1 = abs(q1-q0)
-    pmaxub              m5, m1
+    ABSSUB              m4, rq0, rq1, m7                ; m1 = abs(q1-q0)
+    pmaxub              m4, m1
+    pmaxub              m5, m4
     ABSSUB              m1, rq1, rq2, m7                ; m1 = abs(q2-q1)
     pmaxub              m5, m1
     ABSSUB              m1, rq2, rq3, m7                ; m1 = abs(q3-q2)
@@ -636,11 +636,11 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     SWAP                 1, 3
     pxor                m3, [pb_ff]
 
-    ; (m0: pb_80, m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3)
+    ; (m0: pb_80, m3: fm, m4: max(abs(q1 - q0), abs(p1 - p0))
+    ;  m8..15: p3 p2 p1 p0 q0 q1 q2 q3)
     ; calc flat8in (if not 44_16) and hev masks
 %if %2 != 44 && %2 != 4
     mova                m6, [pb_81]                     ; [1 1 1 1 ...] ^ 0x80
-    ABSSUB              m2, rp1, rp0, m5                ; abs(p1 - p0)
 %if %2 <= 16
 %if cpuflag(ssse3)
     pxor                m5, m5
@@ -650,8 +650,6 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
     movd                m7, Hd
     SPLATB_MIX          m7
 %endif
-    ABSSUB              m4, rq1, rq0, m5                ; abs(q1 - q0)
-    pmaxub              m4, m2                          ; max(abs(q1 - q0), 
abs(p1 - p0))
     ABSSUB              m2, rp2, rp0, m5                ; abs(p2 - p0)
     pxor                m7, m0
     por                 m2, m4
@@ -664,29 +662,26 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     ABSSUB              m1, rq3, rq0, m5                ; abs(q3 - q0)
     por                 m2, m1
     CMP_GT              m2, m6, m0                      ; flat8in
-    SWAP                0, 4
     pxor                m2, [pb_ff]
 %if %2 == 84 || %2 == 48
     pand                m2, [mask_mix%2]
 %endif
 %else
-    mova                m6, [pb_80]
 %if %2 == 44
     movd                m7, Hd
     SPLATB_MIX          m7
 %else
 %if cpuflag(ssse3)
-    pxor                m0, m0
+    pxor                m5, m5
 %endif
-    SPLATB_REG          m7, H, m0                       ; H H H H ...
+    SPLATB_REG          m7, H, m5                       ; H H H H ...
 %endif
-    pxor                m7, m6
-    ABSSUB              m0, rp1, rp0, m1                ; abs(p1 - p0)
-    ABSSUB              m4, rq1, rq0, m1                ; abs(q1 - q0)
-    pmaxub              m0, m4                          ; max(abs(p1 - p0), 
abs(q1 - q0))
-    pxor                m0, m6
-    pcmpgtb             m0, m7                          ; max > H; hev final 
value
+    pxor                m4, m0
+    pxor                m7, m0
+    pcmpgtb             m4, m7                          ; max > H; hev final 
value
+    SWAP                0, 6
 %endif
+    SWAP                0, 4
 
 %if %2 == 16
     ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3)
-- 
2.52.0


>From 083006f08be9ff29100e3aba178599f4052569b4 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Jul 2026 19:20:04 +0200
Subject: [PATCH 3/8] avcodec/x86/vp9lpf: Improve deriving masks

Deriving the fm, flat8in and flat8out masks involves
calculating max{abs(a_i-a), 1<=i<=N} (with N being two or four).
The current code does this by calculating the abs individually
(two psubusb and a por), followed by combining the results
(another por or pmaxub). But there is a better way:
Calculate the min m and max M of the a_i. Then the result equals
max{(M-a)^+,(a-m)^+}, which can be calculated with two
psubusb, followed by combining the result. E.g. for N=2
this saves two por and exchanges two psubusb with pmaxub/pminub.

Doing so saves 2062B of .text here; performance is basically
flat (the length of the critical section is unchanged).

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/vp9lpf.asm | 148 ++++++++++++++++++++++----------------
 1 file changed, 86 insertions(+), 62 deletions(-)

diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm
index 8ccba1f09b..7447992ea9 100644
--- a/libavcodec/x86/vp9lpf.asm
+++ b/libavcodec/x86/vp9lpf.asm
@@ -81,6 +81,73 @@ SECTION .text
     por                 %1, %4
 %endmacro
 
+%macro MINMAX 3-5 ; maxdst, mindst, src, scratch reg, [initial value]
+%if %0 == 5
+    %ifnum sizeof%5 ; register
+        %define %%srcmax %5
+        %define %%srcmin %5
+    %else
+        mova            %2, %5
+        %define %%srcmax %2
+        %define %%srcmin %2
+    %endif
+%else
+    %define %%srcmax %1
+    %define %%srcmin %2
+%endif
+
+%ifnum sizeof%3  ; src is register
+    %define %%src %3
+%else            ; src is memory
+    %ifnidn %4, ""
+        %define %%src %4
+        mova            %4, %3
+    %else
+        %define %%src %3
+    %endif
+%endif
+
+    pmaxub              %1, %%srcmax, %%src
+    pminub              %2, %%srcmin, %%src
+%endmacro
+
+%macro ABSDIFF_MAX 5-6 ; max [dst], min, common subtrahend, combine op, 
scratch reg, [dst]
+%ifidn %5, ""
+    ; no spare reg; must have separate dst reg
+    %define %%sub
+    psubusb             %1, %3
+    %4                  %6, %1
+    mova                %1, %3
+    psubusb             %1, %2
+    %4                  %6, %1
+%else
+%ifnum sizeof%3
+    psubusb             %1, %3
+    %define %%sub %3
+%else
+    mova                %5, %3
+    psubusb             %1, %5
+    %define %%sub %5
+%endif
+%if avx_enabled
+    %define %%min       %2
+    psubusb             %2, %%sub, %2
+%else
+    %define %%min       %5
+    %ifnidn %%sub, %5
+        mova            %5, %%sub
+    %endif
+    psubusb             %5, %2
+%endif
+%if %0 == 6
+    %4                  %6, %1
+    %4                  %6, %%min
+%else
+    %4                  %1, %%min
+%endif
+%endif
+%endmacro
+
 ; %1 = %1>%2
 %macro CMP_GT 2-3 ; src/dst, cmp, pb_80
 %if %0 == 3
@@ -612,17 +679,14 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
 %define rq2 [Q2]
 %define rq3 [Q3]
 %endif
-    ABSSUB              m5, rp3, rp2, m7                ; m5 = abs(p3-p2)
-    ABSSUB              m1, rp2, rp1, m7                ; m1 = abs(p2-p1)
-    pmaxub              m5, m1
+    MINMAX              m5, m1, rp1, m6, rp3            ; max(p1,p3), 
min(p1,p3)
+    ABSDIFF_MAX         m5, m1, rp2, pmaxub, m6         ; 
max(abs(p3-p2),abs(p2-p1))
     ABSSUB              m1, rp1, rp0, m7                ; m1 = abs(p1-p0)
     ABSSUB              m4, rq0, rq1, m7                ; m1 = abs(q1-q0)
     pmaxub              m4, m1
+    MINMAX              m1, m6, rq3, m7, rq1            ; max(q1,q3), 
min(q1,q3)
     pmaxub              m5, m4
-    ABSSUB              m1, rq1, rq2, m7                ; m1 = abs(q2-q1)
-    pmaxub              m5, m1
-    ABSSUB              m1, rq2, rq3, m7                ; m1 = abs(q3-q2)
-    pmaxub              m5, m1
+    ABSDIFF_MAX         m1, m6, rq2, pmaxub, m7, m5
     CMP_GT              m5, m2, m0
     ABSSUB              m1, rp0, rq0, m7                ; abs(p0-q0)
     paddusb             m1, m1                          ; abs(p0-q0) * 2
@@ -640,6 +704,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
     ;  m8..15: p3 p2 p1 p0 q0 q1 q2 q3)
     ; calc flat8in (if not 44_16) and hev masks
 %if %2 != 44 && %2 != 4
+    MINMAX              m2, m1, rp2, m5, rp3            ; max(p2,p3), 
min(p2,p3)
     mova                m6, [pb_81]                     ; [1 1 1 1 ...] ^ 0x80
 %if %2 <= 16
 %if cpuflag(ssse3)
@@ -650,17 +715,14 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     movd                m7, Hd
     SPLATB_MIX          m7
 %endif
-    ABSSUB              m2, rp2, rp0, m5                ; abs(p2 - p0)
+    ABSDIFF_MAX         m2, m1, rp0, por, m5            ; 
max(abs(p2-p0),abs(p3-p0))
     pxor                m7, m0
     por                 m2, m4
     pxor                m4, m0
     pcmpgtb             m4, m7                          ; hev: max(abs(q1 - 
q0), abs(p1 - p0)) > H
-    ABSSUB              m1, rp3, rp0, m5                ; abs(p3 - p0)
-    por                 m2, m1
-    ABSSUB              m1, rq2, rq0, m5                ; abs(q2 - q0)
-    por                 m2, m1
-    ABSSUB              m1, rq3, rq0, m5                ; abs(q3 - q0)
-    por                 m2, m1
+
+    MINMAX              m7, m1, rq3, m5, rq2            ; max(q2,q3), 
min(q2,q3)
+    ABSDIFF_MAX         m7, m1, rq0, por, m5, m2
     CMP_GT              m2, m6, m0                      ; flat8in
     pxor                m2, [pb_ff]
 %if %2 == 84 || %2 == 48
@@ -686,57 +748,19 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
 %if %2 == 16
     ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3)
     ; calc flat8out mask
+    MINMAX              m1, m7, [P6], m5, [P7]           ; max(p6, p7), 
min(p6,p7)
+    MINMAX              m1, m7, [P5], m5                 ; max(p5,p6,p7), 
min(p5,p6,p7)
+    MINMAX              m1, m7, [P4], m5                 ; max(p4...p7), 
min(p4...p7)
+    ABSDIFF_MAX         m1, m7, rp0, por, m5
 %ifdef m8
-    mova                m8, [P7]
-    mova                m9, [P6]
-%define rp7 m8
-%define rp6 m9
+    %define M8 m8
 %else
-%define rp7 [P7]
-%define rp6 [P6]
+    %define M8 ""
 %endif
-    ABSSUB              m7, rp7, rp0, m5                ; abs(p7 - p0)
-    ABSSUB              m1, rp6, rp0, m5                ; abs(p6 - p0)
-    por                 m1, m7
-%ifdef m8
-    mova                m8, [P5]
-    mova                m9, [P4]
-%define rp5 m8
-%define rp4 m9
-%else
-%define rp5 [P5]
-%define rp4 [P4]
-%endif
-    ABSSUB              m7, rp5, rp0, m5                ; abs(p5 - p0)
-    por                 m1, m7
-    ABSSUB              m7, rp4, rp0, m5                ; abs(p4 - p0)
-    por                 m1, m7
-%ifdef m8
-    mova                m14, [Q4]
-    mova                m15, [Q5]
-%define rq4 m14
-%define rq5 m15
-%else
-%define rq4 [Q4]
-%define rq5 [Q5]
-%endif
-    ABSSUB              m7, rq4, rq0, m5                ; abs(q4 - q0)
-    por                 m1, m7
-    ABSSUB              m7, rq5, rq0, m5                ; abs(q5 - q0)
-    por                 m1, m7
-%ifdef m8
-    mova                m14, [Q6]
-    mova                m15, [Q7]
-%define rq6 m14
-%define rq7 m15
-%else
-%define rq6 [Q6]
-%define rq7 [Q7]
-%endif
-    ABSSUB              m7, rq6, rq0, m5                ; abs(q4 - q0)
-    por                 m1, m7
-    ABSSUB              m7, rq7, rq0, m5                ; abs(q5 - q0)
-    por                 m1, m7                          ; flat8out final value
+    MINMAX              m5, m7, [Q5], M8, [Q4]           ; max(q4,q5), 
min(q4,q5)
+    MINMAX              m5, m7, [Q6], M8                 ; max(q4,q5,q6), 
min(q4,q5,q6)
+    MINMAX              m5, m7, [Q7], M8                 ; max(q4...q7), 
min(q4...q7)
+    ABSDIFF_MAX         m5, m7, rq0, por, M8, m1
     CMP_GT              m1, m6, [pb_80]
     pxor                m1, [pb_ff]
 %endif
-- 
2.52.0


>From 14dc8f95ed4ff8e8dbd210d43377a04c6066afb3 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 8 Jul 2026 21:14:02 +0200
Subject: [PATCH 4/8] avcodec/x86/vp9lpf: Avoid reloading constant

pb_80 is still in a register.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/vp9lpf.asm | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm
index 7447992ea9..106afff654 100644
--- a/libavcodec/x86/vp9lpf.asm
+++ b/libavcodec/x86/vp9lpf.asm
@@ -741,12 +741,11 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     pxor                m4, m0
     pxor                m7, m0
     pcmpgtb             m4, m7                          ; max > H; hev final 
value
-    SWAP                0, 6
 %endif
     SWAP                0, 4
 
 %if %2 == 16
-    ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3)
+    ; (m0: hev, m2: flat8in, m3: fm, m4: pb_80, m6: pb_81, m9..15: p2 p1 p0 q0 
q1 q2 q3)
     ; calc flat8out mask
     MINMAX              m1, m7, [P6], m5, [P7]           ; max(p6, p7), 
min(p6,p7)
     MINMAX              m1, m7, [P5], m5                 ; max(p5,p6,p7), 
min(p5,p6,p7)
@@ -761,7 +760,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
     MINMAX              m5, m7, [Q6], M8                 ; max(q4,q5,q6), 
min(q4,q5,q6)
     MINMAX              m5, m7, [Q7], M8                 ; max(q4...q7), 
min(q4...q7)
     ABSDIFF_MAX         m5, m7, rq0, por, M8, m1
-    CMP_GT              m1, m6, [pb_80]
+    CMP_GT              m1, m6, m4
     pxor                m1, [pb_ff]
 %endif
 
@@ -777,10 +776,10 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     ; f2:  fm & ~f14 & ~f6 & hev => fm & ~(out & in) & ~(~out & in) & hev      
    => fm &  ~in &  hev
     ; f4:  fm & ~f14 & ~f6 & ~f2 => fm & ~(out & in) & ~(~out & in) & ~(~in & 
hev) => fm &  ~in & ~hev
 
-    ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m8..15: p5 p4 p1 p0 q0 
q1 q6 q7)
+    ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m4: pb_80, m8..15: p5 
p4 p1 p0 q0 q1 q6 q7)
     ; filter2()
+    SWAP 4, 6
 %if %2 != 44 && %2 != 4
-    mova                m6, [pb_80]                     ; already in m6 if 
44_16
     SCRATCH              2, 15, rsp+%3+%4
 %if %2 == 16
     SCRATCH              1,  8, rsp+%3+%4+16
-- 
2.52.0


>From aadec4b3d03bd20546c43a4ce10207f490f3e80a Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Thu, 9 Jul 2026 10:27:44 +0200
Subject: [PATCH 5/8] avcodec/x86/vp9lpf: Avoid inverting masks

Change the comparison instead to already yield the inverted mask.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/vp9lpf.asm | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm
index 106afff654..e231d46d92 100644
--- a/libavcodec/x86/vp9lpf.asm
+++ b/libavcodec/x86/vp9lpf.asm
@@ -31,7 +31,7 @@ cextern pb_80
 pb_4:   times 16 db 0x04
 pb_10:  times 16 db 0x10
 pb_40:  times 16 db 0x40
-pb_81:  times 16 db 0x81
+pb_82:  times 16 db 0x82
 pb_f8:  times 16 db 0xf8
 pb_fe:  times 16 db 0xfe
 pb_ff:  times 16 db 0xff
@@ -705,7 +705,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
     ; calc flat8in (if not 44_16) and hev masks
 %if %2 != 44 && %2 != 4
     MINMAX              m2, m1, rp2, m5, rp3            ; max(p2,p3), 
min(p2,p3)
-    mova                m6, [pb_81]                     ; [1 1 1 1 ...] ^ 0x80
+    mova                m6, [pb_82]                     ; [2 2 2 2 ...] ^ 0x80
 %if %2 <= 16
 %if cpuflag(ssse3)
     pxor                m5, m5
@@ -723,8 +723,15 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
 
     MINMAX              m7, m1, rq3, m5, rq2            ; max(q2,q3), 
min(q2,q3)
     ABSDIFF_MAX         m7, m1, rq0, por, m5, m2
-    CMP_GT              m2, m6, m0                      ; flat8in
-    pxor                m2, [pb_ff]
+    pxor                m2, m0
+%if %2 == 16
+    ; preserve pb_82 in m6
+    pcmpgtb             m5, m6, m2                      ; flat8in
+    SWAP 2,5
+%else
+    pcmpgtb             m6, m2                          ; flat8in
+    SWAP 2,6
+%endif
 %if %2 == 84 || %2 == 48
     pand                m2, [mask_mix%2]
 %endif
@@ -745,7 +752,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
     SWAP                0, 4
 
 %if %2 == 16
-    ; (m0: hev, m2: flat8in, m3: fm, m4: pb_80, m6: pb_81, m9..15: p2 p1 p0 q0 
q1 q2 q3)
+    ; (m0: hev, m2: flat8in, m3: fm, m4: pb_80, m6: pb_82, m9..15: p2 p1 p0 q0 
q1 q2 q3)
     ; calc flat8out mask
     MINMAX              m1, m7, [P6], m5, [P7]           ; max(p6, p7), 
min(p6,p7)
     MINMAX              m1, m7, [P5], m5                 ; max(p5,p6,p7), 
min(p5,p6,p7)
@@ -760,8 +767,9 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
     MINMAX              m5, m7, [Q6], M8                 ; max(q4,q5,q6), 
min(q4,q5,q6)
     MINMAX              m5, m7, [Q7], M8                 ; max(q4...q7), 
min(q4...q7)
     ABSDIFF_MAX         m5, m7, rq0, por, M8, m1
-    CMP_GT              m1, m6, m4
-    pxor                m1, [pb_ff]
+    pxor                m1, m4
+    pcmpgtb             m6, m1
+    SWAP                1, 6
 %endif
 
     ; if (fm) {
-- 
2.52.0


>From b1dc4d4080617c1354bb8c2f440c1cc444f38381 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Thu, 9 Jul 2026 12:37:18 +0200
Subject: [PATCH 6/8] avcodec/x86/vp9lpf: Avoid unnecessary stores

P1, P0, Q0 and Q1 are kept in registers throughout the whole
function (when using xmm registers on x64), so they need not
be stored on the stack.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/vp9lpf.asm | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm
index e231d46d92..fd34881014 100644
--- a/libavcodec/x86/vp9lpf.asm
+++ b/libavcodec/x86/vp9lpf.asm
@@ -519,10 +519,6 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
 %endif ; %2
     mova           [P3],  m4
     mova           [P2],  m5
-    mova           [P1],  m6
-    mova           [P0],  m7
-    mova           [Q0],  m8
-    mova           [Q1],  m9
     mova           [Q2], m10
     mova           [Q3], m11
 %if %2 == 16
-- 
2.52.0


>From 351494ad40f7b58957a6603a0d04904405091d69 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Thu, 9 Jul 2026 18:30:49 +0200
Subject: [PATCH 7/8] avcodec/x86/vp9lpf: Combine filter2 and filter4 cases

There are two differences between the filter2 and filter4 case.
The first one is

if (hev) {
    int f = av_clip_intp2(p1 - q1, BIT_DEPTH - 1);
    f = av_clip_intp2(3 * (q0 - p0) + f, BIT_DEPTH - 1);
...
} else {
    int f = av_clip_intp2(3 * (q0 - p0), BIT_DEPTH - 1);
...

which can simply be combined to

int f = hev ? av_clip_intp2(p1 - q1, BIT_DEPTH - 1) : 0;
f = av_clip_intp2(3 * (q0 - p0) + f, BIT_DEPTH - 1);

which boils down to masking f by hev after the first
av_clip_intp2().

The second is that two more rows are processed for filter4(),
but one can simply mask the differential there, too.

So one can just combine both filters into one; doing so saves
8457B of .text here and improves performance.

Old benchmarks:
  vp9_loop_filter_h_4_8_8bpp_c:                77.3
  vp9_loop_filter_h_4_8_8bpp_mmxext:           60.8 ( 1.27x)
  vp9_loop_filter_h_8_8_8bpp_c:                86.3
  vp9_loop_filter_h_8_8_8bpp_mmxext:           82.9 ( 1.04x)
  vp9_loop_filter_h_16_8_8bpp_c:              139.7
  vp9_loop_filter_h_16_16_8bpp_c:             251.9
  vp9_loop_filter_h_16_16_8bpp_sse2:          164.8 ( 1.44x)
  vp9_loop_filter_h_16_16_8bpp_ssse3:         164.4 ( 1.49x)
  vp9_loop_filter_h_16_16_8bpp_avx:           155.1 ( 1.59x)
  vp9_loop_filter_mix2_h_44_16_8bpp_c:        169.2
  vp9_loop_filter_mix2_h_44_16_8bpp_sse2:      58.0 ( 2.91x)
  vp9_loop_filter_mix2_h_44_16_8bpp_ssse3:     56.6 ( 2.99x)
  vp9_loop_filter_mix2_h_44_16_8bpp_avx:       57.1 ( 2.96x)
  vp9_loop_filter_mix2_h_48_16_8bpp_c:        174.9
  vp9_loop_filter_mix2_h_48_16_8bpp_sse2:      75.4 ( 2.32x)
  vp9_loop_filter_mix2_h_48_16_8bpp_ssse3:     80.6 ( 2.16x)
  vp9_loop_filter_mix2_h_48_16_8bpp_avx:       75.1 ( 2.28x)
  vp9_loop_filter_mix2_h_84_16_8bpp_c:        179.7
  vp9_loop_filter_mix2_h_84_16_8bpp_sse2:      79.5 ( 2.25x)
  vp9_loop_filter_mix2_h_84_16_8bpp_ssse3:     78.2 ( 2.28x)
  vp9_loop_filter_mix2_h_84_16_8bpp_avx:       76.1 ( 2.32x)
  vp9_loop_filter_mix2_h_88_16_8bpp_c:        184.5
  vp9_loop_filter_mix2_h_88_16_8bpp_sse2:      82.5 ( 2.23x)
  vp9_loop_filter_mix2_h_88_16_8bpp_ssse3:     78.7 ( 2.34x)
  vp9_loop_filter_mix2_h_88_16_8bpp_avx:       74.4 ( 2.48x)
  vp9_loop_filter_mix2_v_44_16_8bpp_c:        176.0
  vp9_loop_filter_mix2_v_44_16_8bpp_sse2:      28.4 ( 6.18x)
  vp9_loop_filter_mix2_v_44_16_8bpp_ssse3:     26.3 ( 6.69x)
  vp9_loop_filter_mix2_v_44_16_8bpp_avx:       26.2 ( 6.72x)
  vp9_loop_filter_mix2_v_48_16_8bpp_c:        188.7
  vp9_loop_filter_mix2_v_48_16_8bpp_sse2:      60.4 ( 3.11x)
  vp9_loop_filter_mix2_v_48_16_8bpp_ssse3:     53.6 ( 3.50x)
  vp9_loop_filter_mix2_v_48_16_8bpp_avx:       51.2 ( 3.64x)
  vp9_loop_filter_mix2_v_84_16_8bpp_c:        191.7
  vp9_loop_filter_mix2_v_84_16_8bpp_sse2:      55.2 ( 3.40x)
  vp9_loop_filter_mix2_v_84_16_8bpp_ssse3:     51.6 ( 3.71x)
  vp9_loop_filter_mix2_v_84_16_8bpp_avx:       50.8 ( 3.77x)
  vp9_loop_filter_mix2_v_88_16_8bpp_c:        201.1
  vp9_loop_filter_mix2_v_88_16_8bpp_sse2:      52.1 ( 3.86x)
  vp9_loop_filter_mix2_v_88_16_8bpp_ssse3:     53.9 ( 3.73x)
  vp9_loop_filter_mix2_v_88_16_8bpp_avx:       51.5 ( 3.90x)
  vp9_loop_filter_v_4_8_8bpp_c:                83.7
  vp9_loop_filter_v_4_8_8bpp_mmxext:           29.7 ( 2.81x)
  vp9_loop_filter_v_8_8_8bpp_c:                93.2
  vp9_loop_filter_v_8_8_8bpp_mmxext:           58.7 ( 1.59x)
  vp9_loop_filter_v_16_8_8bpp_c:              156.5
  vp9_loop_filter_v_16_16_8bpp_c:             292.9
  vp9_loop_filter_v_16_16_8bpp_sse2:          117.8 ( 2.43x)
  vp9_loop_filter_v_16_16_8bpp_ssse3:         116.7 ( 2.45x)
  vp9_loop_filter_v_16_16_8bpp_avx:           104.5 ( 2.78x)

New benchmarks:
  vp9_loop_filter_h_4_8_8bpp_c:                77.5
  vp9_loop_filter_h_4_8_8bpp_mmxext:           54.8 ( 1.41x)
  vp9_loop_filter_h_8_8_8bpp_c:                85.5
  vp9_loop_filter_h_8_8_8bpp_mmxext:           75.0 ( 1.12x)
  vp9_loop_filter_h_16_8_8bpp_c:              139.8
  vp9_loop_filter_h_16_16_8bpp_c:             249.7
  vp9_loop_filter_h_16_16_8bpp_sse2:          154.9 ( 1.54x)
  vp9_loop_filter_h_16_16_8bpp_ssse3:         152.9 ( 1.54x)
  vp9_loop_filter_h_16_16_8bpp_avx:           142.1 ( 1.62x)
  vp9_loop_filter_mix2_h_44_16_8bpp_c:        167.8
  vp9_loop_filter_mix2_h_44_16_8bpp_sse2:      52.3 ( 3.21x)
  vp9_loop_filter_mix2_h_44_16_8bpp_ssse3:     52.7 ( 3.18x)
  vp9_loop_filter_mix2_h_44_16_8bpp_avx:       51.9 ( 3.18x)
  vp9_loop_filter_mix2_h_48_16_8bpp_c:        175.1
  vp9_loop_filter_mix2_h_48_16_8bpp_sse2:      73.2 ( 2.39x)
  vp9_loop_filter_mix2_h_48_16_8bpp_ssse3:     74.9 ( 2.28x)
  vp9_loop_filter_mix2_h_48_16_8bpp_avx:       69.0 ( 2.54x)
  vp9_loop_filter_mix2_h_84_16_8bpp_c:        177.7
  vp9_loop_filter_mix2_h_84_16_8bpp_sse2:      72.6 ( 2.45x)
  vp9_loop_filter_mix2_h_84_16_8bpp_ssse3:     71.3 ( 2.48x)
  vp9_loop_filter_mix2_h_84_16_8bpp_avx:       69.3 ( 2.56x)
  vp9_loop_filter_mix2_h_88_16_8bpp_c:        184.3
  vp9_loop_filter_mix2_h_88_16_8bpp_sse2:      69.6 ( 2.59x)
  vp9_loop_filter_mix2_h_88_16_8bpp_ssse3:     70.2 ( 2.62x)
  vp9_loop_filter_mix2_h_88_16_8bpp_avx:       69.3 ( 2.66x)
  vp9_loop_filter_mix2_v_44_16_8bpp_c:        176.3
  vp9_loop_filter_mix2_v_44_16_8bpp_sse2:      22.0 ( 7.98x)
  vp9_loop_filter_mix2_v_44_16_8bpp_ssse3:     21.4 ( 8.23x)
  vp9_loop_filter_mix2_v_44_16_8bpp_avx:       21.6 ( 8.18x)
  vp9_loop_filter_mix2_v_48_16_8bpp_c:        187.8
  vp9_loop_filter_mix2_v_48_16_8bpp_sse2:      49.9 ( 3.75x)
  vp9_loop_filter_mix2_v_48_16_8bpp_ssse3:     47.3 ( 3.96x)
  vp9_loop_filter_mix2_v_48_16_8bpp_avx:       46.1 ( 4.07x)
  vp9_loop_filter_mix2_v_84_16_8bpp_c:        189.7
  vp9_loop_filter_mix2_v_84_16_8bpp_sse2:      51.2 ( 3.58x)
  vp9_loop_filter_mix2_v_84_16_8bpp_ssse3:     48.4 ( 3.90x)
  vp9_loop_filter_mix2_v_84_16_8bpp_avx:       45.9 ( 4.14x)
  vp9_loop_filter_mix2_v_88_16_8bpp_c:        199.8
  vp9_loop_filter_mix2_v_88_16_8bpp_sse2:      51.2 ( 3.88x)
  vp9_loop_filter_mix2_v_88_16_8bpp_ssse3:     50.5 ( 3.93x)
  vp9_loop_filter_mix2_v_88_16_8bpp_avx:       45.4 ( 4.40x)
  vp9_loop_filter_v_4_8_8bpp_c:                83.3
  vp9_loop_filter_v_4_8_8bpp_mmxext:           23.2 ( 3.58x)
  vp9_loop_filter_v_8_8_8bpp_c:                92.6
  vp9_loop_filter_v_8_8_8bpp_mmxext:           52.5 ( 1.76x)
  vp9_loop_filter_v_16_8_8bpp_c:              154.9
  vp9_loop_filter_v_16_16_8bpp_c:             291.3
  vp9_loop_filter_v_16_16_8bpp_sse2:          104.8 ( 2.68x)
  vp9_loop_filter_v_16_16_8bpp_ssse3:         107.5 ( 2.64x)
  vp9_loop_filter_v_16_16_8bpp_avx:            97.7 ( 2.90x)

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/vp9lpf.asm | 127 +++++++++++++-------------------------
 1 file changed, 44 insertions(+), 83 deletions(-)

diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm
index fd34881014..e4366e8713 100644
--- a/libavcodec/x86/vp9lpf.asm
+++ b/libavcodec/x86/vp9lpf.asm
@@ -219,10 +219,11 @@ SECTION .text
     mova                %5, %1
 %endmacro
 
-%macro SRSHIFT3B_2X 4 ; reg1, reg2, [pb_10], tmp
-    mova                %4, [pb_f8]
-    pand                %1, %4
-    pand                %2, %4
+%macro SRSHIFT3B_2X 3 ; reg1, reg2, tmp
+    mova                %3, [pb_f8]
+    pand                %1, %3
+    pand                %2, %3
+    mova                %3, [pb_10]
     psrlq               %1, 3
     psrlq               %2, 3
     pxor                %1, %3
@@ -771,8 +772,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 
+ %%ext, dst, stride
     ; if (fm) {
     ;     if (out && in) filter_14()
     ;     else if (in)   filter_6()
-    ;     else if (hev)  filter_2()
-    ;     else           filter_4()
+    ;     else           filter_2_4()
     ; }
     ;
     ; f14:                                                                     
       fm &  out &  in
@@ -781,86 +781,49 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     ; f4:  fm & ~f14 & ~f6 & ~f2 => fm & ~(out & in) & ~(~out & in) & ~(~in & 
hev) => fm &  ~in & ~hev
 
     ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m4: pb_80, m8..15: p5 
p4 p1 p0 q0 q1 q6 q7)
-    ; filter2()
-    SWAP 4, 6
-%if %2 != 44 && %2 != 4
-    SCRATCH              2, 15, rsp+%3+%4
+    ; filter2_4()
 %if %2 == 16
     SCRATCH              1,  8, rsp+%3+%4+16
 %endif
-%endif
-    pxor                m2, m6, rq0                     ; q0 ^ 0x80
-    pxor                m4, m6, rp0                     ; p0 ^ 0x80
-    psubsb              m2, m4                          ; (signed) q0 - p0
-    pxor                m4, m6, rp1                     ; p1 ^ 0x80
-    pxor                m5, m6, rq1                     ; q1 ^ 0x80
-    psubsb              m4, m5                          ; (signed) p1 - q1
-    paddsb              m4, m2                          ;   (q0 - p0) + (p1 - 
q1)
-    paddsb              m4, m2                          ; 2*(q0 - p0) + (p1 - 
q1)
-    paddsb              m4, m2                          ; 3*(q0 - p0) + (p1 - 
q1)
-    paddsb              m6, m4, [pb_4]                  ; m6: f1 = clip(f + 4, 
127)
-    paddsb              m4, [pb_3]                      ; m4: f2 = clip(f + 3, 
127)
-%ifdef m8
-    mova                m14, [pb_10]                    ; will be reused in 
filter4()
-%define rb10 m14
-%else
-%define rb10 [pb_10]
-%endif
-    SRSHIFT3B_2X        m6, m4, rb10, m7                ; f1 and f2 sign byte 
shift by 3
-    SIGN_SUB            m7, rq0, m6, m5                 ; m7 = q0 - f1
-    SIGN_ADD            m1, rp0, m4, m5                 ; m1 = p0 + f2
+    pxor                m5, m4, rp1                     ; p1 - 128
+    pxor                m7, m4, rq1                     ; q1 - 128
+    pxor                m6, m4, rq0                     ; q0 - 128
+    psubsb              m5, m7                          ; clip_i8(p1 - q1)
+    pxor                m7, m4, rp0                     ; p0 - 128
+    ; mask so we can treat the !hev and hev cases in parallel
+    pand                m5, m0                          ; hev ? clip_i8(p1 - 
q1) : 0
+    psubsb              m6, m7                          ; clip_i8(q0 - p0)
+    paddsb              m5, m6                          ;   (q0 - p0) + (p1 - 
q1)
+    paddsb              m5, m6                          ; 2*(q0 - p0) + (p1 - 
q1)
+    paddsb              m5, m6                          ; f = 3*(q0 - p0) + 
(p1 - q1)
+    ; zero f unless we are in filter2_4 case to ensure that p0, p1, q0, q1
+    ; are only changed if they should be
 %if %2 != 44 && %2 != 4
-%ifdef m8
-    pandn               m6, m15, m3                     ;  ~mask(in) & mask(fm)
+    pandn               m7, m2, m3
+    pand                m5, m7
 %else
-    mova                m6, [rsp+%3+%4]
-    pandn               m6, m3
+    pand                m5, m3
 %endif
-    pand                m6, m0                          ; (~mask(in) & 
mask(fm)) & mask(hev)
-%else
-    pand                m6, m3, m0
-%endif
-    MASK_APPLY          m7, rq0, m6, m5                 ; m7 = filter2(q0) & 
mask / we write it in filter4()
-    MASK_APPLY          m1, rp0, m6, m5                 ; m1 = filter2(p0) & 
mask / we write it in filter4()
-
-    ; (m0: hev, m1: p0', m2: q0-p0, m3: fm, m7: q0', [m8: flat8out], m10..13: 
p1 p0 q0 q1, m14: pb_10, [m15: flat8in], )
-    ; filter4()
-    paddsb              m4, m2, m2                      ; 2 * (q0 - p0)
-    paddsb              m2, m4                          ; 3 * (q0 - p0)
-    paddsb              m6, m2, [pb_4]                  ; m6:  f1 = clip(f + 
4, 127)
-    paddsb              m2, [pb_3]                      ; m2: f2 = clip(f + 3, 
127)
-    SRSHIFT3B_2X        m6, m2, rb10, m4                ; f1 and f2 sign byte 
shift by 3
-%if %2 != 44 && %2 != 4
-%ifdef m8
-    pandn               m5, m15, m3                     ;               
~mask(in) & mask(fm)
-%else
-    mova                m5, [rsp+%3+%4]
-    pandn               m5, m3
-%endif
-    pandn               m0, m5                          ; ~mask(hev) & 
(~mask(in) & mask(fm))
-%else
-    pandn               m0, m3
-%endif
-    SIGN_SUB            m5, rq0, m6, m4                 ; q0 - f1
-    MASK_APPLY          m5, m7, m0, m4                  ; filter4(q0) & mask
-    mova                [Q0], m5
-    SIGN_ADD            m7, rp0, m2, m4                 ; p0 + f2
-    MASK_APPLY          m7, m1, m0, m4                  ; filter4(p0) & mask
-    mova                [P0], m7
-    paddb               m6, [pb_80]                     ;
-    pxor                m1, m1                          ;   f=(f1+1)>>1
-    pavgb               m6, m1                          ;
-    psubb               m6, [pb_40]                     ;
-    SIGN_ADD            m1, rp1, m6, m2                 ; p1 + f
-    SIGN_SUB            m4, rq1, m6, m2                 ; q1 - f
-    MASK_APPLY          m1, rp1, m0, m2                 ; m1 = filter4(p1)
-    MASK_APPLY          m4, rq1, m0, m2                 ; m4 = filter4(q1)
-    mova                [P1], m1
-    mova                [Q1], m4
-
-%if %2 != 44 && %2 != 4
-    UNSCRATCH            2, 15, rsp+%3+%4
+    paddsb              m6, m5, [pb_4]                  ; m6: f1 = clip(f + 4, 
127)
+    paddsb              m5, [pb_3]                      ; m5: f2 = clip(f + 3, 
127)
+    SRSHIFT3B_2X        m6, m5, m7                      ; f1 and f2 sign byte 
shift by 3
+    pandn               m0, m6                          ; hev ? 0 : f1
+    SIGN_SUB            m7, rq0, m6, m1                 ; m7 = q0 - f1
+    SIGN_ADD            m6, rp0, m5, m1                 ; m6 = p0 + f2
+    mova              [Q0], m7
+    mova              [P0], m6
+    pxor                m0, m4                          ; f1 ^ 0x80
+    pxor                m5, m5
+    pavgb               m0, m5
+    psubb               m0, [pb_40]                     ; (f1 + 1) >> 1
+%if %2 == 44 || %2 == 4
+    SWAP                 1, 6                           ; m1 = p0
+    SWAP                 2, 7                           ; m2 = q0
 %endif
+    SIGN_ADD            m6, rp1, m0, m5                 ; p1 + f
+    SIGN_SUB            m7, rq1, m0, m5                 ; q1 - f
+    mova              [P1], m6
+    mova              [Q1], m7
 
     ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1)
     ; filter6()
@@ -1052,10 +1015,8 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     movhps [Q7],  m7
 %endif
 %elif %2 == 44 || %2 == 4
-    SWAP 0, 1   ; m0 = p1
-    SWAP 1, 7   ; m1 = p0
-    SWAP 2, 5   ; m2 = q0
-    SWAP 3, 4   ; m3 = q1
+    SWAP 0, 6   ; m0 = p1
+    SWAP 3, 7   ; m3 = q1
     DEFINE_REAL_P7_TO_Q7 2
     SBUTTERFLY  bw, 0, 1, 4
     SBUTTERFLY  bw, 2, 3, 4
-- 
2.52.0


>From c821d10fe36704a86268311e26c40bdefe583899 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Thu, 9 Jul 2026 20:06:42 +0200
Subject: [PATCH 8/8] avcodec/x86/vp9lpf: Simplify clip_u8(u8+i8)

Just subtract 128 from u8 to make it signed, use paddsb
and convert back to u8. Saves 2477B of .text here.

Old benchmarks:
  vp9_loop_filter_h_4_8_8bpp_c:                77.5
  vp9_loop_filter_h_4_8_8bpp_mmxext:           54.8 ( 1.41x)
  vp9_loop_filter_h_8_8_8bpp_c:                85.5
  vp9_loop_filter_h_8_8_8bpp_mmxext:           75.0 ( 1.12x)
  vp9_loop_filter_h_16_8_8bpp_c:              139.8
  vp9_loop_filter_h_16_16_8bpp_c:             249.7
  vp9_loop_filter_h_16_16_8bpp_sse2:          154.9 ( 1.54x)
  vp9_loop_filter_h_16_16_8bpp_ssse3:         152.9 ( 1.54x)
  vp9_loop_filter_h_16_16_8bpp_avx:           142.1 ( 1.62x)
  vp9_loop_filter_mix2_h_44_16_8bpp_c:        167.8
  vp9_loop_filter_mix2_h_44_16_8bpp_sse2:      52.3 ( 3.21x)
  vp9_loop_filter_mix2_h_44_16_8bpp_ssse3:     52.7 ( 3.18x)
  vp9_loop_filter_mix2_h_44_16_8bpp_avx:       51.9 ( 3.18x)
  vp9_loop_filter_mix2_h_48_16_8bpp_c:        175.1
  vp9_loop_filter_mix2_h_48_16_8bpp_sse2:      73.2 ( 2.39x)
  vp9_loop_filter_mix2_h_48_16_8bpp_ssse3:     74.9 ( 2.28x)
  vp9_loop_filter_mix2_h_48_16_8bpp_avx:       69.0 ( 2.54x)
  vp9_loop_filter_mix2_h_84_16_8bpp_c:        177.7
  vp9_loop_filter_mix2_h_84_16_8bpp_sse2:      72.6 ( 2.45x)
  vp9_loop_filter_mix2_h_84_16_8bpp_ssse3:     71.3 ( 2.48x)
  vp9_loop_filter_mix2_h_84_16_8bpp_avx:       69.3 ( 2.56x)
  vp9_loop_filter_mix2_h_88_16_8bpp_c:        184.3
  vp9_loop_filter_mix2_h_88_16_8bpp_sse2:      69.6 ( 2.59x)
  vp9_loop_filter_mix2_h_88_16_8bpp_ssse3:     70.2 ( 2.62x)
  vp9_loop_filter_mix2_h_88_16_8bpp_avx:       69.3 ( 2.66x)
  vp9_loop_filter_mix2_v_44_16_8bpp_c:        176.3
  vp9_loop_filter_mix2_v_44_16_8bpp_sse2:      22.0 ( 7.98x)
  vp9_loop_filter_mix2_v_44_16_8bpp_ssse3:     21.4 ( 8.23x)
  vp9_loop_filter_mix2_v_44_16_8bpp_avx:       21.6 ( 8.18x)
  vp9_loop_filter_mix2_v_48_16_8bpp_c:        187.8
  vp9_loop_filter_mix2_v_48_16_8bpp_sse2:      49.9 ( 3.75x)
  vp9_loop_filter_mix2_v_48_16_8bpp_ssse3:     47.3 ( 3.96x)
  vp9_loop_filter_mix2_v_48_16_8bpp_avx:       46.1 ( 4.07x)
  vp9_loop_filter_mix2_v_84_16_8bpp_c:        189.7
  vp9_loop_filter_mix2_v_84_16_8bpp_sse2:      51.2 ( 3.58x)
  vp9_loop_filter_mix2_v_84_16_8bpp_ssse3:     48.4 ( 3.90x)
  vp9_loop_filter_mix2_v_84_16_8bpp_avx:       45.9 ( 4.14x)
  vp9_loop_filter_mix2_v_88_16_8bpp_c:        199.8
  vp9_loop_filter_mix2_v_88_16_8bpp_sse2:      51.2 ( 3.88x)
  vp9_loop_filter_mix2_v_88_16_8bpp_ssse3:     50.5 ( 3.93x)
  vp9_loop_filter_mix2_v_88_16_8bpp_avx:       45.4 ( 4.40x)
  vp9_loop_filter_v_4_8_8bpp_c:                83.3
  vp9_loop_filter_v_4_8_8bpp_mmxext:           23.2 ( 3.58x)
  vp9_loop_filter_v_8_8_8bpp_c:                92.6
  vp9_loop_filter_v_8_8_8bpp_mmxext:           52.5 ( 1.76x)
  vp9_loop_filter_v_16_8_8bpp_c:              154.9
  vp9_loop_filter_v_16_16_8bpp_c:             291.3
  vp9_loop_filter_v_16_16_8bpp_sse2:          104.8 ( 2.68x)
  vp9_loop_filter_v_16_16_8bpp_ssse3:         107.5 ( 2.64x)
  vp9_loop_filter_v_16_16_8bpp_avx:            97.7 ( 2.90x)

New benchmarks:
  vp9_loop_filter_h_4_8_8bpp_c:                77.1
  vp9_loop_filter_h_4_8_8bpp_mmxext:           52.0 ( 1.48x)
  vp9_loop_filter_h_8_8_8bpp_c:                85.6
  vp9_loop_filter_h_8_8_8bpp_mmxext:           73.3 ( 1.17x)
  vp9_loop_filter_h_16_8_8bpp_c:              139.2
  vp9_loop_filter_h_16_16_8bpp_c:             252.4
  vp9_loop_filter_h_16_16_8bpp_sse2:          149.3 ( 1.60x)
  vp9_loop_filter_h_16_16_8bpp_ssse3:         149.3 ( 1.62x)
  vp9_loop_filter_h_16_16_8bpp_avx:           140.2 ( 1.77x)
  vp9_loop_filter_mix2_h_44_16_8bpp_c:        168.5
  vp9_loop_filter_mix2_h_44_16_8bpp_sse2:      48.4 ( 3.48x)
  vp9_loop_filter_mix2_h_44_16_8bpp_ssse3:     49.6 ( 3.39x)
  vp9_loop_filter_mix2_h_44_16_8bpp_avx:       49.0 ( 3.43x)
  vp9_loop_filter_mix2_h_48_16_8bpp_c:        174.8
  vp9_loop_filter_mix2_h_48_16_8bpp_sse2:      66.0 ( 2.65x)
  vp9_loop_filter_mix2_h_48_16_8bpp_ssse3:     64.9 ( 2.69x)
  vp9_loop_filter_mix2_h_48_16_8bpp_avx:       64.6 ( 2.65x)
  vp9_loop_filter_mix2_h_84_16_8bpp_c:        177.6
  vp9_loop_filter_mix2_h_84_16_8bpp_sse2:      70.5 ( 2.51x)
  vp9_loop_filter_mix2_h_84_16_8bpp_ssse3:     66.8 ( 2.65x)
  vp9_loop_filter_mix2_h_84_16_8bpp_avx:       66.3 ( 2.68x)
  vp9_loop_filter_mix2_h_88_16_8bpp_c:        185.6
  vp9_loop_filter_mix2_h_88_16_8bpp_sse2:      72.1 ( 2.50x)
  vp9_loop_filter_mix2_h_88_16_8bpp_ssse3:     70.7 ( 2.54x)
  vp9_loop_filter_mix2_h_88_16_8bpp_avx:       65.5 ( 2.83x)
  vp9_loop_filter_mix2_v_44_16_8bpp_c:        175.9
  vp9_loop_filter_mix2_v_44_16_8bpp_sse2:      19.2 ( 9.17x)
  vp9_loop_filter_mix2_v_44_16_8bpp_ssse3:     19.2 ( 9.16x)
  vp9_loop_filter_mix2_v_44_16_8bpp_avx:       19.1 ( 9.18x)
  vp9_loop_filter_mix2_v_48_16_8bpp_c:        186.9
  vp9_loop_filter_mix2_v_48_16_8bpp_sse2:      49.6 ( 3.73x)
  vp9_loop_filter_mix2_v_48_16_8bpp_ssse3:     47.7 ( 3.89x)
  vp9_loop_filter_mix2_v_48_16_8bpp_avx:       43.6 ( 4.28x)
  vp9_loop_filter_mix2_v_84_16_8bpp_c:        189.1
  vp9_loop_filter_mix2_v_84_16_8bpp_sse2:      45.8 ( 4.12x)
  vp9_loop_filter_mix2_v_84_16_8bpp_ssse3:     46.6 ( 4.05x)
  vp9_loop_filter_mix2_v_84_16_8bpp_avx:       43.0 ( 4.27x)
  vp9_loop_filter_mix2_v_88_16_8bpp_c:        198.6
  vp9_loop_filter_mix2_v_88_16_8bpp_sse2:      43.5 ( 4.57x)
  vp9_loop_filter_mix2_v_88_16_8bpp_ssse3:     43.3 ( 4.57x)
  vp9_loop_filter_mix2_v_88_16_8bpp_avx:       43.0 ( 4.62x)
  vp9_loop_filter_v_4_8_8bpp_c:                83.2
  vp9_loop_filter_v_4_8_8bpp_mmxext:           21.8 ( 3.81x)
  vp9_loop_filter_v_8_8_8bpp_c:                92.3
  vp9_loop_filter_v_8_8_8bpp_mmxext:           51.5 ( 1.79x)
  vp9_loop_filter_v_16_8_8bpp_c:              155.6
  vp9_loop_filter_v_16_16_8bpp_c:             290.3
  vp9_loop_filter_v_16_16_8bpp_sse2:          105.1 ( 2.68x)
  vp9_loop_filter_v_16_16_8bpp_ssse3:         103.8 ( 2.72x)
  vp9_loop_filter_v_16_16_8bpp_avx:            97.7 ( 2.86x)

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/vp9lpf.asm | 51 +++++++++++++++------------------------
 1 file changed, 20 insertions(+), 31 deletions(-)

diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm
index e4366e8713..13a3530b19 100644
--- a/libavcodec/x86/vp9lpf.asm
+++ b/libavcodec/x86/vp9lpf.asm
@@ -232,27 +232,18 @@ SECTION .text
     psubb               %2, %3
 %endmacro
 
-%macro EXTRACT_POS_NEG 3 ; i8, neg, pos
-    pxor                %3, %3
-    pxor                %2, %2
-    pcmpgtb             %3, %1                          ; i8 < 0 mask
-    psubb               %2, %1                          ; neg values (only the 
originally - will be kept)
-    pand                %2, %3                          ; negative values of 
i8 (but stored as +)
-    pandn               %3, %1                          ; positive values of i8
-%endmacro
-
-; clip_u8(u8 + i8)
-%macro SIGN_ADD 4 ; dst, u8, i8, tmp1
-    EXTRACT_POS_NEG     %3, %4, %1
-    paddusb             %1, %2                          ; add the positives
-    psubusb             %1, %4                          ; sub the negatives
-%endmacro
-
-; clip_u8(u8 - i8)
-%macro SIGN_SUB 4 ; dst, u8, i8, tmp1
-    EXTRACT_POS_NEG     %3, %1, %4
-    paddusb             %1, %2                          ; add the negatives
-    psubusb             %1, %4                          ; sub the positives
+%macro ADD_SUB_CLIP 8; dst0, dst1, u8_0, u8_1, i8_0, i8_1, pb_80, tmp
+    pxor                m%8, %7, %3
+    paddsb              m%1, m%5, m%8
+    pxor                m%8, %7, %4
+%if avx_enabled
+    psubsb              m%2, m%8, m%6
+%else
+    psubsb              m%8, m%6
+    SWAP                %2, %8
+%endif
+    pxor                m%1, %7
+    pxor                m%2, %7
 %endmacro
 
 %macro FILTER6_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off
@@ -808,20 +799,18 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + 
%4 + %%ext, dst, stride
     paddsb              m5, [pb_3]                      ; m5: f2 = clip(f + 3, 
127)
     SRSHIFT3B_2X        m6, m5, m7                      ; f1 and f2 sign byte 
shift by 3
     pandn               m0, m6                          ; hev ? 0 : f1
-    SIGN_SUB            m7, rq0, m6, m1                 ; m7 = q0 - f1
-    SIGN_ADD            m6, rp0, m5, m1                 ; m6 = p0 + f2
-    mova              [Q0], m7
-    mova              [P0], m6
+    ADD_SUB_CLIP         5, 6, rp0, rq0, 5, 6, m4, 7    ; m5 = p0 + f2, m6 = 
q0 - f1
+    mova              [Q0], m6
+    mova              [P0], m5
     pxor                m0, m4                          ; f1 ^ 0x80
-    pxor                m5, m5
-    pavgb               m0, m5
+    pxor                m7, m7
+    pavgb               m0, m7
     psubb               m0, [pb_40]                     ; (f1 + 1) >> 1
 %if %2 == 44 || %2 == 4
-    SWAP                 1, 6                           ; m1 = p0
-    SWAP                 2, 7                           ; m2 = q0
+    SWAP                 1, 5                           ; m1 = p0
+    SWAP                 2, 6                           ; m2 = q0
 %endif
-    SIGN_ADD            m6, rp1, m0, m5                 ; p1 + f
-    SIGN_SUB            m7, rq1, m0, m5                 ; q1 - f
+    ADD_SUB_CLIP         6, 7, rp1, rq1, 0, 0, m4, 5    ; m6 = p1 + f, m7 = q1 
- f
     mova              [P1], m6
     mova              [Q1], m7
 
-- 
2.52.0

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

Reply via email to