shithub: dav1d

Download patch

ref: 713aa34c421726719a2e9676ba2d0d5af99512bf
parent: 0ed3ad192c81b671a79148c0f697634c0f2355cb
author: Martin Storsjö <martin@martin.st>
date: Sat Sep 28 19:37:25 EDT 2019

arm64: itx: Fix overflows in idct

Don't add two 16 bit coefficients in 16 bit, if the result isn't supposed
to be clipped.

This fixes mismatches for some samples, see issue #299.

Before:                                Cortex A53       A72       A73
inv_txfm_add_4x4_dct_dct_1_8bpc_neon:        93.0      52.8      49.5
inv_txfm_add_8x8_dct_dct_1_8bpc_neon:       260.0     186.0     196.4
inv_txfm_add_16x16_dct_dct_2_8bpc_neon:    1371.0     953.4    1028.6
inv_txfm_add_32x32_dct_dct_4_8bpc_neon:    7363.2    4887.5    5135.8
inv_txfm_add_64x64_dct_dct_4_8bpc_neon:   25029.0   17492.3   18404.5
After:
inv_txfm_add_4x4_dct_dct_1_8bpc_neon:       105.0      58.7      55.2
inv_txfm_add_8x8_dct_dct_1_8bpc_neon:       294.0     211.5     209.9
inv_txfm_add_16x16_dct_dct_2_8bpc_neon:    1495.8    1050.4    1070.6
inv_txfm_add_32x32_dct_dct_4_8bpc_neon:    7866.7    5197.8    5321.4
inv_txfm_add_64x64_dct_dct_4_8bpc_neon:   25807.2   18619.3   18526.9

--- a/src/arm/64/itx.S
+++ b/src/arm/64/itx.S
@@ -468,18 +468,18 @@
 .endm
 
 .macro idct_4 r0, r1, r2, r3, sz
-        add             v2\sz,   \r0\sz,  \r2\sz
-        sub             v3\sz,   \r0\sz,  \r2\sz
         smull_smlal     v6,  v7,  \r1, \r3, v0.h[3], v0.h[2], \sz
         smull_smlsl     v4,  v5,  \r1, \r3, v0.h[2], v0.h[3], \sz
-        sqrdmulh        v2\sz,   v2\sz,  v0.h[1]
-        sqrdmulh        v3\sz,   v3\sz,  v0.h[1]
+        smull_smlal     v2,  v3,  \r0, \r2, v0.h[0], v0.h[0], \sz
         rshrn_sz        v6,  v6,  v7,  #12, \sz
-        rshrn_sz        v4,  v4,  v5,  #12, \sz
+        rshrn_sz        v7,  v4,  v5,  #12, \sz
+        smull_smlsl     v4,  v5,  \r0, \r2, v0.h[0], v0.h[0], \sz
+        rshrn_sz        v2,  v2,  v3,  #12, \sz
+        rshrn_sz        v3,  v4,  v5,  #12, \sz
         sqadd           \r0\sz,  v2\sz,   v6\sz
         sqsub           \r3\sz,  v2\sz,   v6\sz
-        sqadd           \r1\sz,  v3\sz,   v4\sz
-        sqsub           \r2\sz,  v3\sz,   v4\sz
+        sqadd           \r1\sz,  v3\sz,   v7\sz
+        sqsub           \r2\sz,  v3\sz,   v7\sz
 .endm
 
 function inv_dct_4x4_neon
@@ -759,12 +759,11 @@
         sqadd           v3\sz,   \r7\sz,  \r5\sz // t7
         sqsub           \r3\sz,  \r7\sz,  \r5\sz // t6a
 
-        sub             \r5\sz,  \r3\sz,  \r1\sz // -> t5
-        add             \r7\sz,  \r3\sz,  \r1\sz // -> t6
+        smull_smlsl     v4,  v5,  \r3, \r1, v0.h[0], v0.h[0], \sz // -> t5
+        smull_smlal     v6,  v7,  \r3, \r1, v0.h[0], v0.h[0], \sz // -> t6
+        rshrn_sz        v4,  v4,  v5,  #12, \sz // t5
+        rshrn_sz        v5,  v6,  v7,  #12, \sz // t6
 
-        sqrdmulh        v4\sz,   \r5\sz, v0.h[1] // t5
-        sqrdmulh        v5\sz,   \r7\sz, v0.h[1] // t6
-
         sqsub           \r7\sz,  \r0\sz,  v3\sz // out7
         sqadd           \r0\sz,  \r0\sz,  v3\sz // out0
         sqadd           \r1\sz,  \r2\sz,  v5\sz // out1
@@ -1098,15 +1097,16 @@
         sqsub           v25\sz,  v27\sz,  v29\sz  // t13
         sqadd           v27\sz,  v27\sz,  v29\sz  // t14
 
-        sub             v23\sz,  v3\sz,   v2\sz     // -> t11
-        add             v29\sz,  v3\sz,   v2\sz     // -> t12
-        sub             v6\sz,   v25\sz,  v21\sz    // -> t10a
-        add             v7\sz,   v25\sz,  v21\sz    // -> t13a
-        sqrdmulh        v2\sz,   v23\sz,  v0.h[1]   // t11
-        sqrdmulh        v3\sz,   v29\sz,  v0.h[1]   // t12
-        sqrdmulh        v4\sz,   v6\sz,   v0.h[1]   // t10a
-        sqrdmulh        v5\sz,   v7\sz,   v0.h[1]   // t13a
+        smull_smlsl     v4,  v5,  v3,  v2,  v0.h[0], v0.h[0], \sz // -> t11
+        smull_smlal     v6,  v7,  v3,  v2,  v0.h[0], v0.h[0], \sz // -> t12
+        smull_smlsl     v2,  v3,  v25, v21, v0.h[0], v0.h[0], \sz // -> t10a
 
+        rshrn_sz        v4,  v4,  v5,  #12, \sz   // t11
+        rshrn_sz        v5,  v6,  v7,  #12, \sz   // t12
+        smull_smlal     v6,  v7,  v25, v21, v0.h[0], v0.h[0], \sz // -> t10a
+        rshrn_sz        v2,  v2,  v3,  #12, \sz   // t10a
+        rshrn_sz        v3,  v6,  v7,  #12, \sz   // t13a
+
         sqadd           v6\sz,   v16\sz,  v31\sz  // out0
         sqsub           v31\sz,  v16\sz,  v31\sz  // out15
         mov             v16\szb, v6\szb
@@ -1114,18 +1114,18 @@
         sqsub           v7\sz,   v30\sz,  v17\sz  // out8
         sqadd           v17\sz,  v18\sz,  v27\sz  // out1
         sqsub           v30\sz,  v18\sz,  v27\sz  // out14
-        sqadd           v18\sz,  v20\sz,  v5\sz   // out2
-        sqsub           v29\sz,  v20\sz,  v5\sz   // out13
-        sqadd           v5\sz,   v28\sz,  v19\sz  // out6
+        sqadd           v18\sz,  v20\sz,  v3\sz   // out2
+        sqsub           v29\sz,  v20\sz,  v3\sz   // out13
+        sqadd           v3\sz,   v28\sz,  v19\sz  // out6
         sqsub           v25\sz,  v28\sz,  v19\sz  // out9
-        sqadd           v19\sz,  v22\sz,  v3\sz   // out3
-        sqsub           v28\sz,  v22\sz,  v3\sz   // out12
-        sqadd           v20\sz,  v24\sz,  v2\sz   // out4
-        sqsub           v27\sz,  v24\sz,  v2\sz   // out11
-        sqadd           v21\sz,  v26\sz,  v4\sz   // out5
-        sqsub           v26\sz,  v26\sz,  v4\sz   // out10
+        sqadd           v19\sz,  v22\sz,  v5\sz   // out3
+        sqsub           v28\sz,  v22\sz,  v5\sz   // out12
+        sqadd           v20\sz,  v24\sz,  v4\sz   // out4
+        sqsub           v27\sz,  v24\sz,  v4\sz   // out11
+        sqadd           v21\sz,  v26\sz,  v2\sz   // out5
+        sqsub           v26\sz,  v26\sz,  v2\sz   // out10
         mov             v24\szb, v7\szb
-        mov             v22\szb, v5\szb
+        mov             v22\szb, v3\szb
 .endm
 
 function inv_dct_8x16_neon
@@ -1874,22 +1874,26 @@
         sqsub           v24.8h,  v24.8h,  v19.8h // t27a
         mov             v19.16b, v4.16b          // out19
 
-        sub             v20.8h,  v24.8h,  v26.8h    // -> t20
-        add             v4.8h,   v24.8h,  v26.8h    // -> t27
-        sub             v5.8h,   v25.8h,  v27.8h    // -> t21a
-        add             v26.8h,  v25.8h,  v27.8h    // -> t26a
-        sqrdmulh        v20.8h,  v20.8h,  v0.h[1]   // t20 = out20
-        sqrdmulh        v27.8h,  v4.8h,   v0.h[1]   // t27 = out27
-        sub             v22.8h,  v21.8h,  v23.8h    // -> t22
-        add             v25.8h,  v21.8h,  v23.8h    // -> t25
-        sqrdmulh        v21.8h,  v5.8h,   v0.h[1]   // t21a = out21
-        sqrdmulh        v26.8h,  v26.8h,  v0.h[1]   // t26a = out26
-        sub             v23.8h,  v3.8h,   v2.8h     // -> t23a
-        add             v24.8h,  v3.8h,   v2.8h     // -> t24a
-        sqrdmulh        v22.8h,  v22.8h,  v0.h[1]   // t22 = out22
-        sqrdmulh        v25.8h,  v25.8h,  v0.h[1]   // t25 = out25
-        sqrdmulh        v23.8h,  v23.8h,  v0.h[1]   // t23a = out23
-        sqrdmulh        v24.8h,  v24.8h,  v0.h[1]   // t24a = out24
+        smull_smlsl     v4,  v5,  v24, v26, v0.h[0], v0.h[0], .8h // -> t20
+        smull_smlal     v6,  v7,  v24, v26, v0.h[0], v0.h[0], .8h // -> t27
+        rshrn_sz        v20, v4,  v5,  #12, .8h   // t20
+        rshrn_sz        v22, v6,  v7,  #12, .8h   // t27
+
+        smull_smlal     v4,  v5,  v25, v27, v0.h[0], v0.h[0], .8h // -> t26a
+        smull_smlsl     v6,  v7,  v25, v27, v0.h[0], v0.h[0], .8h // -> t21a
+        mov             v27.16b,  v22.16b         // t27
+        rshrn_sz        v26, v4,  v5,  #12, .8h   // t26a
+
+        smull_smlsl     v24, v25, v21, v23, v0.h[0], v0.h[0], .8h // -> t22
+        smull_smlal     v4,  v5,  v21, v23, v0.h[0], v0.h[0], .8h // -> t25
+        rshrn_sz        v21, v6,  v7,  #12, .8h   // t21a
+        rshrn_sz        v22, v24, v25, #12, .8h   // t22
+        rshrn_sz        v25, v4,  v5,  #12, .8h   // t25
+
+        smull_smlsl     v4,  v5,  v3,  v2,  v0.h[0], v0.h[0], .8h // -> t23a
+        smull_smlal     v6,  v7,  v3,  v2,  v0.h[0], v0.h[0], .8h // -> t24a
+        rshrn_sz        v23, v4,  v5,  #12, .8h   // t23a
+        rshrn_sz        v24, v6,  v7,  #12, .8h   // t24a
 
         ret
 endfunc