PR #22792 opened by i-Amogh
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22792
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22792.patch

Adds FATE test coverage for softfloat_ieee754.h that validates all public API 
functions using av_assert0() for fail fast behaviour, matching the pattern 
established by fate-integer.

Tests added:

- Integer conversion - roundtrip for ±1 through ±100, plus fractional exponents
- IEEE 754 bit roundtrip - 9 representative bit patterns (1.0, -1.0, 0.5, 2.0, 
0.0, -0.0, 3.0, 4.0, -2.0)
- Multiplication - including large exponents (2¹⁰ × 2⁵ = 32768), large values 
(100 × 100), and negative
- sign handling
- Division - exact quotients and negative operands
- Comparison - equality for same/different representations, inequality, 
negatives
- Normalization - including FLOAT_0 and FLOAT_1 constant validation
- Arithmetic consistency - 50 × 50 matrix of multiplication and power of 2 
division results

Coverage: 0% -> 100% Line, 100% Function for libavutil/softfloat_ieee754.h.


From 849882e327eefaa2ee3909e0e3341dbcf4c82ddd Mon Sep 17 00:00:00 2001
From: i-Amogh <[email protected]>
Date: Sun, 12 Apr 2026 01:42:19 +0530
Subject: [PATCH] lavu/tests: Add FATE tests for libavutil/softfloat_ieee754.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Tested all public functions softfloat_ieee754, which are used by the ALS 
decoder for floating point sample data processing.

The test validates:
 - av_int2sf_ieee754 integer roundtrip conversion
 - av_int2sf_ieee754 with fractional exponents
 - av_bits2sf_ieee754 IEEE 754 bit pattern roundtrip
 - av_mul_sf_ieee754 including negative operands
 - av_div_sf_ieee754 for exact quotients
 - av_cmp_sf_ieee754 equality
 - av_normalize_sf_ieee754
 - Arithmetic consistency over a 50×50 multiplication/division matrix

Signed-off-by: i-Amogh <[email protected]>
---
 libavutil/Makefile                  |   1 +
 libavutil/tests/softfloat_ieee754.c | 167 ++++++++++++++++++++++++++++
 tests/fate/libavutil.mak            |   5 +
 3 files changed, 173 insertions(+)
 create mode 100644 libavutil/tests/softfloat_ieee754.c

diff --git a/libavutil/Makefile b/libavutil/Makefile
index ff166cc81a..c6eb8786ba 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -301,6 +301,7 @@ TESTPROGS = adler32                                         
            \
             sha512                                                      \
             side_data_array                                             \
             softfloat                                                   \
+            softfloat_ieee754                                           \
             stereo3d                                                    \
             tree                                                        \
             twofish                                                     \
diff --git a/libavutil/tests/softfloat_ieee754.c 
b/libavutil/tests/softfloat_ieee754.c
new file mode 100644
index 0000000000..f0823ae007
--- /dev/null
+++ b/libavutil/tests/softfloat_ieee754.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2026 Amogh Kumar Sinha
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/softfloat_ieee754.h"
+
+static uint64_t full_mantissa(SoftFloat_IEEE754 sf)
+{
+    if (sf.mant == 0 && sf.exp == -126)
+        return 0;
+    return sf.mant | 0x00800000UL;
+}
+
+static int sf_to_int(SoftFloat_IEEE754 sf)
+{
+    if (sf.mant == 0 && sf.exp == -126)
+        return 0;
+
+    uint64_t mant = full_mantissa(sf);
+    int exp = sf.exp - 23;
+
+    if (exp >= 0)
+        return sf.sign ? -(int)(mant << exp) : (int)(mant << exp);
+    else
+        return sf.sign ? -(int)(mant >> (-exp)) : (int)(mant >> (-exp));
+}
+
+static uint32_t sf_to_bits(SoftFloat_IEEE754 sf)
+{
+    return ((uint32_t)sf.sign << 31) |
+           (((uint32_t)(uint8_t)sf.exp) << 23) |
+           ((uint32_t)sf.mant & 0x7FFFFFUL);
+}
+
+int main(void)
+{
+    SoftFloat_IEEE754 sf;
+    int i, j;
+
+    for (i = 1; i <= 100; i++) {
+        sf = av_int2sf_ieee754(i, 0);
+        av_assert0(sf_to_int(sf) == i);
+    }
+
+    for (i = 1; i <= 100; i++) {
+        sf = av_int2sf_ieee754(-i, 0);
+        av_assert0(sf_to_int(sf) == -i);
+    }
+
+    sf = av_int2sf_ieee754(1, 10);
+    av_assert0(sf_to_int(sf) == 1024);
+
+    sf = av_int2sf_ieee754(3, 8);
+    av_assert0(sf_to_int(sf) == 768);
+
+    sf = av_int2sf_ieee754(5, -1);
+    av_assert0(sf_to_int(sf) == 2);
+
+    {
+        uint32_t test_values[] = {
+            0x3F800000UL,
+            0xBF800000UL,
+            0x3F000000UL,
+            0x40000000UL,
+            0x00000000UL,
+            0x80000000UL,
+            0x40400000UL,
+            0x40800000UL,
+            0xC0000000UL,
+        };
+        size_t k;
+        for (k = 0; k < sizeof(test_values) / sizeof(test_values[0]); k++) {
+            sf = av_bits2sf_ieee754(test_values[k]);
+            av_assert0(sf_to_bits(sf) == test_values[k]);
+        }
+    }
+
+    sf = av_mul_sf_ieee754(av_int2sf_ieee754(5, 0), av_int2sf_ieee754(3, 0));
+    av_assert0(sf_to_int(sf) == 15);
+
+    sf = av_mul_sf_ieee754(av_int2sf_ieee754(1, 10), av_int2sf_ieee754(1, 5));
+    av_assert0(sf_to_int(sf) == 32768);
+
+    sf = av_mul_sf_ieee754(av_int2sf_ieee754(100, 0), av_int2sf_ieee754(100, 
0));
+    av_assert0(sf_to_int(sf) == 10000);
+
+    sf = av_mul_sf_ieee754(av_int2sf_ieee754(-5, 0), av_int2sf_ieee754(3, 0));
+    av_assert0(sf_to_int(sf) == -15);
+
+    sf = av_mul_sf_ieee754(av_int2sf_ieee754(-5, 0), av_int2sf_ieee754(-3, 0));
+    av_assert0(sf_to_int(sf) == 15);
+
+    sf = av_div_sf_ieee754(av_int2sf_ieee754(6, 0), av_int2sf_ieee754(2, 0));
+    av_assert0(sf_to_int(sf) == 3);
+
+    sf = av_div_sf_ieee754(av_int2sf_ieee754(100, 0), av_int2sf_ieee754(4, 0));
+    av_assert0(sf_to_int(sf) == 25);
+
+    sf = av_div_sf_ieee754(av_int2sf_ieee754(-15, 0), av_int2sf_ieee754(3, 0));
+    av_assert0(sf_to_int(sf) == -5);
+
+    sf = av_div_sf_ieee754(av_int2sf_ieee754(1, 0), av_int2sf_ieee754(1, 0));
+    av_assert0(sf_to_int(sf) == 1);
+
+    sf = av_int2sf_ieee754(42, 0);
+    av_assert0(av_cmp_sf_ieee754(sf, av_int2sf_ieee754(42, 0)));
+
+    sf = av_int2sf_ieee754(2, 0);
+    av_assert0(!av_cmp_sf_ieee754(sf, av_int2sf_ieee754(3, 0)));
+
+    av_assert0(av_cmp_sf_ieee754(av_int2sf_ieee754(1, 0), av_int2sf_ieee754(2, 
-1)));
+
+    sf = av_int2sf_ieee754(-5, 0);
+    av_assert0(av_cmp_sf_ieee754(sf, av_int2sf_ieee754(-5, 0)));
+
+    av_assert0(FLOAT_0.mant == 0);
+    av_assert0(FLOAT_0.exp == -126);
+    av_assert0(FLOAT_0.sign == 0);
+
+    av_assert0(FLOAT_1.mant == 0);
+    av_assert0(FLOAT_1.exp == 0);
+    av_assert0(FLOAT_1.sign == 0);
+
+    sf = av_normalize_sf_ieee754(av_int2sf_ieee754(42, 0));
+    av_assert0(sf_to_int(sf) == 42);
+
+    sf = av_normalize_sf_ieee754(FLOAT_0);
+    av_assert0(sf_to_int(sf) == 0);
+
+    for (i = 1; i <= 50; i++) {
+        for (j = 1; j <= 50; j++) {
+            SoftFloat_IEEE754 a = av_int2sf_ieee754(i, 0);
+            SoftFloat_IEEE754 b = av_int2sf_ieee754(j, 0);
+            SoftFloat_IEEE754 mul_result = av_mul_sf_ieee754(a, b);
+            av_assert0(sf_to_int(mul_result) == i * j);
+
+            if ((i % j) == 0) {
+                int expected = i / j;
+                if ((expected & (expected - 1)) == 0) {
+                    SoftFloat_IEEE754 div_result = av_div_sf_ieee754(a, b);
+                    av_assert0(sf_to_int(div_result) == expected);
+                }
+            }
+        }
+    }
+
+    return 0;
+}
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index d69a4de863..0c4a47aa64 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -152,6 +152,11 @@ FATE_LIBAVUTIL += fate-sha512
 fate-sha512: libavutil/tests/sha512$(EXESUF)
 fate-sha512: CMD = run libavutil/tests/sha512$(EXESUF)
 
+FATE_LIBAVUTIL += fate-softfloat_ieee754
+fate-softfloat_ieee754: libavutil/tests/softfloat_ieee754$(EXESUF)
+fate-softfloat_ieee754: CMD = run libavutil/tests/softfloat_ieee754$(EXESUF)
+fate-softfloat_ieee754: CMP = null
+
 FATE_LIBAVUTIL += fate-side_data_array
 fate-side_data_array: libavutil/tests/side_data_array$(EXESUF)
 fate-side_data_array: CMD = run libavutil/tests/side_data_array$(EXESUF)
-- 
2.52.0

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

Reply via email to