From f3dda9252360c434a0ac3bb0516227331c33344d Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 21 May 2025 12:33:36 +0900 Subject: [PATCH 1/4] Add FIX_USAN_L_DEPOSIT_H to resolve undefined behavior in L_deposit_h --- lib_com/basop32.c | 4 ++++ lib_com/options.h | 1 + 2 files changed, 5 insertions(+) diff --git a/lib_com/basop32.c b/lib_com/basop32.c index fbe08a11f..2e6c7710b 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -2790,7 +2790,11 @@ Word32 L_deposit_h( Word16 var1 ) { Word32 L_var_out; +#ifdef FIX_USAN_L_DEPOSIT_H + L_var_out = (Word32) ( ( (UWord32) var1 ) << 16 ); +#else L_var_out = (Word32) var1 << 16; +#endif #ifdef WMOPS multiCounter[currCounter].L_deposit_h++; diff --git a/lib_com/options.h b/lib_com/options.h index 75323cf13..db8bb96e9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -98,4 +98,5 @@ #define FIX_1486_IND_SHB_RES /* VA: Fix for issue 1486: align the usage of IND_SHB_RES_GS indices with float code */ #define TEST_HR +#define FIX_USAN_L_DEPOSIT_H /* Eri: (Issue #1528): The L_deposit_h does left-shift of negative numbers, which is undefined. This is resolved by casting to an unsigned number before the shift. */ #endif -- GitLab From 79bf423830b269fea93f7e10bf836ace81d1e289 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 21 May 2025 17:35:49 +0900 Subject: [PATCH 2/4] Added fix for L_add_o, L_add_co, shl_o and L_sub_o under FIX_1528_USAN_BASOP32 --- lib_com/basop32.c | 23 ++++++++++++++++++++++- lib_com/options.h | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 2e6c7710b..4219119e6 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -740,7 +740,12 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) } else { + +#ifdef FIX_1528_USAN_BASOP32 + result = (Word32) var1 * (Word32) ( 1UL << var2 ); +#else result = (Word32) var1 * ( (Word32) 1 << var2 ); +#endif if ( ( var2 > 15 && var1 != 0 ) || ( result != (Word32) ( (Word16) result ) ) ) { @@ -1626,7 +1631,11 @@ Word32 L_add_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) { Word32 L_var_out; +#ifdef FIX_1528_USAN_BASOP32 + L_var_out = (Word32) ( (UWord32) L_var1 + (UWord32) L_var2 ); +#else L_var_out = L_var1 + L_var2; +#endif if ( ( ( L_var1 ^ L_var2 ) & MIN_32 ) == 0 ) { @@ -1708,7 +1717,11 @@ Word32 L_sub_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) { Word32 L_var_out; +#ifdef FIX_1528_USAN_BASOP32 + L_var_out = (Word32) ( (UWord32) L_var1 - (UWord32) L_var2 ); +#else L_var_out = L_var1 - L_var2; +#endif if ( ( ( L_var1 ^ L_var2 ) & MIN_32 ) != 0 ) { @@ -1871,9 +1884,17 @@ Word32 L_add_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) Word32 L_test; Flag carry_int = 0; +#ifdef FIX_1528_USAN_BASOP32 + L_var_out = (Word32) ( (UWord32) L_var1 + (UWord32) L_var2 + get_carry( Carry ) ); +#else L_var_out = L_var1 + L_var2 + get_carry( Carry ); +#endif +#ifdef FIX_1528_USAN_BASOP32 + L_test = (Word32) ( (UWord32) L_var1 + (UWord32) L_var2 ); +#else L_test = L_var1 + L_var2; +#endif if ( ( L_var1 > 0 ) && ( L_var2 > 0 ) && ( L_test < 0 ) ) { @@ -2790,7 +2811,7 @@ Word32 L_deposit_h( Word16 var1 ) { Word32 L_var_out; -#ifdef FIX_USAN_L_DEPOSIT_H +#ifdef FIX_1528_USAN_BASOP32 L_var_out = (Word32) ( ( (UWord32) var1 ) << 16 ); #else L_var_out = (Word32) var1 << 16; diff --git a/lib_com/options.h b/lib_com/options.h index db8bb96e9..7de91d628 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -98,5 +98,5 @@ #define FIX_1486_IND_SHB_RES /* VA: Fix for issue 1486: align the usage of IND_SHB_RES_GS indices with float code */ #define TEST_HR -#define FIX_USAN_L_DEPOSIT_H /* Eri: (Issue #1528): The L_deposit_h does left-shift of negative numbers, which is undefined. This is resolved by casting to an unsigned number before the shift. */ +#define FIX_1528_USAN_BASOP32 /* Eri: (Issue #1528): The operators L_add_o, L_add_co, shl_o and L_sub_o assume additions/subtractions treated as unsigned numbers where wrap-around may happen. */ #endif -- GitLab From 72fb1c9293b5d118f4a3715a660190fad7d01643 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 22 May 2025 17:24:40 +0900 Subject: [PATCH 3/4] Add USAN fix for BASOP_Util_Divide3232_Scale_newton under FIX_1528_USAN_BASOP32 --- lib_com/basop_util.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index e52f404f6..9ed148f3a 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1409,7 +1409,11 @@ Word32 BASOP_Util_Divide3232_Scale_newton( Word32 x, Word32 y, Word16 *s ) *s = 0; return ( (Word32) 0 ); } +#ifdef FIX_1528_USAN_BASOP32 + IF( EQ_32( y, (Word32) 0x80000000 ) ) +#else IF( EQ_32( y, 0x80000000 ) ) +#endif { /* Division by -1.0: same as negation of numerator */ /* Return normalized negated numerator */ -- GitLab From 9d3a3315374cbe45332e55ebf53dee990a991f0e Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 4 Jun 2025 07:30:26 +0200 Subject: [PATCH 4/4] Add explicit type casts to UWord32 --- lib_com/basop32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 4219119e6..1e7ff42e4 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -742,7 +742,7 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) { #ifdef FIX_1528_USAN_BASOP32 - result = (Word32) var1 * (Word32) ( 1UL << var2 ); + result = (Word32) var1 * (Word32) ( ( (UWord32) 1 ) << var2 ); #else result = (Word32) var1 * ( (Word32) 1 << var2 ); #endif @@ -1885,7 +1885,7 @@ Word32 L_add_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) Flag carry_int = 0; #ifdef FIX_1528_USAN_BASOP32 - L_var_out = (Word32) ( (UWord32) L_var1 + (UWord32) L_var2 + get_carry( Carry ) ); + L_var_out = (Word32) ( (UWord32) L_var1 + (UWord32) L_var2 + (UWord32) get_carry( Carry ) ); #else L_var_out = L_var1 + L_var2 + get_carry( Carry ); #endif -- GitLab