From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lf1-x12f.google.com (mail-lf1-x12f.google.com [IPv6:2a00:1450:4864:20::12f]) by sourceware.org (Postfix) with ESMTPS id 3BC193858C98 for ; Mon, 20 Nov 2023 07:47:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3BC193858C98 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3BC193858C98 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::12f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700466448; cv=none; b=er9dEZAiIXWU9dwGJzrQmynbQYJJrtf0KxSt1MhRmQ1Q57AkU0RjuIPTbuGeaVeZIafKhIolb+jdV2nJSfxTYAp6K3dSWSb63FV41E4WEhiYESQmsALbm7Ftt0t+9KnJFlObUZRxE5KzFzyg8xNlo3SRHKwvrye8x6DiLBzsMSA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700466448; c=relaxed/simple; bh=fObYSeZgxdz+cPAzWooPUMJ7wmrNcKh7MoHJ4Wi6jUE=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=g1i9qJ3EHDTpvlocYBGPCxRa1h8xLRy35WXOWKHYQSBBAnbk8j/oFnLDYU4W4GUEX7Qvdc8SE3vQ5GR0rQbw9FJtmlCns5WxYVqB4A2sBTMS3eLO2WaRX56XrPq5/dBJaEdmIU+M6hBvsqkiyGnXndr6fBAmFiow80vIUR+rdJ8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-lf1-x12f.google.com with SMTP id 2adb3069b0e04-507bd644a96so5624804e87.3 for ; Sun, 19 Nov 2023 23:47:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700466445; x=1701071245; darn=gcc.gnu.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=JLnVoscWcGNmfbmVNV6UihyMDnfXJ6PzTVLY8aldBwI=; b=KaSjQXfrIS7s0pKkQPg9ZaQ0K+TFwOviEUGOUobsTKIY7njdFmbFHD6xGRP997ot/b VPlNfhgvvi2qbcUh1yMWbj2oSu/XOc1EKtKxXiFowX3I4DspJUD3rW029H4OH+Dy4dcU jvOX1fnFi3ipMCg4jg5/swsPQD7gVsvHx4b5tHa1eHg6J3gr7l4wDtHc0AsUEybH0qYP II9K0+xjvN9v3sZds35lBtm/gJfkwRGFbC62HUpuyKNlILcxNJkssXcckaITTVe62/N6 cUzac9q6DHETuWEun6Elhfw3kcKGIbAGd8KEIZwHfAG4qPkXFsB3/VdebolzcT4I5sTv XOZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700466445; x=1701071245; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JLnVoscWcGNmfbmVNV6UihyMDnfXJ6PzTVLY8aldBwI=; b=gUdLTCnn3iKlOZAwtwuTcLhf6SzUZYu3zgChKTiIqm2s0MyQ6lqEppltaeX+TeS9VT 3ETaVAX8jqY733aq8cp2rJAan0kO/uGhK2OXe295d2wq0UIlYDUSEKfkeR0W9AtzsBju Y3cUjEoUenOk7TLEpBkbkF9s+p5AFQrmc8138kh6VkufKtl/5xlcb4/vlpNHmDi8r26t 1zZ62peNEKb+uqkO8ETz9lJaWpNdArp7bbP6Ro6oSaYgQx0A0HBkatjpjQT4GBouccaZ tMptU2ApcVgIF686SixldC7BiWA3V8iOR7yF/z6VEfvX/+85rBZa5Wo606wl3z2Np1M6 w81Q== X-Gm-Message-State: AOJu0Yzgw91flri36df2Zxnb5POwCUpTpp62nkWDkWqm8RNTzwJQLchR Pp9UG0WuCadwgNCQpsXwopWhwZMx50rZm2QmBdZbgaBK X-Google-Smtp-Source: AGHT+IFZrhEbGk5y6rmaxcVKZClFwHP+uThMUCE728AEtYCOvd72uQOMN3nCgTw3LFnHRr+mY71ywVNq8TQT7jcqqTI= X-Received: by 2002:a19:6712:0:b0:50a:764d:7de9 with SMTP id b18-20020a196712000000b0050a764d7de9mr3897433lfc.66.1700466444387; Sun, 19 Nov 2023 23:47:24 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Richard Biener Date: Mon, 20 Nov 2023 08:43:46 +0100 Message-ID: Subject: Re: [PATCH] c: Add __builtin_bit_complement To: Jakub Jelinek Cc: "Joseph S. Myers" , gcc-patches@gcc.gnu.org, Florian Weimer Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Sat, Nov 18, 2023 at 8:38=E2=80=AFPM Jakub Jelinek wr= ote: > > Hi! > > Another obstackle mentioned in the > https://sourceware.org/pipermail/libc-alpha/2023-November/152819.html > thread is that half of the stdc_{leading,trailing}_{zeros,ones}, > stdc_first_{leading,trailing}_{zero,one} and stdc_count_{zeros,ones} > type-generic macros actually need to use the __builtin_*g type-generic > builtins on inverted values, but need to use > (__typeof (value)) ~(value) > for that, because if value has unsigned char or unsigned short type, > it is promoted to int with the ~ operator, but that suffers from the > nested macros problem as well. > > The following patch adds a C only builtin (if we'd want to make > stdbit.h work in C++, I think best would be to use a function template), > especially because the builtin needs a type-generic return type, > which is functionally equivalent to (__typeof (arg)) ~(arg). > > Ok for trunk if it passes bootstrap/regtest? And for this I suppose a "not promoting 'auto'" might be more generally useful? So _Unprom_auto tem =3D arg; (__typeof (tem))~tem; then? > > 2023-11-18 Jakub Jelinek > > gcc/ > * doc/extend.texi (__builtin_bit_complement): Document. > gcc/c-family/ > * c-common.h (enum rid): Add RID_BUILTIN_BIT_COMPLEMENT. > * c-common.cc (c_common_reswords): Add __builtin_bit_complement. > Move __builtin_assoc_barrier alphabetically. > gcc/c/ > * c-parser.cc (c_parser_postfix_expression): Handle > RID_BUILTIN_BIT_COMPLEMENT. > * c-decl.cc (names_builtin_p): Likewise. Move > RID_BUILTIN_ASSOC_BARRIER alphabetically. > gcc/testsuite/ > * gcc.dg/builtin-bit-complement-1.c: New test. > * gcc.dg/builtin-bit-complement-2.c: New test. > > --- gcc/doc/extend.texi.jj 2023-11-18 13:17:40.982551766 +0100 > +++ gcc/doc/extend.texi 2023-11-18 18:39:24.303561182 +0100 > @@ -15066,6 +15066,14 @@ unsigned integer (standard, extended or > promotions are performed on the argument. > @enddefbuiltin > > +@defbuiltin{@var{type} __builtin_bit_complement (@var{type} @var{arg})} > +The @code{__builtin_bit_complement} function is available only > +in C. It is type-generic, the argument can be any integral type, and > +is equivalent to @code{(__typeof (@var{arg})) ~(@var{arg})}, except that > +there is no need to specify the argument tokens twice. No integral argu= ment > +promotions are performed on the argument. > +@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-09 09:04:18.422546151 +0100 > +++ gcc/c-family/c-common.h 2023-11-18 17:05:00.223049400 +0100 > @@ -110,6 +110,7 @@ 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_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 13:20:55.751844490 +0100 > +++ gcc/c-family/c-common.cc 2023-11-18 17:03:17.838466559 +0100 > @@ -380,7 +380,9 @@ 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_bit_complement", RID_BUILTIN_BIT_COMPLEMENT, D_CONLY }, > { "__builtin_call_with_static_chain", > RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY }, > { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY }, > @@ -388,7 +390,6 @@ 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_tgmath", RID_BUILTIN_TGMATH, D_CONLY }, > --- gcc/c/c-parser.cc.jj 2023-11-11 08:51:54.324206082 +0100 > +++ gcc/c/c-parser.cc 2023-11-18 17:16:23.228591823 +0100 > @@ -11743,6 +11743,46 @@ c_parser_postfix_expression (c_parser *p > set_c_expr_source_range (&expr, start_loc, end_loc); > } > break; > + case RID_BUILTIN_BIT_COMPLEMENT: > + { > + vec *cexpr_list; > + c_expr_t *arg_p; > + location_t close_paren_loc; > + > + c_parser_consume_token (parser); > + if (!c_parser_get_builtin_args (parser, > + "__builtin_bit_complement", > + &cexpr_list, false, > + &close_paren_loc)) > + { > + expr.set_error (); > + break; > + } > + > + if (vec_safe_length (cexpr_list) !=3D 1) > + { > + error_at (loc, "wrong number of arguments to " > + "%<__builtin_bit_complement%>"); > + expr.set_error (); > + break; > + } > + > + arg_p =3D &(*cexpr_list)[0]; > + *arg_p =3D convert_lvalue_to_rvalue (loc, *arg_p, true, true)= ; > + if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p->value))) > + { > + error_at (loc, "%<__builtin_bit_complement%> operand " > + "not an integral type"); > + expr.set_error (); > + break; > + } > + expr.value > + =3D build1_loc (loc, BIT_NOT_EXPR, > + TYPE_MAIN_VARIANT (TREE_TYPE (arg_p->value)), > + arg_p->value); > + set_c_expr_source_range (&expr, loc, close_paren_loc); > + break; > + } > case RID_AT_SELECTOR: > { > gcc_assert (c_dialect_objc ()); > --- gcc/c/c-decl.cc.jj 2023-11-09 09:04:18.463545570 +0100 > +++ gcc/c/c-decl.cc 2023-11-18 17:31:39.298880201 +0100 > @@ -11370,11 +11370,12 @@ names_builtin_p (const char *name) > functions. */ > switch (C_RID_CODE (id)) > { > + case RID_BUILTIN_ASSOC_BARRIER: > + case RID_BUILTIN_BIT_COMPLEMENT: > case RID_BUILTIN_CONVERTVECTOR: > case RID_BUILTIN_HAS_ATTRIBUTE: > case RID_BUILTIN_SHUFFLE: > case RID_BUILTIN_SHUFFLEVECTOR: > - case RID_BUILTIN_ASSOC_BARRIER: > case RID_CHOOSE_EXPR: > case RID_OFFSETOF: > case RID_TYPES_COMPATIBLE_P: > --- gcc/testsuite/gcc.dg/builtin-bit-complement-1.c.jj 2023-11-18 17:39:= 47.748104287 +0100 > +++ gcc/testsuite/gcc.dg/builtin-bit-complement-1.c 2023-11-18 18:33:= 08.700744489 +0100 > @@ -0,0 +1,87 @@ > +/* { dg-do run } */ > +/* { dg-options "-std=3Dc11" } */ > + > +#define expr_has_type(e, t) _Generic (e, default : 0, t : 1) > +enum E { E0, E1 }; > + > +int > +main () > +{ > + if (__builtin_bit_complement ((unsigned char) 0) !=3D (unsigned char) = ~(unsigned char) 0 > + || __builtin_bit_complement ((unsigned char) 0x33) !=3D (unsigned = char) ~(unsigned char) 0x33 > + || !expr_has_type (__builtin_bit_complement ((unsigned char) 0), u= nsigned char) > + || __builtin_bit_complement ((unsigned short) 0) !=3D (unsigned sh= ort) ~(unsigned short) 0 > + || __builtin_bit_complement ((unsigned short) 0x5555) !=3D (unsign= ed short) ~(unsigned short) 0x5555 > + || !expr_has_type (__builtin_bit_complement ((unsigned short) 0), = unsigned short) > + || __builtin_bit_complement (0U) !=3D ~0U > + || __builtin_bit_complement (0xaaaaU) !=3D ~0xaaaaU > + || !expr_has_type (__builtin_bit_complement (0U), unsigned int) > + || __builtin_bit_complement (0UL) !=3D ~0UL > + || __builtin_bit_complement (0xaaaaaaaaUL) !=3D ~0xaaaaaaaaUL > + || !expr_has_type (__builtin_bit_complement (0UL), unsigned long) > + || __builtin_bit_complement (0ULL) !=3D ~0ULL > + || __builtin_bit_complement (0xaaaaaaaa55555555ULL) !=3D ~0xaaaaaa= aa55555555ULL > + || !expr_has_type (__builtin_bit_complement (0ULL), unsigned long = long) > + || __builtin_bit_complement ((signed char) 0) !=3D (signed char) ~= (signed char) 0 > + || __builtin_bit_complement ((signed char) 0x33) !=3D (signed char= ) ~(signed char) 0x33 > + || !expr_has_type (__builtin_bit_complement ((signed char) 0), sig= ned char) > + || __builtin_bit_complement ((signed short) 0) !=3D (signed short)= ~(signed short) 0 > + || __builtin_bit_complement ((signed short) 0x5555) !=3D (signed s= hort) ~(signed short) 0x5555 > + || !expr_has_type (__builtin_bit_complement ((signed short) 0), si= gned short) > + || __builtin_bit_complement (0) !=3D ~0 > + || __builtin_bit_complement (0x5aaa) !=3D ~0x5aaa > + || !expr_has_type (__builtin_bit_complement (0), signed int) > + || __builtin_bit_complement (0L) !=3D ~0L > + || __builtin_bit_complement (0x5aaaaaaaL) !=3D ~0x5aaaaaaaL > + || !expr_has_type (__builtin_bit_complement (0L), signed long) > + || __builtin_bit_complement (0LL) !=3D ~0LL > + || __builtin_bit_complement (0x5aaaaaaa55555555LL) !=3D ~0x5aaaaaa= a55555555LL > + || !expr_has_type (__builtin_bit_complement (0LL), signed long lon= g) > + || __builtin_bit_complement ((_Bool) 0) !=3D (_Bool) 1 > + || __builtin_bit_complement ((_Bool) 1) !=3D (_Bool) 0 > + || !expr_has_type (__builtin_bit_complement ((_Bool) 0), _Bool) > + || __builtin_bit_complement ((enum E) E0) !=3D (enum E) ~0 > + || __builtin_bit_complement ((enum E) E1) !=3D (enum E) ~1 > + || !expr_has_type (__builtin_bit_complement ((enum E) E0), enum E)= ) > + __builtin_abort (); > +#if __SIZEOF_INT128__ > + if (__builtin_bit_complement ((unsigned __int128) 0) !=3D ~(unsigned _= _int128) 0 > + || __builtin_bit_complement ((unsigned __int128) 0xaaaaaaaa5555555= 5ULL) !=3D ~(unsigned __int128) 0xaaaaaaaa55555555ULL > + || !expr_has_type (__builtin_bit_complement ((unsigned __int128) 0= ), unsigned __int128) > + || __builtin_bit_complement ((signed __int128) 0) !=3D ~(signed __= int128) 0 > + || __builtin_bit_complement ((signed __int128) 0x5aaaaaaa55555555L= L) !=3D ~(signed __int128) 0x5aaaaaaa55555555LL > + || !expr_has_type (__builtin_bit_complement ((signed __int128) 0),= signed __int128)) > + __builtin_abort (); > +#endif > +#if __has_builtin (__builtin_bit_complement) !=3D 1 > +#error __builtin_bit_complement not implemented > +#endif > + unsigned char a =3D 0; > + if (__builtin_bit_complement (a++) !=3D (unsigned char) ~(unsigned cha= r) 0 > + || a !=3D 1) > + __builtin_abort (); > + if (!expr_has_type (__builtin_bit_complement (a++), unsigned char) > + || a !=3D 1) > + __builtin_abort (); > + unsigned short b =3D 0; > + if (__builtin_bit_complement (b++) !=3D (unsigned short) ~(unsigned sh= ort) 0 > + || b !=3D 1) > + __builtin_abort (); > + if (!expr_has_type (__builtin_bit_complement (b++), unsigned short) > + || b !=3D 1) > + __builtin_abort (); > + int c =3D 0; > + if (__builtin_bit_complement (c++) !=3D ~0 > + || c !=3D 1) > + __builtin_abort (); > + if (!expr_has_type (__builtin_bit_complement (c++), int) > + || c !=3D 1) > + __builtin_abort (); > +#if __BITINT_MAXWIDTH__ >=3D 256 > + if (__builtin_bit_complement (0uwb) !=3D ~0uwb > + || !expr_has_type (__builtin_bit_complement (0uwb), unsigned _BitI= nt(1)) > + || __builtin_bit_complement ((signed _BitInt(256)) 0) !=3D ~(signe= d _BitInt(256)) 0 > + || !expr_has_type (__builtin_bit_complement ((signed _BitInt(256))= 0), signed _BitInt(256))) > + __builtin_abort (); > +#endif > +} > --- gcc/testsuite/gcc.dg/builtin-bit-complement-2.c.jj 2023-11-18 18:26:= 01.871634733 +0100 > +++ gcc/testsuite/gcc.dg/builtin-bit-complement-2.c 2023-11-18 18:32:= 55.448927364 +0100 > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "" } */ > + > +void > +foo (void) > +{ > + typedef int V __attribute__ ((vector_size (4 * sizeof (int)))); > + struct S { int s; }; > + __builtin_bit_complement (0.0f); /* { dg-error "'__builtin_bit_com= plement' operand not an integral type" } */ > + __builtin_bit_complement (0.0); /* { dg-error "'__builtin_bit_com= plement' operand not an integral type" } */ > + __builtin_bit_complement (0.0L); /* { dg-error "'__builtin_bit_com= plement' operand not an integral type" } */ > + __builtin_bit_complement ((V) {}); /* { dg-error "'__builtin_bit_com= plement' operand not an integral type" } */ > + __builtin_bit_complement ((struct S) { 0 }); /* { dg-error "'__builtin= _bit_complement' operand not an integral type" } */ > + __builtin_bit_complement (); /* { dg-error "wrong number of ar= guments to '__builtin_bit_complement'" } */ > + __builtin_bit_complement (0, 0); /* { dg-error "wrong number of ar= guments to '__builtin_bit_complement'" } */ > +} > > Jakub >