aom: Double-check calculation in multiply_and_scale()

From 72b1f1d4b4f685a81beac05c8b495837df9e947e Mon Sep 17 00:00:00 2001
From: Wan-Teh Chang <[EMAIL REDACTED]>
Date: Thu, 29 Feb 2024 13:24:04 -0800
Subject: [PATCH] Double-check calculation in multiply_and_scale()

Double-check the calculation in multiply_and_scale() using __int128. To
be removed after two months.

Bug: b:319140742
Bug: oss-fuzz:66474
Change-Id: Ibe29fbe89475424caf3ca5c943565395bba18947
---
 av1/encoder/pickrst.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c
index e8a285393..b0d0d0bb7 100644
--- a/av1/encoder/pickrst.c
+++ b/av1/encoder/pickrst.c
@@ -1124,6 +1124,15 @@ static INLINE int64_t multiply_and_scale(int64_t x, int32_t w1, int32_t w2) {
   // Let y = x * w / WIENER_TAP_SCALE_FACTOR
   //       = x * (w1 * WIENER_TAP_SCALE_FACTOR + w2) / WIENER_TAP_SCALE_FACTOR
   const int64_t y = x * w1 + x * w2 / WIENER_TAP_SCALE_FACTOR;
+  // Double-check the calculation using __int128.
+  // TODO(wtc): Remove after 2024-04-30.
+#if !defined(NDEBUG) && defined(__GNUC__) && defined(__LP64__)
+  const int32_t w = w1 * WIENER_TAP_SCALE_FACTOR + w2;
+  const __int128 z = (__int128)x * w / WIENER_TAP_SCALE_FACTOR;
+  assert(z >= INT64_MIN);
+  assert(z <= INT64_MAX);
+  assert(y == (int64_t)z);
+#endif
   return y;
 }