From: "René Scharfe" <l.s.r@web.de>
To: git@vger.kernel.org
Cc: Jeff King <peff@peff.net>, Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v2 2/2] use __builtin_add_overflow() in st_add() with Clang
Date: Mon, 18 May 2026 22:25:02 +0200 [thread overview]
Message-ID: <20260518202502.25682-3-l.s.r@web.de> (raw)
In-Reply-To: <20260518202502.25682-1-l.s.r@web.de>
Clang and GCC optimize away comparisons of overflow checks by checking
the carry flag on x64. GCC does the same on ARM64, but Clang currently
(version 22.1) doesn't.
It does this optimization for overflow checks that use its builtin
function __builtin_add_overflow(), though. Provide a non-generic
lookalike for size_t that does the same checks as before as a fallback
and use the original with Clang. Use it on all platforms for simplicity.
On an Apple M1 I get a nice speedup for a command that builds lots of
strings using a strbuf, which exercises the st_add3() in strbuf_grow()
for every line of output:
Benchmark 1: ./git_main cat-file --batch-all-objects --batch-check='%(objectname)'
Time (mean ± σ): 120.4 ms ± 0.2 ms [User: 113.8 ms, System: 6.0 ms]
Range (min … max): 120.1 ms … 121.1 ms 24 runs
Benchmark 2: ./git cat-file --batch-all-objects --batch-check='%(objectname)'
Time (mean ± σ): 115.5 ms ± 0.1 ms [User: 108.6 ms, System: 5.8 ms]
Range (min … max): 115.2 ms … 115.8 ms 25 runs
Summary
./git cat-file --batch-all-objects --batch-check='%(objectname)' ran
1.04 ± 0.00 times faster than ./git_main cat-file --batch-all-objects --batch-check='%(objectname)'
Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: René Scharfe <l.s.r@web.de>
---
git-compat-util.h | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/git-compat-util.h b/git-compat-util.h
index ae1bdc90a4..5b1d15fe4f 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -614,12 +614,30 @@ static inline bool strip_suffix(const char *str, const char *suffix,
int git_open_cloexec(const char *name, int flags);
#define git_open(name) git_open_cloexec(name, O_RDONLY)
-static inline size_t st_add(size_t a, size_t b)
+
+/*
+ * Help Clang; GCC generates the same instructions for both variants on
+ * x64 and aarch64.
+ */
+#ifdef __clang__
+#define st_add_overflow __builtin_add_overflow
+#else
+static inline bool st_add_overflow(size_t a, size_t b, size_t *out)
{
if (unsigned_add_overflows(a, b))
+ return true;
+ *out = a + b;
+ return false;
+}
+#endif
+
+static inline size_t st_add(size_t a, size_t b)
+{
+ size_t result;
+ if (st_add_overflow(a, b, &result))
die("size_t overflow: %"PRIuMAX" + %"PRIuMAX,
(uintmax_t)a, (uintmax_t)b);
- return a + b;
+ return result;
}
#define st_add3(a,b,c) st_add(st_add((a),(b)),(c))
#define st_add4(a,b,c,d) st_add(st_add3((a),(b),(c)),(d))
--
2.54.0
next prev parent reply other threads:[~2026-05-18 20:25 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-14 15:11 [PATCH 1/2] strbuf: use st_add3() in strbuf_grow() René Scharfe
2026-05-14 15:13 ` [PATCH 2/2] use __builtin_add_overflow() in st_add() with Clang René Scharfe
2026-05-14 19:12 ` Junio C Hamano
2026-05-14 20:17 ` René Scharfe
2026-05-15 16:49 ` René Scharfe
2026-05-15 4:40 ` Jeff King
2026-05-15 14:36 ` René Scharfe
2026-05-15 16:53 ` Jeff King
2026-05-14 19:07 ` [PATCH 1/2] strbuf: use st_add3() in strbuf_grow() Junio C Hamano
2026-05-14 20:13 ` René Scharfe
2026-05-15 4:36 ` Jeff King
2026-05-15 14:30 ` René Scharfe
2026-05-15 16:50 ` Jeff King
2026-05-18 20:25 ` [PATCH v2 0/2] use __builtin_add_overflow() in st_add() with Clang René Scharfe
2026-05-18 20:25 ` [PATCH v2 1/2] strbuf: use st_add3() in strbuf_grow() René Scharfe
2026-05-18 20:25 ` René Scharfe [this message]
2026-05-19 0:44 ` [PATCH v2 0/2] use __builtin_add_overflow() in st_add() with Clang Jeff King
2026-05-19 0:57 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260518202502.25682-3-l.s.r@web.de \
--to=l.s.r@web.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox