diff --git a/ruy/kernel_common.h b/ruy/kernel_common.h index 69e819b20a..d4cf293fde 100644 --- a/ruy/kernel_common.h +++ b/ruy/kernel_common.h @@ -177,7 +177,13 @@ void MakeKernelParams8bit(const PMat& lhs, params->rhs_zero_point = rhs.zero_point; params->dst_zero_point = dst->zero_point; params->depth = depth; - params->prod_zp_depth = lhs.zero_point * rhs.zero_point * depth; + // prod_zp_depth intentionally relies on two's-complement wraparound to match + // the wrapping arithmetic performed by the asm kernels. Compute it in unsigned + // so the overflow is well-defined. + params->prod_zp_depth = static_cast( + static_cast(lhs.zero_point) * + static_cast(rhs.zero_point) * + static_cast(depth)); params->flags |= RUY_ASM_FLAG_NEEDS_LEFT_SHIFT; if (mul_params.multiplier_fixedpoint_perchannel()) { // Temporary release-assert to debug some crashes in an application.