From: David Laight <David.Laight@ACULAB.COM>
To: 'Arnd Bergmann' <arnd@kernel.org>,
Linus Torvalds <torvalds@linuxfoundation.org>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Jens Axboe <axboe@kernel.dk>,
Matthew Wilcox <willy@infradead.org>,
Christoph Hellwig <hch@infradead.org>,
Andrew Morton <akpm@linux-foundation.org>,
"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
Dan Carpenter <dan.carpenter@linaro.org>,
"Jason A . Donenfeld" <Jason@zx2c4.com>,
"pedro.falcato@gmail.com" <pedro.falcato@gmail.com>,
Mateusz Guzik <mjguzik@gmail.com>,
"linux-mm@kvack.org" <linux-mm@kvack.org>,
"Lorenzo Stoakes" <lorenzo.stoakes@oracle.com>
Subject: RE: [PATCH v2 1/8] minmax: Put all the clamp() definitions together
Date: Tue, 30 Jul 2024 12:03:24 +0000 [thread overview]
Message-ID: <424323bd65354ecbad256657d5782bc2@AcuMS.aculab.com> (raw)
In-Reply-To: <e946e002-8ca8-4a09-a800-d117c89b39d3@app.fastmail.com>
From: Arnd Bergmann
> Sent: 29 July 2024 23:25
..
> - My macros use __builtin_choose_expr() instead of ?: to
> ensure that the arguments are constant, this produces a
> relatively clear compiler warning when they are not.
> Without that, I would expect random drivers to start
> using MIN()/MAX() in places where it's not safe.
Yes, I think you either want temporaries or a constant check.
Losing the signedness check is less of a problem.
Since 'constantness' is only important for array sizes and
static initialisers the constant check is unlikely to be a problem.
Just adding __builtin_choose_expr((x)+(y),0,0) to the result
is enough and quite simple.
Then each argument is expanded 3 times.
(cf once for temporaries without a signedness check.))
>
> - I went with the belts-and-suspenders version of MIN()/MAX()
> that works when comparing a negative constant against
> an unsigned one. This requires expanding each argument
> four or five times instead of two, so you might still
> want the simpler version (like MIN_T/MAX_T):
I'm not sure that is worth it, there are very few negative
values (except error values) in the entire kernel.
And where ever the value is used a carefully created negative
constant is likely to be promoted to unsigned.
I'm not sure I like the casts in MIN_T() and MAX_T() either.
As with min_t() someone will use too small a type.
OTOH umin(x, y) could now be defined as:
min_t(u64, (x) + 0 + 0u, (y) + 0 + 0u)
(which will never sign extend).
Then some of the bloating min() that are known to generate
unsigned values can be changed to umin().
It is also worth noting that umin() is likely to generate
better code than an _min() (that doesn't have the type check)
because comparing a 32bit signed type (assumed positive) with
a 64bit value won't require the (pointless) sign extension
code (particularly nasty on 32bit).
In my tests the compiler optimised for the high 32bits being
zero (from the zero extend) - so extending to 64bits doesn't matter.
The typeof((x) + 0) in the signedness test (a different email)
that matches the C promotion of u8 and u16 might have been added
before I did the change to allow unsigned comparisons against
positive integer constants.
Another anti-bloat is to do all the type tests on the temporaries.
So something based on:
#define ok_unsigned(_x, x)
(is_unsigned_type((typeof(_x)) ? 1 : if_constexpr((x), (x) >= 0, 0)))
#define min(x, y)
__auto_type _x = x;
__auto_type _y = y;
if (!is_signed_type(typeof(_x + _y))
&& !(ok_unsigned(_x, x) && ok_unsigned(_y, y)))
error();
__x < _y ? _x : _y;
which only has 3 expansions of each term.
(Of course the 'uniq' needed for nested calls don't help.)
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
next prev parent reply other threads:[~2024-07-30 12:04 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-28 14:15 [PATCH v2 0/8] minmax: reduce compilation time David Laight
2024-07-28 14:17 ` [PATCH v2 1/8] minmax: Put all the clamp() definitions together David Laight
2024-07-28 17:24 ` Linus Torvalds
2024-07-28 18:11 ` David Laight
2024-07-28 19:55 ` Linus Torvalds
2024-07-28 20:09 ` David Laight
2024-07-28 20:13 ` Linus Torvalds
2024-07-28 20:22 ` David Laight
2024-07-28 20:31 ` Linus Torvalds
2024-07-28 22:13 ` David Laight
2024-07-28 22:22 ` Linus Torvalds
2024-07-29 8:01 ` David Laight
2024-07-28 21:01 ` Linus Torvalds
2024-07-28 21:53 ` David Laight
2024-07-29 4:15 ` Linus Torvalds
2024-07-29 22:25 ` Arnd Bergmann
2024-07-29 23:21 ` Linus Torvalds
2024-07-30 1:52 ` Linus Torvalds
2024-07-30 3:59 ` Linus Torvalds
2024-07-30 10:10 ` Arnd Bergmann
2024-07-30 14:14 ` Arnd Bergmann
2024-07-30 18:02 ` Linus Torvalds
2024-07-30 19:52 ` Linus Torvalds
2024-07-30 21:47 ` David Laight
2024-07-30 22:44 ` Linus Torvalds
2024-07-30 23:03 ` Linus Torvalds
2024-07-31 8:09 ` David Laight
2024-07-31 10:50 ` Arnd Bergmann
2024-07-31 15:38 ` Linus Torvalds
2024-07-31 15:56 ` David Laight
2024-07-31 16:04 ` Linus Torvalds
2024-12-04 13:15 ` Geert Uytterhoeven
2024-12-04 17:16 ` David Laight
2024-07-30 16:35 ` Linus Torvalds
2024-07-30 16:46 ` Linus Torvalds
2024-07-30 12:03 ` David Laight [this message]
2024-07-28 18:23 ` David Laight
2024-07-28 14:18 ` [PATCH v2 2/8] minmax: Use _Static_assert() instead of static_assert() David Laight
2024-07-28 17:51 ` Christophe JAILLET
2024-07-28 18:12 ` David Laight
2024-07-28 14:19 ` [PATCH v2 3/8] compiler.h: Add __if_constexpr(expr, if_const, if_not_const) David Laight
2024-07-28 14:20 ` [PATCH v2 4/8] minmax: Simplify signedness check David Laight
2024-07-28 16:57 ` Linus Torvalds
2024-07-28 18:14 ` David Laight
2024-07-28 20:13 ` David Laight
2024-07-28 14:21 ` [PATCH v2 5/8] minmax: Factor out the zero-extension logic from umin/umax David Laight
2024-07-28 14:22 ` [PATCH v2 6/8] minmax: Optimise _Static_assert() check in clamp() David Laight
2024-07-28 14:23 ` [PATCH v2 7/8] minmax: Use __auto_type David Laight
2024-07-28 16:59 ` Linus Torvalds
2024-07-28 14:24 ` [PATCH v2 8/8] minmax: minmax: Add __types_ok3() and optimise defines with 3 arguments David Laight
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=424323bd65354ecbad256657d5782bc2@AcuMS.aculab.com \
--to=david.laight@aculab.com \
--cc=Jason@zx2c4.com \
--cc=akpm@linux-foundation.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=arnd@kernel.org \
--cc=axboe@kernel.dk \
--cc=dan.carpenter@linaro.org \
--cc=hch@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=mjguzik@gmail.com \
--cc=pedro.falcato@gmail.com \
--cc=torvalds@linuxfoundation.org \
--cc=willy@infradead.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