Utilize __builtin functions to improve overflow handling
Bug: 353665200
Bug: 350884410
Bug: 354211166
Test: Play audio files present in the bug
Test: atest CtsMediaV2TestCases
Test: atest MctsMediaV2TestCases
Test: atest VtsHalMediaC2V1_0TargetAudioDecTest
Test: atest VtsHalMediaC2V1_0TargetAudioEncTest
Change-Id: I131e1914e5689c571fbd19d7553b99001bcd8aff
diff --git a/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
index 8f0867a..8817621 100644
--- a/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
+++ b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
@@ -120,15 +120,11 @@
{
Word32 L_sum;
- L_sum = L_var1 + L_var2;
-
- if ((L_var1 ^ L_var2) >= 0)
+ if (__builtin_add_overflow(L_var1, L_var2, &L_sum))
{
- if ((L_sum ^ L_var1) < 0)
- {
- L_sum = (L_var1 < 0) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
+ // saturating...
+ L_sum = (L_var1 < 0) ? MIN_32 : MAX_32;
+ *pOverflow = 1;
}
return (L_sum);
@@ -160,15 +156,11 @@
{
Word32 L_diff;
- L_diff = L_var1 - L_var2;
-
- if ((L_var1 ^ L_var2) < 0)
+ if (__builtin_sub_overflow(L_var1, L_var2, &L_diff))
{
- if ((L_diff ^ L_var1) & MIN_32)
- {
- L_diff = (L_var1 < 0L) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
+ // saturating...
+ L_diff = (L_var1 < 0L) ? MIN_32 : MAX_32;
+ *pOverflow = 1;
}
return (L_diff);
@@ -204,16 +196,12 @@
result = (Word32) var1 * var2;
if (result != (Word32) 0x40000000L)
{
- L_sum = (result << 1) + L_var3;
-
/* Check if L_sum and L_var_3 share the same sign */
- if ((L_var3 ^ result) > 0)
+ if (__builtin_add_overflow((result << 1), L_var3, &L_sum))
{
- if ((L_sum ^ L_var3) < 0)
- {
- L_sum = (L_var3 < 0) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
+ // saturating...
+ L_sum = (L_var3 < 0) ? MIN_32 : MAX_32;
+ *pOverflow = 1;
}
}
else
@@ -345,14 +333,10 @@
product32 = ((Word32) L_var1_hi * L_var2_lo) >> 15;
/* L_product = L_mac (L_product, result, 1, pOverflow); */
- L_sum = L_product + (product32 << 1);
-
- if ((L_product ^ product32) > 0)
+ if (__builtin_add_overflow(L_product, (product32 << 1), &L_sum))
{
- if ((L_sum ^ L_product) < 0)
- {
- L_sum = (L_product < 0) ? MIN_32 : MAX_32;
- }
+ // saturating...
+ L_sum = (L_product < 0) ? MIN_32 : MAX_32;
}
L_product = L_sum;
@@ -361,14 +345,10 @@
product32 = ((Word32) L_var1_lo * L_var2_hi) >> 15;
/* L_product = L_mac (L_product, result, 1, pOverflow); */
- L_sum = L_product + (product32 << 1);
-
- if ((L_product ^ product32) > 0)
+ if (__builtin_add_overflow(L_product, (product32 << 1), &L_sum))
{
- if ((L_sum ^ L_product) < 0)
- {
- L_sum = (L_product < 0) ? MIN_32 : MAX_32;
- }
+ // saturating...
+ L_sum = (L_product < 0) ? MIN_32 : MAX_32;
}
return (L_sum);
}
@@ -416,15 +396,11 @@
result = ((Word32)L_var1_lo * var2) >> 15;
- L_sum = L_product + (result << 1);
-
- if ((L_product ^ result) > 0)
+ if (__builtin_add_overflow(L_product, (result << 1), &L_sum))
{
- if ((L_sum ^ L_product) < 0)
- {
- L_sum = (L_product < 0) ? MIN_32 : MAX_32;
- *pOverflow = 1;
- }
+ // saturating...
+ L_sum = (L_product < 0) ? MIN_32 : MAX_32;
+ *pOverflow = 1;
}
return (L_sum);
diff --git a/media/module/codecs/amrnb/enc/src/g_pitch.cpp b/media/module/codecs/amrnb/enc/src/g_pitch.cpp
index 5b80e2a..6f686fa 100644
--- a/media/module/codecs/amrnb/enc/src/g_pitch.cpp
+++ b/media/module/codecs/amrnb/enc/src/g_pitch.cpp
@@ -376,15 +376,11 @@
{
L_temp = ((Word32) * (p_xn++) * *(p_y1++));
s1 = s;
- s = s1 + L_temp;
- if ((s1 ^ L_temp) > 0)
+ if (__builtin_add_overflow(s1, L_temp, &s))
{
- if ((s1 ^ s) < 0)
- {
- *pOverflow = 1;
- break;
- }
+ *pOverflow = 1;
+ break;
}
}
diff --git a/media/module/codecs/amrwb/enc/inc/basic_op.h b/media/module/codecs/amrwb/enc/inc/basic_op.h
index 80ad7f1..8e740b4 100644
--- a/media/module/codecs/amrwb/enc/inc/basic_op.h
+++ b/media/module/codecs/amrwb/enc/inc/basic_op.h
@@ -569,13 +569,10 @@
static_vo Word32 L_add (Word32 L_var1, Word32 L_var2)
{
Word32 L_var_out;
- L_var_out = L_var1 + L_var2;
- if (((L_var1 ^ L_var2) & MIN_32) == 0)
+ if (__builtin_add_overflow(L_var1, L_var2, &L_var_out))
{
- if ((L_var_out ^ L_var1) & MIN_32)
- {
- L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
- }
+ // saturating...
+ L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
}
return (L_var_out);
}
@@ -616,13 +613,10 @@
static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2)
{
Word32 L_var_out;
- L_var_out = L_var1 - L_var2;
- if (((L_var1 ^ L_var2) & MIN_32) != 0)
+ if (__builtin_sub_overflow(L_var1, L_var2, &L_var_out))
{
- if ((L_var_out ^ L_var1) & MIN_32)
- {
- L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
- }
+ // saturating...
+ L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
}
return (L_var_out);
}