Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
On Thu, Nov 23, 2023 at 12:09:05AM +, Joseph Myers wrote: > OK with tests added for unsigned _BitInt(1). Specifically, unsigned > _BitInt(1) is a bit of a degenerate case for stdc_bit_ceil (always > returning 1 after evaluating the argument's side effects); I think the > code that builds of constant 2 of that type (a constant only used in dead > code) should still work (and produce a constant 0), and that the > documentation is also still correct in the case where converting 2 to the > type produces 0, but given those degeneracies I think it's worth testing > unsigned _BitInt(1) with these functions to make sure they do behave as > expected. Thanks, here is incremental diff between what was posted and what was committed: --- gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c 2023-11-20 16:25:22.548758830 +0100 +++ gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c 2023-11-23 10:08:50.133761681 +0100 @@ -668,6 +668,87 @@ __builtin_abort (); if (__builtin_stdc_has_single_bit (b++) || b != 14) __builtin_abort (); +#if __BITINT_MAXWIDTH__ >= 64 + if (__builtin_stdc_leading_zeros (0uwb) != 1 + || !expr_has_type (__builtin_stdc_leading_zeros (0uwb), unsigned int) + || __builtin_stdc_leading_zeros (1uwb) != 0 + || !expr_has_type (__builtin_stdc_leading_zeros (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_leading_ones (0uwb) != 0 + || !expr_has_type (__builtin_stdc_leading_ones (0uwb), unsigned int) + || __builtin_stdc_leading_ones (1uwb) != 1 + || !expr_has_type (__builtin_stdc_leading_ones (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_trailing_zeros (0uwb) != 1 + || !expr_has_type (__builtin_stdc_trailing_zeros (0uwb), unsigned int) + || __builtin_stdc_trailing_zeros (1uwb) != 0 + || !expr_has_type (__builtin_stdc_trailing_zeros (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_trailing_ones (0uwb) != 0 + || !expr_has_type (__builtin_stdc_trailing_ones (0uwb), unsigned int) + || __builtin_stdc_trailing_ones (1uwb) != 1 + || !expr_has_type (__builtin_stdc_trailing_ones (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_first_leading_zero (0uwb) != 1 + || !expr_has_type (__builtin_stdc_first_leading_zero (0uwb), unsigned int) + || __builtin_stdc_first_leading_zero (1uwb) != 0 + || !expr_has_type (__builtin_stdc_first_leading_zero (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_first_leading_one (0uwb) != 0 + || !expr_has_type (__builtin_stdc_first_leading_one (0uwb), unsigned int) + || __builtin_stdc_first_leading_one (1uwb) != 1 + || !expr_has_type (__builtin_stdc_first_leading_one (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_first_trailing_zero (0uwb) != 1 + || !expr_has_type (__builtin_stdc_first_trailing_zero (0uwb), unsigned int) + || __builtin_stdc_first_trailing_zero (1uwb) != 0 + || !expr_has_type (__builtin_stdc_first_trailing_zero (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_first_trailing_one (0uwb) != 0 + || !expr_has_type (__builtin_stdc_first_trailing_one (0uwb), unsigned int) + || __builtin_stdc_first_trailing_one (1uwb) != 1 + || !expr_has_type (__builtin_stdc_first_trailing_one (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_count_zeros (0uwb) != 1 + || !expr_has_type (__builtin_stdc_count_zeros (0uwb), unsigned int) + || __builtin_stdc_count_zeros (1uwb) != 0 + || !expr_has_type (__builtin_stdc_count_zeros (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_count_ones (0uwb) != 0 + || !expr_has_type (__builtin_stdc_count_ones (0uwb), unsigned int) + || __builtin_stdc_count_ones (1uwb) != 1 + || !expr_has_type (__builtin_stdc_count_ones (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_has_single_bit (0uwb) + || !expr_has_type (__builtin_stdc_has_single_bit (0uwb), _Bool) + || !__builtin_stdc_has_single_bit (1uwb) + || !expr_has_type (__builtin_stdc_has_single_bit (1uwb), _Bool)) +__builtin_abort (); + if (__builtin_stdc_bit_width (0uwb) != 0 + || !expr_has_type (__builtin_stdc_bit_width (0uwb), unsigned int) + || __builtin_stdc_bit_width (1uwb) != 1 + || !expr_has_type (__builtin_stdc_bit_width (1uwb), unsigned int)) +__builtin_abort (); + if (__builtin_stdc_bit_floor (0uwb) != 0 + || !expr_has_type (__builtin_stdc_bit_floor (0uwb), unsigned _BitInt(1)) + || __builtin_stdc_bit_floor (1uwb) != 1 + || !expr_has_type (__builtin_stdc_bit_floor (1uwb), unsigned _BitInt(1))) +__builtin_abort (); + if (__builtin_stdc_bit_ceil (0uwb) != 1 + || !expr_has_type (__builtin_stdc_bit_ceil (0uwb), unsigned _BitInt(1)) + || __builtin_stdc_bit_ceil (1uwb) != 1 + || !expr_has_type (__builtin_stdc_bit_ceil (1uwb), unsigned _BitInt(1))) +__builtin_abort
Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
On Mon, 20 Nov 2023, Jakub Jelinek wrote: > On Mon, Nov 20, 2023 at 04:03:07PM +0100, Jakub Jelinek wrote: > > > Note that stdc_bit_ceil now has defined behavior (return 0) on overflow: > > > CD2 comment FR-135 was accepted for the DIS at the June WG14 meeting. > > > This affects both the documentation and the implementation, as they need > > > to avoid an undefined shift by the width of the type. That's why my > > > stdbit.h implementations have two shifts (not claiming that's necessarily > > > the optimal way of ensuring the correct result in the overflow case). > > > > > > return __x <= 1 ? 1 : ((uint64_t) 1) << (__bw64_inline (__x - 1) - 1) > > > << 1; > > > > Given the feedback from Richi I've in the meantime reworked the patch to > > add all 14 builtins (but because the enum rid is very close to 256 values > > and with 14 new ones was already 7 too many, used one RID value for all 14 > > builtins (different spellings)). > > > > Will need to rework it for CD2 FR-135 then... > > Here it is updated to use that > x <= 1 ? 1 : ((type) 2) << (prec - 1 - __builtin_clzg ((type) (x - 1))) > I've mentioned. > > 2023-11-20 Jakub Jelinek > > gcc/ > * doc/extend.texi (__builtin_stdc_bit_ceil, __builtin_stdc_bit_floor, > __builtin_stdc_bit_width, __builtin_stdc_count_ones, > __builtin_stdc_count_zeros, __builtin_stdc_first_leading_one, > __builtin_stdc_first_leading_zero, __builtin_stdc_first_trailing_one, > __builtin_stdc_first_trailing_zero, __builtin_stdc_has_single_bit, > __builtin_stdc_leading_ones, __builtin_stdc_leading_zeros, > __builtin_stdc_trailing_ones, __builtin_stdc_trailing_zeros): Document. > gcc/c-family/ > * c-common.h (enum rid): Add RID_BUILTIN_STDC: New. > * c-common.cc (c_common_reswords): Add __builtin_stdc_bit_ceil, > __builtin_stdc_bit_floor, __builtin_stdc_bit_width, > __builtin_stdc_count_ones, __builtin_stdc_count_zeros, > __builtin_stdc_first_leading_one, __builtin_stdc_first_leading_zero, > __builtin_stdc_first_trailing_one, __builtin_stdc_first_trailing_zero, > __builtin_stdc_has_single_bit, __builtin_stdc_leading_ones, > __builtin_stdc_leading_zeros, __builtin_stdc_trailing_ones and > __builtin_stdc_trailing_zeros. Move __builtin_assoc_barrier > alphabetically earlier. > gcc/c/ > * c-parser.cc (c_parser_postfix_expression): Handle RID_BUILTIN_STDC. > * c-decl.cc (names_builtin_p): Likewise. > gcc/testsuite/ > * gcc.dg/builtin-stdc-bit-1.c: New test. > * gcc.dg/builtin-stdc-bit-2.c: New test. OK with tests added for unsigned _BitInt(1). Specifically, unsigned _BitInt(1) is a bit of a degenerate case for stdc_bit_ceil (always returning 1 after evaluating the argument's side effects); I think the code that builds of constant 2 of that type (a constant only used in dead code) should still work (and produce a constant 0), and that the documentation is also still correct in the case where converting 2 to the type produces 0, but given those degeneracies I think it's worth testing unsigned _BitInt(1) with these functions to make sure they do behave as expected. -- Joseph S. Myers jos...@codesourcery.com
Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
On Mon, 20 Nov 2023, Jakub Jelinek wrote: > > Note that stdc_bit_ceil now has defined behavior (return 0) on overflow: > > CD2 comment FR-135 was accepted for the DIS at the June WG14 meeting. > > This affects both the documentation and the implementation, as they need > > to avoid an undefined shift by the width of the type. That's why my > > stdbit.h implementations have two shifts (not claiming that's necessarily > > the optimal way of ensuring the correct result in the overflow case). > > > > return __x <= 1 ? 1 : ((uint64_t) 1) << (__bw64_inline (__x - 1) - 1) << > > 1; > > So > return __x <= 1 ? 1 : ((uint64_t) 2) << (__bw64_inline (__x - 1) - 1); > then? Yes, that looks better than my version, thanks. -- Joseph S. Myers jos...@codesourcery.com
Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
On Mon, Nov 20, 2023 at 04:29:47PM +0100, Jakub Jelinek wrote: > On Mon, Nov 20, 2023 at 04:03:07PM +0100, Jakub Jelinek wrote: > > > Note that stdc_bit_ceil now has defined behavior (return 0) on overflow: > > > CD2 comment FR-135 was accepted for the DIS at the June WG14 meeting. > > > This affects both the documentation and the implementation, as they need > > > to avoid an undefined shift by the width of the type. That's why my > > > stdbit.h implementations have two shifts (not claiming that's necessarily > > > the optimal way of ensuring the correct result in the overflow case). > > > > > > return __x <= 1 ? 1 : ((uint64_t) 1) << (__bw64_inline (__x - 1) - 1) > > > << 1; > > > > Given the feedback from Richi I've in the meantime reworked the patch to > > add all 14 builtins (but because the enum rid is very close to 256 values > > and with 14 new ones was already 7 too many, used one RID value for all 14 > > builtins (different spellings)). > > > > Will need to rework it for CD2 FR-135 then... > > Here it is updated to use that > x <= 1 ? 1 : ((type) 2) << (prec - 1 - __builtin_clzg ((type) (x - 1))) > I've mentioned. Now successfully bootstrapped/regtested on x86_64-linux and i686-linux on top of the https://gcc.gnu.org/pipermail/gcc-patches/2023-November/637540.html patch (the bug was discovered while working on this patch). > 2023-11-20 Jakub Jelinek > > gcc/ > * doc/extend.texi (__builtin_stdc_bit_ceil, __builtin_stdc_bit_floor, > __builtin_stdc_bit_width, __builtin_stdc_count_ones, > __builtin_stdc_count_zeros, __builtin_stdc_first_leading_one, > __builtin_stdc_first_leading_zero, __builtin_stdc_first_trailing_one, > __builtin_stdc_first_trailing_zero, __builtin_stdc_has_single_bit, > __builtin_stdc_leading_ones, __builtin_stdc_leading_zeros, > __builtin_stdc_trailing_ones, __builtin_stdc_trailing_zeros): Document. > gcc/c-family/ > * c-common.h (enum rid): Add RID_BUILTIN_STDC: New. > * c-common.cc (c_common_reswords): Add __builtin_stdc_bit_ceil, > __builtin_stdc_bit_floor, __builtin_stdc_bit_width, > __builtin_stdc_count_ones, __builtin_stdc_count_zeros, > __builtin_stdc_first_leading_one, __builtin_stdc_first_leading_zero, > __builtin_stdc_first_trailing_one, __builtin_stdc_first_trailing_zero, > __builtin_stdc_has_single_bit, __builtin_stdc_leading_ones, > __builtin_stdc_leading_zeros, __builtin_stdc_trailing_ones and > __builtin_stdc_trailing_zeros. Move __builtin_assoc_barrier > alphabetically earlier. > gcc/c/ > * c-parser.cc (c_parser_postfix_expression): Handle RID_BUILTIN_STDC. > * c-decl.cc (names_builtin_p): Likewise. > gcc/testsuite/ > * gcc.dg/builtin-stdc-bit-1.c: New test. > * gcc.dg/builtin-stdc-bit-2.c: New test. Jakub
Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
On Mon, Nov 20, 2023 at 04:03:07PM +0100, Jakub Jelinek wrote: > > Note that stdc_bit_ceil now has defined behavior (return 0) on overflow: > > CD2 comment FR-135 was accepted for the DIS at the June WG14 meeting. > > This affects both the documentation and the implementation, as they need > > to avoid an undefined shift by the width of the type. That's why my > > stdbit.h implementations have two shifts (not claiming that's necessarily > > the optimal way of ensuring the correct result in the overflow case). > > > > return __x <= 1 ? 1 : ((uint64_t) 1) << (__bw64_inline (__x - 1) - 1) << > > 1; > > Given the feedback from Richi I've in the meantime reworked the patch to > add all 14 builtins (but because the enum rid is very close to 256 values > and with 14 new ones was already 7 too many, used one RID value for all 14 > builtins (different spellings)). > > Will need to rework it for CD2 FR-135 then... Here it is updated to use that x <= 1 ? 1 : ((type) 2) << (prec - 1 - __builtin_clzg ((type) (x - 1))) I've mentioned. 2023-11-20 Jakub Jelinek gcc/ * doc/extend.texi (__builtin_stdc_bit_ceil, __builtin_stdc_bit_floor, __builtin_stdc_bit_width, __builtin_stdc_count_ones, __builtin_stdc_count_zeros, __builtin_stdc_first_leading_one, __builtin_stdc_first_leading_zero, __builtin_stdc_first_trailing_one, __builtin_stdc_first_trailing_zero, __builtin_stdc_has_single_bit, __builtin_stdc_leading_ones, __builtin_stdc_leading_zeros, __builtin_stdc_trailing_ones, __builtin_stdc_trailing_zeros): Document. gcc/c-family/ * c-common.h (enum rid): Add RID_BUILTIN_STDC: New. * c-common.cc (c_common_reswords): Add __builtin_stdc_bit_ceil, __builtin_stdc_bit_floor, __builtin_stdc_bit_width, __builtin_stdc_count_ones, __builtin_stdc_count_zeros, __builtin_stdc_first_leading_one, __builtin_stdc_first_leading_zero, __builtin_stdc_first_trailing_one, __builtin_stdc_first_trailing_zero, __builtin_stdc_has_single_bit, __builtin_stdc_leading_ones, __builtin_stdc_leading_zeros, __builtin_stdc_trailing_ones and __builtin_stdc_trailing_zeros. Move __builtin_assoc_barrier alphabetically earlier. gcc/c/ * c-parser.cc (c_parser_postfix_expression): Handle RID_BUILTIN_STDC. * c-decl.cc (names_builtin_p): Likewise. gcc/testsuite/ * gcc.dg/builtin-stdc-bit-1.c: New test. * gcc.dg/builtin-stdc-bit-2.c: New test. --- gcc/c-family/c-common.h.jj 2023-11-20 09:49:34.760674813 +0100 +++ gcc/c-family/c-common.h 2023-11-20 13:55:50.691612365 +0100 @@ -106,10 +106,10 @@ enum rid /* C extensions */ RID_ASM, RID_TYPEOF, RID_TYPEOF_UNQUAL, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG, - RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR, - RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, - RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH, - RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER, + RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,RID_CHOOSE_EXPR, + RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, + RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH, + RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER, RID_BUILTIN_STDC, RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, /* TS 18661-3 keywords, in the same sequence as the TI_* values. */ --- gcc/c-family/c-common.cc.jj 2023-11-20 09:49:34.691675777 +0100 +++ gcc/c-family/c-common.cc2023-11-20 13:55:40.104758727 +0100 @@ -380,6 +380,7 @@ const struct c_common_resword c_common_r { "__attribute__", RID_ATTRIBUTE, 0 }, { "__auto_type", RID_AUTO_TYPE, D_CONLY }, { "__builtin_addressof", RID_ADDRESSOF, D_CXXONLY }, + { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 }, { "__builtin_bit_cast", RID_BUILTIN_BIT_CAST, D_CXXONLY }, { "__builtin_call_with_static_chain", RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY }, @@ -388,9 +389,22 @@ const struct c_common_resword c_common_r { "__builtin_convertvector", RID_BUILTIN_CONVERTVECTOR, 0 }, { "__builtin_has_attribute", RID_BUILTIN_HAS_ATTRIBUTE, 0 }, { "__builtin_launder", RID_BUILTIN_LAUNDER, D_CXXONLY }, - { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 }, { "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 }, { "__builtin_shufflevector", RID_BUILTIN_SHUFFLEVECTOR, 0 }, + { "__builtin_stdc_bit_ceil", RID_BUILTIN_STDC, D_CONLY }, + { "__builtin_stdc_bit_floor", RID_BUILTIN_STDC, D_CONLY }, + { "__builtin_stdc_bit_width", RID_BUILTIN_STDC, D_CONLY }, + { "__builtin_stdc_count_ones", RID_BUILTIN_STDC, D_CONLY }, + { "__builtin_stdc_count_zeros", RID_BUILTIN_STDC, D_CONLY }, + { "__builtin_stdc_first_leading_one", RID_BUILTIN_STDC, D_CONLY }, + { "__builtin_stdc_first_leading_zero", RID_BUILTIN_STDC, D_CONLY }, + { "__builtin_std
Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
On Mon, Nov 20, 2023 at 02:55:33PM +, Joseph Myers wrote: > On Sat, 18 Nov 2023, Jakub Jelinek wrote: > > > +@defbuiltin{@var{type} __builtin_stdc_bit_ceil (@var{type} @var{arg})} > > +The @code{__builtin_stdc_bit_ceil} function is available only > > +in C. It is type-generic, the argument can be any unsigned integer > > +(standard, extended or bit-precise). No integral argument promotions are > > +performed on the argument. It is equivalent to > > +@code{@var{arg} <= 1 ? (@var{type}) 1 > > +: (@var{type}) 1 << (@var{prec} - __builtin_clzg ((@var{type}) (@var{arg} > > - 1)))} > > +where @var{prec} is bit width of @var{type}, except that side-effects > > +in @var{arg} are evaluated just once. > > +@enddefbuiltin > > Note that stdc_bit_ceil now has defined behavior (return 0) on overflow: > CD2 comment FR-135 was accepted for the DIS at the June WG14 meeting. > This affects both the documentation and the implementation, as they need > to avoid an undefined shift by the width of the type. That's why my > stdbit.h implementations have two shifts (not claiming that's necessarily > the optimal way of ensuring the correct result in the overflow case). > > return __x <= 1 ? 1 : ((uint64_t) 1) << (__bw64_inline (__x - 1) - 1) << 1; Given the feedback from Richi I've in the meantime reworked the patch to add all 14 builtins (but because the enum rid is very close to 256 values and with 14 new ones was already 7 too many, used one RID value for all 14 builtins (different spellings)). Will need to rework it for CD2 FR-135 then... 2023-11-20 Jakub Jelinek gcc/ * doc/extend.texi (__builtin_stdc_bit_ceil, __builtin_stdc_bit_floor, __builtin_stdc_bit_width, __builtin_stdc_count_ones, __builtin_stdc_count_zeros, __builtin_stdc_first_leading_one, __builtin_stdc_first_leading_zero, __builtin_stdc_first_trailing_one, __builtin_stdc_first_trailing_zero, __builtin_stdc_has_single_bit, __builtin_stdc_leading_ones, __builtin_stdc_leading_zeros, __builtin_stdc_trailing_ones, __builtin_stdc_trailing_zeros): Document. gcc/c-family/ * c-common.h (enum rid): Add RID_BUILTIN_STDC: New. * c-common.cc (c_common_reswords): Add __builtin_stdc_bit_ceil, __builtin_stdc_bit_floor, __builtin_stdc_bit_width, __builtin_stdc_count_ones, __builtin_stdc_count_zeros, __builtin_stdc_first_leading_one, __builtin_stdc_first_leading_zero, __builtin_stdc_first_trailing_one, __builtin_stdc_first_trailing_zero, __builtin_stdc_has_single_bit, __builtin_stdc_leading_ones, __builtin_stdc_leading_zeros, __builtin_stdc_trailing_ones and __builtin_stdc_trailing_zeros. Move __builtin_assoc_barrier alphabetically earlier. gcc/c/ * c-parser.cc (c_parser_postfix_expression): Handle RID_BUILTIN_STDC. * c-decl.cc (names_builtin_p): Likewise. gcc/testsuite/ * gcc.dg/builtin-stdc-bit-1.c: New test. * gcc.dg/builtin-stdc-bit-2.c: New test. --- gcc/c-family/c-common.h.jj 2023-11-20 09:49:34.760674813 +0100 +++ gcc/c-family/c-common.h 2023-11-20 13:55:50.691612365 +0100 @@ -106,10 +106,10 @@ enum rid /* C extensions */ RID_ASM, RID_TYPEOF, RID_TYPEOF_UNQUAL, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG, - RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR, - RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, - RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH, - RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER, + RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,RID_CHOOSE_EXPR, + RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, + RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH, + RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER, RID_BUILTIN_STDC, RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, /* TS 18661-3 keywords, in the same sequence as the TI_* values. */ --- gcc/c-family/c-common.cc.jj 2023-11-20 09:49:34.691675777 +0100 +++ gcc/c-family/c-common.cc2023-11-20 13:55:40.104758727 +0100 @@ -380,6 +380,7 @@ const struct c_common_resword c_common_r { "__attribute__", RID_ATTRIBUTE, 0 }, { "__auto_type", RID_AUTO_TYPE, D_CONLY }, { "__builtin_addressof", RID_ADDRESSOF, D_CXXONLY }, + { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 }, { "__builtin_bit_cast", RID_BUILTIN_BIT_CAST, D_CXXONLY }, { "__builtin_call_with_static_chain", RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY }, @@ -388,9 +389,22 @@ const struct c_common_resword c_common_r { "__builtin_convertvector", RID_BUILTIN_CONVERTVECTOR, 0 }, { "__builtin_has_attribute", RID_BUILTIN_HAS_ATTRIBUTE, 0 }, { "__builtin_launder", RID_BUILTIN_LAUNDER, D_CXXONLY }, - { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 }, { "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 }, { "__builtin_shuff
Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
On Mon, Nov 20, 2023 at 02:55:33PM +, Joseph Myers wrote: > On Sat, 18 Nov 2023, Jakub Jelinek wrote: > > > +@defbuiltin{@var{type} __builtin_stdc_bit_ceil (@var{type} @var{arg})} > > +The @code{__builtin_stdc_bit_ceil} function is available only > > +in C. It is type-generic, the argument can be any unsigned integer > > +(standard, extended or bit-precise). No integral argument promotions are > > +performed on the argument. It is equivalent to > > +@code{@var{arg} <= 1 ? (@var{type}) 1 > > +: (@var{type}) 1 << (@var{prec} - __builtin_clzg ((@var{type}) (@var{arg} > > - 1)))} > > +where @var{prec} is bit width of @var{type}, except that side-effects > > +in @var{arg} are evaluated just once. > > +@enddefbuiltin > > Note that stdc_bit_ceil now has defined behavior (return 0) on overflow: > CD2 comment FR-135 was accepted for the DIS at the June WG14 meeting. > This affects both the documentation and the implementation, as they need > to avoid an undefined shift by the width of the type. That's why my > stdbit.h implementations have two shifts (not claiming that's necessarily > the optimal way of ensuring the correct result in the overflow case). > > return __x <= 1 ? 1 : ((uint64_t) 1) << (__bw64_inline (__x - 1) - 1) << 1; So return __x <= 1 ? 1 : ((uint64_t) 2) << (__bw64_inline (__x - 1) - 1); then? Jakub
Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
On Sat, 18 Nov 2023, Jakub Jelinek wrote: > +@defbuiltin{@var{type} __builtin_stdc_bit_ceil (@var{type} @var{arg})} > +The @code{__builtin_stdc_bit_ceil} function is available only > +in C. It is type-generic, the argument can be any unsigned integer > +(standard, extended or bit-precise). No integral argument promotions are > +performed on the argument. It is equivalent to > +@code{@var{arg} <= 1 ? (@var{type}) 1 > +: (@var{type}) 1 << (@var{prec} - __builtin_clzg ((@var{type}) (@var{arg} - > 1)))} > +where @var{prec} is bit width of @var{type}, except that side-effects > +in @var{arg} are evaluated just once. > +@enddefbuiltin Note that stdc_bit_ceil now has defined behavior (return 0) on overflow: CD2 comment FR-135 was accepted for the DIS at the June WG14 meeting. This affects both the documentation and the implementation, as they need to avoid an undefined shift by the width of the type. That's why my stdbit.h implementations have two shifts (not claiming that's necessarily the optimal way of ensuring the correct result in the overflow case). return __x <= 1 ? 1 : ((uint64_t) 1) << (__bw64_inline (__x - 1) - 1) << 1; -- Joseph S. Myers jos...@codesourcery.com
[PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
Hi! For these 3 type-generic macros I'm out of ideas how to satisfy all the requirements (no use of ({ ... }), not expanding argument multiple times, not evaluating side-effects multiple times using some small building blocks, so the following patch introduces 3 new C only builtins which can be used to implement those macros. As a bonus, I think with this and previous 2 patches all the type-generic stdbit.h macros can be actually used in constant expressions. While in theory __builtin_stdc_bit_width builtin could be C/C++ in builtins.def, given that it has unsigned return type rather than the type-generic type, because it has very similar implementation to the other two and is not really useful for C++ I chose to implement all 3 in there. Ok for trunk if it passes bootstrap/regtest? 2023-11-18 Jakub Jelinek gcc/ * doc/extend.texi (__builtin_stdc_bit_width, __builtin_stdc_bit_floor, __builtin_stdc_bit_ceil): Document. gcc/c-family/ * c-common.h (enum rid): Add RID_BUILTIN_STDC_BIT_WIDTH, RID_BUILTIN_STDC_BIT_FLOOR and RID_BUILTIN_STDC_BIT_CEIL. * c-common.cc (c_common_reswords): Add __builtin_stdc_bit_width, __builtin_stdc_bit_floor and __builtin_stdc_bit_ceil. gcc/c/ * c-parser.cc (c_parser_postfix_expression): Handle RID_BUILTIN_STDC_BIT_WIDTH, RID_BUILTIN_STDC_BIT_FLOOR and RID_BUILTIN_STDC_BIT_CEIL. * c-decl.cc (names_builtin_p): Likewise. gcc/testsuite/ * gcc.dg/builtin-stdc-bit-1.c: New test. * gcc.dg/builtin-stdc-bit-2.c: New test. --- gcc/doc/extend.texi.jj 2023-11-18 19:29:08.056176234 +0100 +++ gcc/doc/extend.texi 2023-11-18 19:35:08.454176312 +0100 @@ -15074,6 +15074,37 @@ there is no need to specify the argument promotions are performed on the argument. @enddefbuiltin +@defbuiltin{unsigned int __builtin_stdc_bit_width (@var{type} @var{arg})} +The @code{__builtin_stdc_bit_width} function is available only +in C. It is type-generic, the argument can be any unsigned integer +(standard, extended or bit-precise). No integral argument promotions are +performed on the argument. It is equivalent to +@code{(unsigned int) (@var{prec} - __builtin_clzg (@var{arg}, @var{prec}))} +where @var{prec} is bit width of @var{type}. +@enddefbuiltin + +@defbuiltin{@var{type} __builtin_stdc_bit_floor (@var{type} @var{arg})} +The @code{__builtin_stdc_bit_floor} function is available only +in C. It is type-generic, the argument can be any unsigned integer +(standard, extended or bit-precise). No integral argument promotions are +performed on the argument. It is equivalent to +@code{@var{arg} == 0 ? (@var{type}) 0 +: (@var{type}) 1 << (@var{prec} - 1 - __builtin_clzg (@var{arg}))} +where @var{prec} is bit width of @var{type}, except that side-effects +in @var{arg} are evaluated just once. +@enddefbuiltin + +@defbuiltin{@var{type} __builtin_stdc_bit_ceil (@var{type} @var{arg})} +The @code{__builtin_stdc_bit_ceil} function is available only +in C. It is type-generic, the argument can be any unsigned integer +(standard, extended or bit-precise). No integral argument promotions are +performed on the argument. It is equivalent to +@code{@var{arg} <= 1 ? (@var{type}) 1 +: (@var{type}) 1 << (@var{prec} - __builtin_clzg ((@var{type}) (@var{arg} - 1)))} +where @var{prec} is bit width of @var{type}, except that side-effects +in @var{arg} are evaluated just once. +@enddefbuiltin + @defbuiltin{double __builtin_powi (double, int)} @defbuiltinx{float __builtin_powif (float, int)} @defbuiltinx{{long double} __builtin_powil (long double, int)} --- gcc/c-family/c-common.h.jj 2023-11-18 17:05:00.223049400 +0100 +++ gcc/c-family/c-common.h 2023-11-18 18:46:53.162346148 +0100 @@ -110,7 +110,8 @@ enum rid RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH, RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER, - RID_BUILTIN_BIT_COMPLEMENT, + RID_BUILTIN_BIT_COMPLEMENT, RID_BUILTIN_STDC_BIT_WIDTH, + RID_BUILTIN_STDC_BIT_CEIL, RID_BUILTIN_STDC_BIT_FLOOR, RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, /* TS 18661-3 keywords, in the same sequence as the TI_* values. */ --- gcc/c-family/c-common.cc.jj 2023-11-18 17:03:17.838466559 +0100 +++ gcc/c-family/c-common.cc2023-11-18 18:47:47.809588817 +0100 @@ -392,6 +392,9 @@ const struct c_common_resword c_common_r { "__builtin_launder", RID_BUILTIN_LAUNDER, D_CXXONLY }, { "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 }, { "__builtin_shufflevector", RID_BUILTIN_SHUFFLEVECTOR, 0 }, + { "__builtin_stdc_bit_ceil", RID_BUILTIN_STDC_BIT_CEIL, D_CONLY }, + { "__builtin_stdc_bit_floor", RID_BUILTIN_STDC_BIT_FLOOR, D_CONLY }, + { "__builtin_stdc_bit_width", RID_BUILTIN_STDC_BIT_WIDTH, D_CONLY }, { "__builtin_tgmath", RID_BUILTIN_TGMATH, D_CONLY }, { "__builtin_offsetof", RID_OFFSETOF, 0 }, { "__builtin_types_compatible_p", RID_TYPES_C