From 1358b843146958d606251659a93c5fce0ee49856 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 3 Apr 2026 23:24:35 +0200 Subject: [PATCH 1/4] increase precision of the return value from maxWithSign() from float to double --- lib_dec/ivas_svd_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 9ed74b000..c2568f8df 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -76,7 +76,7 @@ static void ApplyQRTransform( float singularVectors_Left[][MAX_OUTPUT_CHANNELS], static void ApplyRotation( float singularVector[][MAX_OUTPUT_CHANNELS], const float c, const float s, float x11, float x12, float *f, float *g, const int16_t currentIndex1, const int16_t currentIndex2, const int16_t nChannels ); -static float maxWithSign( const float a ); +static double maxWithSign( const float a ); static void flushToZeroArray( float arr[MAX_OUTPUT_CHANNELS], const int16_t length ); @@ -810,7 +810,7 @@ static float GivensRotation( * *-------------------------------------------------------------------------*/ -static float maxWithSign( +static double maxWithSign( const float a ) { if ( fabsf( a ) > SVD_MINIMUM_VALUE ) -- GitLab From 3e30c20287e0fa8df092518192689aea147d3a38 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Sat, 4 Apr 2026 13:06:43 +0200 Subject: [PATCH 2/4] SVD: Avoid optimizing the division on the result of maxWithSign() with -funsafe-math-optimizations; see float issue #1560 --- lib_com/options.h | 1 + lib_dec/ivas_svd_dec.c | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 7362c39a9..d54cf69ff 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -166,6 +166,7 @@ #define FIX_FLOAT_1544_SBA_META_IMPRECISION_UNSAFE_MATH /* FhG: float issue 1544: imprecision in ivas_get_dirac_sba_max_md_bits() with -funsafe-math-optimizations */ #define FIX_FLOAT_1544_ITD_IMPRECISION_UNSAFE_MATH /* FhG: float issue 1544: Avoid assert() with -funsafe-math-optimizations in stereo_td_itd() */ #define FIX_FLOAT_1539_G192_FORMAT_SWITCH /* Nokia: reintroduce format switching for g192 bitstreams */ +#define FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN /* FhG: float issue 1560: Avoid optimizing the division on the result of maxWithSign() with -funsafe-math-optimizations */ /* #################### End BE switches ################################## */ diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index c2568f8df..6ae362365 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -76,7 +76,7 @@ static void ApplyQRTransform( float singularVectors_Left[][MAX_OUTPUT_CHANNELS], static void ApplyRotation( float singularVector[][MAX_OUTPUT_CHANNELS], const float c, const float s, float x11, float x12, float *f, float *g, const int16_t currentIndex1, const int16_t currentIndex2, const int16_t nChannels ); -static double maxWithSign( const float a ); +static float maxWithSign( const float a ); static void flushToZeroArray( float arr[MAX_OUTPUT_CHANNELS], const int16_t length ); @@ -272,7 +272,12 @@ static int16_t BidagonalDiagonalisation( ) { int16_t kCh, nCh, iCh, jCh, split; +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + volatile float c, s; + float f1, f2; +#else float c, s, f1, f2; +#endif float g = 0.0f; int16_t convergence, iteration, found_split; int16_t error = 0; @@ -385,9 +390,14 @@ static void ApplyQRTransform( ) { int16_t ch, split; +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + float d = 0.0f, g = 0.0f, r = 0.0f, x_ii = 0.0f, x_split = 0.0f, x_kk = 0.0f, aux = 0.0f; + volatile float mu = 0.0f, c = 1.0f, s = 1.0f; +#else float d = 0.0f, g = 0.0f, r = 0.0f, x_ii = 0.0f, x_split = 0.0f, x_kk = 0.0f, mu = 0.0f, aux = 0.0f; float c = 1.0f; float s = 1.0f; +#endif x_kk = singularValues[currentIndex]; x_ii = singularValues[startIndex]; @@ -525,7 +535,12 @@ static void biDiagonalReductionLeft( float *g ) { int16_t iCh, jCh; +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + float norm_x, r; + volatile float f; +#else float norm_x, f, r; +#endif /* Setting values to 0 */ ( *g ) = 0.0f; @@ -638,7 +653,12 @@ static void singularVectorsAccumulationLeft( { int16_t nCh, iCh, k; int16_t nChannels; +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + float norm_y; + volatile float t_jj, t_ii; +#else float norm_y, t_jj, t_ii; +#endif /* Processing */ nChannels = min( nChannelsL, nChannelsC ); /* min(nChannelsL,ChannelsC) */ @@ -706,7 +726,12 @@ static void singularVectorsAccumulationRight( { int16_t nCh, iCh, k; int16_t nChannels; +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + float norm_y, t_ii; + volatile float ratio; +#else float norm_y, t_ii, ratio; +#endif /* Processing */ nChannels = nChannelsC; /* nChannelsC */ @@ -810,7 +835,7 @@ static float GivensRotation( * *-------------------------------------------------------------------------*/ -static double maxWithSign( +static float maxWithSign( const float a ) { if ( fabsf( a ) > SVD_MINIMUM_VALUE ) -- GitLab From 4b6113cc672a9b7ed9ce71a6d7d1a004c56b617b Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Sun, 12 Apr 2026 21:12:46 +0200 Subject: [PATCH 3/4] make SVD more robust to optimizations --- lib_dec/ivas_svd_dec.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 6ae362365..8e29e82b6 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -536,14 +536,19 @@ static void biDiagonalReductionLeft( { int16_t iCh, jCh; #ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN - float norm_x, r; + volatile float norm_x, r; volatile float f; + volatile float g_loc; #else float norm_x, f, r; #endif /* Setting values to 0 */ +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + g_loc = 0.0f; +#else ( *g ) = 0.0f; +#endif if ( currChannel < nChannelsL ) /* i <= m */ { @@ -556,9 +561,15 @@ static void biDiagonalReductionLeft( if ( ( norm_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ { +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + g_loc = -( singularVectors[currChannel][currChannel] >= 0 ? 1 : ( -1 ) ) * sqrtf( norm_x ); + r = g_loc * singularVectors[currChannel][currChannel] - norm_x; + singularVectors[currChannel][currChannel] = ( singularVectors[currChannel][currChannel] - g_loc ); +#else ( *g ) = -( singularVectors[currChannel][currChannel] >= 0 ? 1 : ( -1 ) ) * sqrtf( norm_x ); r = ( *g ) * singularVectors[currChannel][currChannel] - norm_x; singularVectors[currChannel][currChannel] = ( singularVectors[currChannel][currChannel] - ( *g ) ); +#endif for ( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ { @@ -579,6 +590,10 @@ static void biDiagonalReductionLeft( } } +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + *g = g_loc; +#endif + return; } @@ -597,10 +612,17 @@ static void biDiagonalReductionRight( float *g ) { int16_t iCh, jCh, idx; - float norm_x, r; +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + volatile float norm_x, r; + volatile float g_loc; +#endif /* Setting values to 0 */ +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + g_loc = 0.0f; +#else ( *g ) = 0.0f; +#endif if ( currChannel < nChannelsL && currChannel != ( nChannelsC - 1 ) ) /* i <=m && i !=n */ { @@ -615,9 +637,15 @@ static void biDiagonalReductionRight( if ( norm_x ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ { +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + g_loc = -( singularVectors[currChannel][idx] >= 0 ? 1 : ( -1 ) ) * sqrtf( norm_x ); + r = g_loc * singularVectors[currChannel][idx] - norm_x; + singularVectors[currChannel][idx] = ( singularVectors[currChannel][idx] - g_loc ); +#else ( *g ) = -( singularVectors[currChannel][idx] >= 0 ? 1 : ( -1 ) ) * sqrtf( norm_x ); r = ( *g ) * singularVectors[currChannel][idx] - norm_x; singularVectors[currChannel][idx] = ( singularVectors[currChannel][idx] - ( *g ) ); +#endif for ( iCh = currChannel + 1; iCh < nChannelsL; iCh++ ) /* nChannelsL */ { @@ -635,6 +663,10 @@ static void biDiagonalReductionRight( } } +#ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN + *g = g_loc; +#endif + return; } -- GitLab From fc10834ff32e9cc0f4557e2eabc9520866e2249c Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Sun, 12 Apr 2026 21:33:23 +0200 Subject: [PATCH 4/4] fix #else path --- lib_dec/ivas_svd_dec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 8e29e82b6..409971529 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -615,6 +615,8 @@ static void biDiagonalReductionRight( #ifdef FIX_FLOAT_1560_SVD_NO_OPT_MAX_W_SIGN volatile float norm_x, r; volatile float g_loc; +#else + float norm_x, r; #endif /* Setting values to 0 */ -- GitLab