Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Feb 2021 14:21:06 +0000
From:      Alexander Richardson <arichardson@freebsd.org>
To:        =?UTF-8?Q?T=C4=B3l_Coosemans?= <tijl@freebsd.org>
Cc:        Ryan Libby <rlibby@freebsd.org>, John Baldwin <jhb@freebsd.org>,  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:  <CA%2BZ_v8o4oQCFA9tGcs2Nhywq5xthJmnWXHLBhtJN0-x-ppFx9A@mail.gmail.com>
In-Reply-To: <20210218134614.376e4eaa@FreeBSD.org>
References:  <202102031604.113G4SQq019037@gitrepo.freebsd.org> <CAHgpiFyAcK5%2BZh0bdOdMw12Yj96RHo08g9qaNh5C50k1jwP1bA@mail.gmail.com> <CA%2BZ_v8o%2BBX_xMe2bK4ntBzW-FgEPgksY0y%2B87bwfqA1zTaVpHA@mail.gmail.com> <20210218134614.376e4eaa@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 18 Feb 2021 at 12:46, T=C4=B3l Coosemans <tijl@freebsd.org> wrote:
>
> On Wed, 17 Feb 2021 21:01:05 +0000 Alexander Richardson
> <arichardson@freebsd.org> wrote:
> > On Wed, 17 Feb 2021 at 20:46, Ryan Libby <rlibby@freebsd.org> wrote:
> >> On Wed, Feb 3, 2021 at 8:04 AM Alex Richardson <arichardson@freebsd.or=
g> wrote:
> >>> The branch main has been updated by arichardson:
> >>>
> >>> URL: https://cgit.FreeBSD.org/src/commit/?id=3D8fa6abb6f4f64f4f23e292=
0e2aea7996566851a4
> >>>
> >>> 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/round=
down2
> >>>
> >>>     This makes roundup2/rounddown2 type- and const-preserving and all=
ows
> >>>     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 gener=
ation.
> >>>     When using it with integer values there should be no change other=
 than
> >>>     the compiler checking that the alignment value is a valid power-o=
f-two.
> >>>
> >>>     I originally implemented these builtins for CHERI a few years ago=
 and
> >>>     they have been very useful for CheriBSD. However, they are also u=
seful
> >>>     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 alignme=
nt
> >>>     of pointers and integers. These builtins can be used to avoid rel=
ying
> >>>     on implementation-defined behavior of arithmetic on integers deri=
ved
> >>>     from pointers. Additionally, these builtins retain type informati=
on
> >>>     and, unlike bitwise arithmetic, they can perform semantic checkin=
g 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=3D98641
> >>>
> >>>     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 gen=
eration. */
> >>> +/* 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)) =3D=3D 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 t=
o
> >> 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))=3D=3D0)
> >>>
> >>>  /* 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 +=3D 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.
> >
> > https://reviews.freebsd.org/D28599 fixes this specific issue. One
> > reason for the typeof() is to allow using it with pointer types.
> > Currently there are no such uses, but we have some in CheriBSD.
> > Unfortunately +(x) would break that. (x)+0 should work for most cases,
> > but does break void*.
> > I believe the current approach only breaks with bitfields (which is
> > hopefully rare), so I think adding casts for GCC when roundup2() in
> > those cases might be the simplest solution.
>
> The comma operator might work here: typeof(((void)0,(x))).

Thanks, I hadn't considered that. It looks like GCC is happy with that
for both pointers and bitfields: https://godbolt.org/z/KvMEYs



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CA%2BZ_v8o4oQCFA9tGcs2Nhywq5xthJmnWXHLBhtJN0-x-ppFx9A>