From: Eliav Farber <farbere@amazon.com>
To: <richard@nod.at>, <anton.ivanov@cambridgegreys.com>,
<johannes@sipsolutions.net>, <dave.hansen@linux.intel.com>,
<luto@kernel.org>, <peterz@infradead.org>, <tglx@linutronix.de>,
<mingo@redhat.com>, <bp@alien8.de>, <x86@kernel.org>,
<hpa@zytor.com>, <tony.luck@intel.com>, <qiuxu.zhuo@intel.com>,
<james.morse@arm.com>, <mchehab@kernel.org>, <rric@kernel.org>,
<harry.wentland@amd.com>, <sunpeng.li@amd.com>,
<Rodrigo.Siqueira@amd.com>, <alexander.deucher@amd.com>,
<christian.koenig@amd.com>, <Xinhui.Pan@amd.com>,
<airlied@gmail.com>, <daniel@ffwll.ch>, <evan.quan@amd.com>,
<maarten.lankhorst@linux.intel.com>, <mripard@kernel.org>,
<tzimmermann@suse.de>, <jdelvare@suse.com>, <linux@roeck-us.net>,
<linus.walleij@linaro.org>, <dmitry.torokhov@gmail.com>,
<wens@csie.org>, <jernej.skrabec@gmail.com>,
<samuel@sholland.org>, <agk@redhat.com>, <snitzer@kernel.org>,
<dm-devel@lists.linux.dev>, <mailhol.vincent@wanadoo.fr>,
<wg@grandegger.com>, <mkl@pengutronix.de>, <davem@davemloft.net>,
<edumazet@google.com>, <kuba@kernel.org>, <pabeni@redhat.com>,
<alexandre.torgue@foss.st.com>, <joabreu@synopsys.com>,
<mcoquelin.stm32@gmail.com>, <krzysztof.kozlowski@linaro.org>,
<malattia@linux.it>, <hdegoede@redhat.com>,
<ilpo.jarvinen@linux.intel.com>, <markgross@kernel.org>,
<artur.paszkiewicz@intel.com>, <jejb@linux.ibm.com>,
<martin.petersen@oracle.com>, <sakari.ailus@linux.intel.com>,
<gregkh@linuxfoundation.org>, <clm@fb.com>,
<josef@toxicpanda.com>, <dsterba@suse.com>,
<luc.vanoostenryck@gmail.com>, <rostedt@goodmis.org>,
<mhiramat@kernel.org>, <pmladek@suse.com>,
<andriy.shevchenko@linux.intel.com>, <linux@rasmusvillemoes.dk>,
<senozhatsky@chromium.org>, <minchan@kernel.org>,
<akpm@linux-foundation.org>, <dsahern@kernel.org>,
<shuah@kernel.org>, <keescook@chromium.org>, <wad@chromium.org>,
<farbere@amazon.com>, <David.Laight@ACULAB.COM>,
<arnd@kernel.org>, <linux-um@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <linux-edac@vger.kernel.org>,
<amd-gfx@lists.freedesktop.org>,
<dri-devel@lists.freedesktop.org>, <linux-hwmon@vger.kernel.org>,
<linux-input@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<linux-sunxi@lists.linux.dev>, <linux-media@vger.kernel.org>,
<linux-can@vger.kernel.org>, <netdev@vger.kernel.org>,
<linux-stm32@st-md-mailman.stormreply.com>,
<platform-driver-x86@vger.kernel.org>,
<linux-scsi@vger.kernel.org>, <linux-staging@lists.linux.dev>,
<linux-btrfs@vger.kernel.org>, <linux-sparse@vger.kernel.org>,
<linux-trace-kernel@vger.kernel.org>, <linux-mm@kvack.org>,
<linux-kselftest@vger.kernel.org>, <bpf@vger.kernel.org>,
<stable@vger.kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
David Laight <David.Laight@aculab.com>,
Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Subject: [PATCH 05/15 6.6.y] minmax: simplify min()/max()/clamp() implementation
Date: Mon, 22 Sep 2025 10:32:31 +0000 [thread overview]
Message-ID: <20250922103241.16213-6-farbere@amazon.com> (raw)
In-Reply-To: <20250922103241.16213-1-farbere@amazon.com>
From: Linus Torvalds <torvalds@linux-foundation.org>
[ Upstream commit dc1c8034e31b14a2e5e212104ec508aec44ce1b9 ]
Now that we no longer have any C constant expression contexts (ie array
size declarations or static initializers) that use min() or max(), we
can simpify the implementation by not having to worry about the result
staying as a C constant expression.
So now we can unconditionally just use temporary variables of the right
type, and get rid of the excessive expansion that used to come from the
use of
__builtin_choose_expr(__is_constexpr(...), ..
to pick the specialized code for constant expressions.
Another expansion simplification is to pass the temporary variables (in
addition to the original expression) to our __types_ok() macro. That
may superficially look like it complicates the macro, but when we only
want the type of the expression, expanding the temporary variable names
is much simpler and smaller than expanding the potentially complicated
original expression.
As a result, on my machine, doing a
$ time make drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.i
goes from
real 0m16.621s
user 0m15.360s
sys 0m1.221s
to
real 0m2.532s
user 0m2.091s
sys 0m0.452s
because the token expansion goes down dramatically.
In particular, the longest line expansion (which was line 71 of that
'ia_css_ynr.host.c' file) shrinks from 23,338kB (yes, 23MB for one
single line) to "just" 1,444kB (now "only" 1.4MB).
And yes, that line is still the line from hell, because it's doing
multiple levels of "min()/max()" expansion thanks to some of them being
hidden inside the uDIGIT_FITTING() macro.
Lorenzo has a nice cleanup patch that makes that driver use inline
functions instead of macros for sDIGIT_FITTING() and uDIGIT_FITTING(),
which will fix that line once and for all, but the 16-fold reduction in
this case does show why we need to simplify these helpers.
Cc: David Laight <David.Laight@aculab.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
include/linux/minmax.h | 43 ++++++++++++++++++++----------------------
1 file changed, 20 insertions(+), 23 deletions(-)
diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index fc384714da45..e3e4353df983 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -35,10 +35,10 @@
#define __is_noneg_int(x) \
(__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0)
-#define __types_ok(x, y) \
- (__is_signed(x) == __is_signed(y) || \
- __is_signed((x) + 0) == __is_signed((y) + 0) || \
- __is_noneg_int(x) || __is_noneg_int(y))
+#define __types_ok(x, y, ux, uy) \
+ (__is_signed(ux) == __is_signed(uy) || \
+ __is_signed((ux) + 0) == __is_signed((uy) + 0) || \
+ __is_noneg_int(x) || __is_noneg_int(y))
#define __cmp_op_min <
#define __cmp_op_max >
@@ -51,34 +51,31 @@
#define __cmp_once(op, type, x, y) \
__cmp_once_unique(op, type, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_))
-#define __careful_cmp_once(op, x, y) ({ \
- static_assert(__types_ok(x, y), \
+#define __careful_cmp_once(op, x, y, ux, uy) ({ \
+ __auto_type ux = (x); __auto_type uy = (y); \
+ static_assert(__types_ok(x, y, ux, uy), \
#op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \
- __cmp_once(op, __auto_type, x, y); })
+ __cmp(op, ux, uy); })
-#define __careful_cmp(op, x, y) \
- __builtin_choose_expr(__is_constexpr((x) - (y)), \
- __cmp(op, x, y), __careful_cmp_once(op, x, y))
+#define __careful_cmp(op, x, y) \
+ __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_))
#define __clamp(val, lo, hi) \
((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
-#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ \
- typeof(val) unique_val = (val); \
- typeof(lo) unique_lo = (lo); \
- typeof(hi) unique_hi = (hi); \
+#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \
+ __auto_type uval = (val); \
+ __auto_type ulo = (lo); \
+ __auto_type uhi = (hi); \
static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \
(lo) <= (hi), true), \
"clamp() low limit " #lo " greater than high limit " #hi); \
- static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error"); \
- static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error"); \
- __clamp(unique_val, unique_lo, unique_hi); })
-
-#define __careful_clamp(val, lo, hi) ({ \
- __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)), \
- __clamp(val, lo, hi), \
- __clamp_once(val, lo, hi, __UNIQUE_ID(__val), \
- __UNIQUE_ID(__lo), __UNIQUE_ID(__hi))); })
+ static_assert(__types_ok(uval, lo, uval, ulo), "clamp() 'lo' signedness error"); \
+ static_assert(__types_ok(uval, hi, uval, uhi), "clamp() 'hi' signedness error"); \
+ __clamp(uval, ulo, uhi); })
+
+#define __careful_clamp(val, lo, hi) \
+ __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_))
/**
* min - return minimum of two values of the same or compatible types
--
2.47.3
next prev parent reply other threads:[~2025-09-22 10:35 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-22 10:32 [PATCH 00/15 v6.6.y] Backport minmax.h updates from v6.17-rc7 Eliav Farber
2025-09-22 10:32 ` [PATCH 01/15 6.6.y] minmax: avoid overly complicated constant expressions in VM code Eliav Farber
2025-09-22 10:32 ` [PATCH 02/15 6.6.y] minmax: simplify and clarify min_t()/max_t() implementation Eliav Farber
2025-09-22 10:32 ` [PATCH 03/15 6.6.y] minmax: add a few more MIN_T/MAX_T users Eliav Farber
2025-09-22 10:32 ` [PATCH 04/15 6.6.y] minmax: make generic MIN() and MAX() macros available everywhere Eliav Farber
2025-09-22 10:32 ` Eliav Farber [this message]
2025-09-22 10:32 ` [PATCH 06/15 6.6.y] minmax: don't use max() in situations that want a C constant expression Eliav Farber
2025-09-22 10:32 ` [PATCH 07/15 6.6.y] minmax: improve macro expansion and type checking Eliav Farber
2025-09-22 10:32 ` [PATCH 08/15 6.6.y] minmax: fix up min3() and max3() too Eliav Farber
2025-09-22 10:32 ` [PATCH 09/15 6.6.y] minmax.h: add whitespace around operators and after commas Eliav Farber
2025-09-22 10:32 ` [PATCH 10/15 6.6.y] minmax.h: update some comments Eliav Farber
2025-09-22 10:32 ` [PATCH 11/15 6.6.y] minmax.h: reduce the #define expansion of min(), max() and clamp() Eliav Farber
2025-09-22 10:32 ` [PATCH 12/15 6.6.y] minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp() Eliav Farber
2025-09-22 10:32 ` [PATCH 13/15 6.6.y] minmax.h: move all the clamp() definitions after the min/max() ones Eliav Farber
2025-09-22 10:32 ` [PATCH 14/15 6.6.y] minmax.h: simplify the variants of clamp() Eliav Farber
2025-09-22 10:32 ` [PATCH 15/15 6.6.y] minmax.h: remove some #defines that are only expanded once Eliav Farber
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=20250922103241.16213-6-farbere@amazon.com \
--to=farbere@amazon.com \
--cc=David.Laight@ACULAB.COM \
--cc=Rodrigo.Siqueira@amd.com \
--cc=Xinhui.Pan@amd.com \
--cc=agk@redhat.com \
--cc=airlied@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=alexander.deucher@amd.com \
--cc=alexandre.torgue@foss.st.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=anton.ivanov@cambridgegreys.com \
--cc=arnd@kernel.org \
--cc=artur.paszkiewicz@intel.com \
--cc=bp@alien8.de \
--cc=bpf@vger.kernel.org \
--cc=christian.koenig@amd.com \
--cc=clm@fb.com \
--cc=daniel@ffwll.ch \
--cc=dave.hansen@linux.intel.com \
--cc=davem@davemloft.net \
--cc=dm-devel@lists.linux.dev \
--cc=dmitry.torokhov@gmail.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=dsahern@kernel.org \
--cc=dsterba@suse.com \
--cc=edumazet@google.com \
--cc=evan.quan@amd.com \
--cc=gregkh@linuxfoundation.org \
--cc=harry.wentland@amd.com \
--cc=hdegoede@redhat.com \
--cc=hpa@zytor.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=james.morse@arm.com \
--cc=jdelvare@suse.com \
--cc=jejb@linux.ibm.com \
--cc=jernej.skrabec@gmail.com \
--cc=joabreu@synopsys.com \
--cc=johannes@sipsolutions.net \
--cc=josef@toxicpanda.com \
--cc=keescook@chromium.org \
--cc=krzysztof.kozlowski@linaro.org \
--cc=kuba@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-can@vger.kernel.org \
--cc=linux-edac@vger.kernel.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-scsi@vger.kernel.org \
--cc=linux-sparse@vger.kernel.org \
--cc=linux-staging@lists.linux.dev \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=linux-sunxi@lists.linux.dev \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=linux-um@lists.infradead.org \
--cc=linux@rasmusvillemoes.dk \
--cc=linux@roeck-us.net \
--cc=lorenzo.stoakes@oracle.com \
--cc=luc.vanoostenryck@gmail.com \
--cc=luto@kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mailhol.vincent@wanadoo.fr \
--cc=malattia@linux.it \
--cc=markgross@kernel.org \
--cc=martin.petersen@oracle.com \
--cc=mchehab@kernel.org \
--cc=mcoquelin.stm32@gmail.com \
--cc=mhiramat@kernel.org \
--cc=minchan@kernel.org \
--cc=mingo@redhat.com \
--cc=mkl@pengutronix.de \
--cc=mripard@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=peterz@infradead.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=pmladek@suse.com \
--cc=qiuxu.zhuo@intel.com \
--cc=richard@nod.at \
--cc=rostedt@goodmis.org \
--cc=rric@kernel.org \
--cc=sakari.ailus@linux.intel.com \
--cc=samuel@sholland.org \
--cc=senozhatsky@chromium.org \
--cc=shuah@kernel.org \
--cc=snitzer@kernel.org \
--cc=stable@vger.kernel.org \
--cc=sunpeng.li@amd.com \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
--cc=torvalds@linux-foundation.org \
--cc=tzimmermann@suse.de \
--cc=wad@chromium.org \
--cc=wens@csie.org \
--cc=wg@grandegger.com \
--cc=x86@kernel.org \
/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;
as well as URLs for NNTP newsgroup(s).