From nobody Sun Feb 8 05:23:28 2026 Received: from 9.mo583.mail-out.ovh.net (9.mo583.mail-out.ovh.net [178.32.96.204]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AAADA3B2A0 for ; Wed, 21 Jan 2026 09:48:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.32.96.204 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768988914; cv=none; b=lb7Kd0OHY1hhgWQEe7SEezNb/G/Y7ccZzC3udMFSgw48EMfRSKROBQ9nnsB+RAKUtxf40zAH8HMSqLw+cO9viu73rruGdxquRa1dMvPJNo1xCG1QaD41hNjgvkQDG/s1SrXH+DTQo/tyP3/P7L+MaXreVLcPX4ykpo2wnNjsXtw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768988914; c=relaxed/simple; bh=Vj14fwKJ01lx3goK00XPZ6+ZTlU3TcD2aMB+jVSoLfI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AUdXlWfMxEw1R1oaAqHf6Q7wTOce8wevNC7bILs3TyYSDPNsTIyoNJ1C+NxtyRdVtlUeH53R4z4QtcGtsCK1obNfxIQPsCjtihCSG2KEybcI1eUS5W0ggfystTOz005hMB4JK87aLrenWXPgbOhumMtJGoFVrrEJ6k7nB6MoA1s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=formalgen.com; spf=pass smtp.mailfrom=formalgen.com; dkim=pass (2048-bit key) header.d=formalgen.com header.i=@formalgen.com header.b=BNCtFAjz; arc=none smtp.client-ip=178.32.96.204 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=formalgen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=formalgen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=formalgen.com header.i=@formalgen.com header.b="BNCtFAjz" Received: from director8.ghost.mail-out.ovh.net (unknown [10.110.0.202]) by mo583.mail-out.ovh.net (Postfix) with ESMTP id 4dwzg55FK3z5yDD for ; Wed, 21 Jan 2026 09:39:29 +0000 (UTC) Received: from ghost-submission-7d8d68f679-t42rs (unknown [10.110.164.191]) by director8.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 2F6B5C047C; Wed, 21 Jan 2026 09:39:23 +0000 (UTC) Received: from formalgen.com ([37.59.142.96]) by ghost-submission-7d8d68f679-t42rs with ESMTPSA id kuC8OsqecGnZ+AAAauWo+w (envelope-from ); Wed, 21 Jan 2026 09:39:23 +0000 Authentication-Results: garm.ovh; auth=pass (GARM-96R00156f290b1-35bc-4cb9-9353-9214f2790884, 831801AFC7761530D51FB11603EF4B8E66579AB0) smtp.auth=david.desobry@formalgen.com X-OVh-ClientIp: 90.91.42.105 From: David Desobry To: tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com Cc: x86@kernel.org, hpa@zytor.com, linux-kernel@vger.kernel.org, David Desobry Subject: [PATCH v4] x86/lib: Optimize num_digits() and fix INT_MIN overflow Date: Wed, 21 Jan 2026 10:39:11 +0100 Message-ID: <20260121093911.27042-1-david.desobry@formalgen.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <02817c9a-e512-427f-bd64-b1420132adf6@zytor.com> References: <02817c9a-e512-427f-bd64-b1420132adf6@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 11442239279355055051 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: dmFkZTEyvxmq+Wn6aeqhMJGuV/35E3UPH0eMwNIGD8R+0m0+yZjQwqIndl7kgx5Wyysx+l6K3Dou9t28/xPm4C3PeEpA/BxOV5raRHHHhfaQPfppFJjchU+QvUVuZGRXNtIlxejUuqV5rMMTuGFJ6YPaI0WRbPIZxsdHTr4N+ZHmH49z1F9r0yuARILpULRWwK/KK4nByibN1qVdrRk+maEM0bCUpMNihODwLT8w4Vj2O0H6hmXw/G8Tacb4fEBz1N2oZ4gsL8FhoAkNZ5mmGYbteJTlM8GXsO5kgVDOw3MuEtQnyMOmfT5MU2vKepBrlwnXf7vJsLwzLcZ8cq6oLP7Ex9rpUQ/H7sg3JQVBzFPojGpXi7i5mF8Pf7yozG4ZsIQNhPWa81nMYgt17MiDNvB14VJRTgvHyxSDERDNep/nhQvlfh0VS8f4VJ62myL9J1q2HOPwgxQFKi4tgzbS2GpqKtWL7vLHLj6S8FIMtpgdKj+3x5PDGnvBuGaGAAikcpFtnMM3yv7KXme+e6mj18Zy9tGbL7UXHaQEs5PS9xiWWNcThTPRqh1X9SwqdvFLwdxAz3W1BeZOf/c3e60Hhzj9E5KFcynNQPzFuSe9e4UPe4uSEI2OOF3KbgveYKrWPzlS8jyaUH08NS32WRXkRJt1syvPxOCLlXYVBiYvPGSo+XnvPg DKIM-Signature: a=rsa-sha256; bh=IHQ/LwAvaA0796A1b13vnwb1xcIEd5pdBYIPrttN2dQ=; c=relaxed/relaxed; d=formalgen.com; h=From; s=ovhmo-selector-1; t=1768988369; v=1; b=BNCtFAjzsd/9K8GLlDI09YiFHWMSjaJgAeZTXMHGLJTOG9sb84HWo1Be+vKKUn7GXuTWnuQJ sUIC44hrthb8eejZDTAeu/HwUyuQdaCJye0GcZa41ggNDdWK2DmVJuME1VsZ+y2YfmX9DvFamDq g6NU8VdLj23E7P2aLHreeyx2nl7nXMslEjjER3/cMsfzEr2M8xjGNt67MANcoohppMp15/iu4En G/SRI97fJNvgwfK0iLDZpyHRSlwraIPdzA92Ew1L/cYkTWVzYhKd5rTifC6fQ/v5iRqCpu7Ej8B ddMjONvVzBWKEyqq9jipQfvWvYU0HkO1hOU4ldt5TSfmg== Content-Type: text/plain; charset="utf-8" The current implementation of num_digits() uses a loop with repeated multiplication, which is inefficient. Furthermore, it takes a signed integer which leads to undefined behavior when negating INT_MIN. As this function is only used for unsigned magnitudes in the kernel code, convert the interface to take an unsigned int. This naturally resolves the INT_MIN overflow issue. Replace the loop with a branchless sequence using inline assembly. By using the 'sbb' instruction against the carry flag after comparisons, we eliminate all conditional branches. This provides constant-time performance and avoids CPU branch misprediction penalties. Update the function comment to reflect that signs are no longer handled. Signed-off-by: David Desobry --- v4: - Switched to branchless inline assembly.=20 - Changed function signature to unsigned int. - Updated prototype in arch/x86/include/asm/misc.h.=20 arch/x86/include/asm/misc.h | 2 +- arch/x86/lib/misc.c | 28 +++++++++++++--------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/misc.h b/arch/x86/include/asm/misc.h index bb049cca3729..48b6bd7c08b9 100644 --- a/arch/x86/include/asm/misc.h +++ b/arch/x86/include/asm/misc.h @@ -2,6 +2,6 @@ #ifndef _ASM_X86_MISC_H #define _ASM_X86_MISC_H =20 -int num_digits(int val); +int num_digits(unsigned int val); =20 #endif /* _ASM_X86_MISC_H */ diff --git a/arch/x86/lib/misc.c b/arch/x86/lib/misc.c index 40b81c338ae5..9623795b059f 100644 --- a/arch/x86/lib/misc.c +++ b/arch/x86/lib/misc.c @@ -2,23 +2,21 @@ #include =20 /* - * Count the digits of @val including a possible sign. - * - * (Typed on and submitted from hpa's mobile phone.) + * Count the decimal digits of an unsigned integer. */ -int num_digits(int val) +int num_digits(unsigned int x) { - long long m =3D 10; - int d =3D 1; + int n =3D 0; =20 - if (val < 0) { - d++; - val =3D -val; - } + asm("cmp %2,%1; sbb $-2,%0" : "+r" (n) : "r" (x), "g" (10)); + asm("cmp %2,%1; sbb $-1,%0" : "+r" (n) : "r" (x), "g" (100)); + asm("cmp %2,%1; sbb $-1,%0" : "+r" (n) : "r" (x), "g" (1000)); + asm("cmp %2,%1; sbb $-1,%0" : "+r" (n) : "r" (x), "g" (10000)); + asm("cmp %2,%1; sbb $-1,%0" : "+r" (n) : "r" (x), "g" (100000)); + asm("cmp %2,%1; sbb $-1,%0" : "+r" (n) : "r" (x), "g" (1000000)); + asm("cmp %2,%1; sbb $-1,%0" : "+r" (n) : "r" (x), "g" (10000000)); + asm("cmp %2,%1; sbb $-1,%0" : "+r" (n) : "r" (x), "g" (100000000)); + asm("cmp %2,%1; sbb $-1,%0" : "+r" (n) : "r" (x), "g" (1000000000)); =20 - while (val >=3D m) { - m *=3D 10; - d++; - } - return d; + return n; } --=20 2.43.0