Date: Wed, 17 Feb 2021 12:46:36 -0800 From: Ryan Libby <rlibby@freebsd.org> To: Alex Richardson <arichardson@freebsd.org> Cc: src-committers <src-committers@freebsd.org>, dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org Subject: Re: git: 8fa6abb6f4f6 - main - Expose clang's alignment builtins and use them for roundup2/rounddown2 Message-ID: <CAHgpiFyAcK5%2BZh0bdOdMw12Yj96RHo08g9qaNh5C50k1jwP1bA@mail.gmail.com> In-Reply-To: <202102031604.113G4SQq019037@gitrepo.freebsd.org> References: <202102031604.113G4SQq019037@gitrepo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Feb 3, 2021 at 8:04 AM Alex Richardson <arichardson@freebsd.org> wrote: > > The branch main has been updated by arichardson: > > URL: https://cgit.FreeBSD.org/src/commit/?id=8fa6abb6f4f64f4f23e2920e2aea7996566851a4 > > commit 8fa6abb6f4f64f4f23e2920e2aea7996566851a4 > Author: Alex Richardson <arichardson@FreeBSD.org> > AuthorDate: 2021-02-03 15:27:17 +0000 > Commit: Alex Richardson <arichardson@FreeBSD.org> > CommitDate: 2021-02-03 16:02:54 +0000 > > Expose clang's alignment builtins and use them for roundup2/rounddown2 > > This makes roundup2/rounddown2 type- and const-preserving and allows > using it on pointer types without casting to uintptr_t first. Not > performing pointer-to-integer conversions also helps the compiler's > optimization passes and can therefore result in better code generation. > When using it with integer values there should be no change other than > the compiler checking that the alignment value is a valid power-of-two. > > I originally implemented these builtins for CHERI a few years ago and > they have been very useful for CheriBSD. However, they are also useful > for non-CHERI code so I was able to upstream them for Clang 10.0. > > Rationale from the clang documentation: > Clang provides builtins to support checking and adjusting alignment > of pointers and integers. These builtins can be used to avoid relying > on implementation-defined behavior of arithmetic on integers derived > from pointers. Additionally, these builtins retain type information > and, unlike bitwise arithmetic, they can perform semantic checking on > the alignment value. > > There is also a feature request for GCC, so GCC may also support it in > the future: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98641 > > Reviewed By: brooks, jhb, imp > Differential Revision: https://reviews.freebsd.org/D28332 > --- > sys/sys/cdefs.h | 19 +++++++++++++++++++ > sys/sys/param.h | 4 ++-- > 2 files changed, 21 insertions(+), 2 deletions(-) > > diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h > index 75bedd4b8128..72ef942084f2 100644 > --- a/sys/sys/cdefs.h > +++ b/sys/sys/cdefs.h > @@ -884,4 +884,23 @@ > #define __guarded_by(x) __lock_annotate(guarded_by(x)) > #define __pt_guarded_by(x) __lock_annotate(pt_guarded_by(x)) > > +/* Alignment builtins for better type checking and improved code generation. */ > +/* Provide fallback versions for other compilers (GCC/Clang < 10): */ > +#if !__has_builtin(__builtin_is_aligned) > +#define __builtin_is_aligned(x, align) \ > + (((__uintptr_t)x & ((align) - 1)) == 0) > +#endif > +#if !__has_builtin(__builtin_align_up) > +#define __builtin_align_up(x, align) \ > + ((__typeof__(x))(((__uintptr_t)(x)+((align)-1))&(~((align)-1)))) > +#endif > +#if !__has_builtin(__builtin_align_down) > +#define __builtin_align_down(x, align) \ > + ((__typeof__(x))((x)&(~((align)-1)))) > +#endif > + > +#define __align_up(x, y) __builtin_align_up(x, y) > +#define __align_down(x, y) __builtin_align_down(x, y) > +#define __is_aligned(x, y) __builtin_is_aligned(x, y) > + Since these are only valid for powers of 2, I think it would be good to indicate that in the names (__align_up2() etc). > #endif /* !_SYS_CDEFS_H_ */ > diff --git a/sys/sys/param.h b/sys/sys/param.h > index 079357a19d47..d6f1eb21dcd2 100644 > --- a/sys/sys/param.h > +++ b/sys/sys/param.h > @@ -305,9 +305,9 @@ > #endif > #define nitems(x) (sizeof((x)) / sizeof((x)[0])) > #define rounddown(x, y) (((x)/(y))*(y)) > -#define rounddown2(x, y) ((x)&(~((y)-1))) /* if y is power of two */ > +#define rounddown2(x, y) __align_down(x, y) /* if y is power of two */ > #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ > -#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ > +#define roundup2(x, y) __align_up(x, y) /* if y is powers of two */ > #define powerof2(x) ((((x)-1)&(x))==0) > > /* Macros for min/max. */ This broke the gcc build: https://ci.freebsd.org/job/FreeBSD-main-amd64-gcc6_build/3200/console 00:40:30 --- all_subdir_firewire --- 00:40:30 In file included from /workspace/src/sys/sys/types.h:43:0, 00:40:30 from /workspace/src/sys/sys/param.h:99, 00:40:30 from /workspace/src/sys/dev/firewire/fwohci.c:40: 00:40:30 /workspace/src/sys/dev/firewire/fwohci.c: In function 'fwohci_get_plen': 00:40:30 /workspace/src/sys/dev/firewire/fwohci.c:2699:17: error: 'typeof' applied to a bit-field 00:40:30 r += roundup2(fp->mode.wreqb.len, sizeof(uint32_t)); We could: - Drop the cast for the fallback. - Cast with (__typeof__(+(x))) which unfortunately promotes e.g. char to int but otherwise I think behaves okay, and the promotion was previously happening for roundup2/rounddown2 anyway. - Punt the casting burden to callers of roundup2/rounddown2. Ryan
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAHgpiFyAcK5%2BZh0bdOdMw12Yj96RHo08g9qaNh5C50k1jwP1bA>