public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c: Add __builtin_bit_complement
@ 2023-11-18 19:37 Jakub Jelinek
  2023-11-20  7:43 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2023-11-18 19:37 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches, Florian Weimer

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?

2023-11-18  Jakub Jelinek  <jakub@redhat.com>

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 argument
+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<c_expr_t, va_gc> *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) != 1)
+	      {
+		error_at (loc, "wrong number of arguments to "
+			       "%<__builtin_bit_complement%>");
+		expr.set_error ();
+		break;
+	      }
+
+	    arg_p = &(*cexpr_list)[0];
+	    *arg_p = 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
+	      = 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=c11" } */
+
+#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) != (unsigned char) ~(unsigned char) 0
+      || __builtin_bit_complement ((unsigned char) 0x33) != (unsigned char) ~(unsigned char) 0x33
+      || !expr_has_type (__builtin_bit_complement ((unsigned char) 0), unsigned char)
+      || __builtin_bit_complement ((unsigned short) 0) != (unsigned short) ~(unsigned short) 0
+      || __builtin_bit_complement ((unsigned short) 0x5555) != (unsigned short) ~(unsigned short) 0x5555
+      || !expr_has_type (__builtin_bit_complement ((unsigned short) 0), unsigned short)
+      || __builtin_bit_complement (0U) != ~0U
+      || __builtin_bit_complement (0xaaaaU) != ~0xaaaaU
+      || !expr_has_type (__builtin_bit_complement (0U), unsigned int)
+      || __builtin_bit_complement (0UL) != ~0UL
+      || __builtin_bit_complement (0xaaaaaaaaUL) != ~0xaaaaaaaaUL
+      || !expr_has_type (__builtin_bit_complement (0UL), unsigned long)
+      || __builtin_bit_complement (0ULL) != ~0ULL
+      || __builtin_bit_complement (0xaaaaaaaa55555555ULL) != ~0xaaaaaaaa55555555ULL
+      || !expr_has_type (__builtin_bit_complement (0ULL), unsigned long long)
+      || __builtin_bit_complement ((signed char) 0) != (signed char) ~(signed char) 0
+      || __builtin_bit_complement ((signed char) 0x33) != (signed char) ~(signed char) 0x33
+      || !expr_has_type (__builtin_bit_complement ((signed char) 0), signed char)
+      || __builtin_bit_complement ((signed short) 0) != (signed short) ~(signed short) 0
+      || __builtin_bit_complement ((signed short) 0x5555) != (signed short) ~(signed short) 0x5555
+      || !expr_has_type (__builtin_bit_complement ((signed short) 0), signed short)
+      || __builtin_bit_complement (0) != ~0
+      || __builtin_bit_complement (0x5aaa) != ~0x5aaa
+      || !expr_has_type (__builtin_bit_complement (0), signed int)
+      || __builtin_bit_complement (0L) != ~0L
+      || __builtin_bit_complement (0x5aaaaaaaL) != ~0x5aaaaaaaL
+      || !expr_has_type (__builtin_bit_complement (0L), signed long)
+      || __builtin_bit_complement (0LL) != ~0LL
+      || __builtin_bit_complement (0x5aaaaaaa55555555LL) != ~0x5aaaaaaa55555555LL
+      || !expr_has_type (__builtin_bit_complement (0LL), signed long long)
+      || __builtin_bit_complement ((_Bool) 0) != (_Bool) 1
+      || __builtin_bit_complement ((_Bool) 1) != (_Bool) 0
+      || !expr_has_type (__builtin_bit_complement ((_Bool) 0), _Bool)
+      || __builtin_bit_complement ((enum E) E0) != (enum E) ~0
+      || __builtin_bit_complement ((enum E) E1) != (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) != ~(unsigned __int128) 0
+      || __builtin_bit_complement ((unsigned __int128) 0xaaaaaaaa55555555ULL) != ~(unsigned __int128) 0xaaaaaaaa55555555ULL
+      || !expr_has_type (__builtin_bit_complement ((unsigned __int128) 0), unsigned __int128)
+      || __builtin_bit_complement ((signed __int128) 0) != ~(signed __int128) 0
+      || __builtin_bit_complement ((signed __int128) 0x5aaaaaaa55555555LL) != ~(signed __int128) 0x5aaaaaaa55555555LL
+      || !expr_has_type (__builtin_bit_complement ((signed __int128) 0), signed __int128))
+    __builtin_abort ();
+#endif
+#if __has_builtin (__builtin_bit_complement) != 1
+#error __builtin_bit_complement not implemented
+#endif
+  unsigned char a = 0;
+  if (__builtin_bit_complement (a++) != (unsigned char) ~(unsigned char) 0
+      || a != 1)
+    __builtin_abort ();
+  if (!expr_has_type (__builtin_bit_complement (a++), unsigned char)
+      || a != 1)
+    __builtin_abort ();
+  unsigned short b = 0;
+  if (__builtin_bit_complement (b++) != (unsigned short) ~(unsigned short) 0
+      || b != 1)
+    __builtin_abort ();
+  if (!expr_has_type (__builtin_bit_complement (b++), unsigned short)
+      || b != 1)
+    __builtin_abort ();
+  int c = 0;
+  if (__builtin_bit_complement (c++) != ~0
+      || c != 1)
+    __builtin_abort ();
+  if (!expr_has_type (__builtin_bit_complement (c++), int)
+      || c != 1)
+    __builtin_abort ();
+#if __BITINT_MAXWIDTH__ >= 256
+  if (__builtin_bit_complement (0uwb) != ~0uwb
+      || !expr_has_type (__builtin_bit_complement (0uwb), unsigned _BitInt(1))
+      || __builtin_bit_complement ((signed _BitInt(256)) 0) != ~(signed _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_complement' operand not an integral type" } */
+  __builtin_bit_complement (0.0);	/* { dg-error "'__builtin_bit_complement' operand not an integral type" } */
+  __builtin_bit_complement (0.0L);	/* { dg-error "'__builtin_bit_complement' operand not an integral type" } */
+  __builtin_bit_complement ((V) {});	/* { dg-error "'__builtin_bit_complement' 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 arguments to '__builtin_bit_complement'" } */
+  __builtin_bit_complement (0, 0);	/* { dg-error "wrong number of arguments to '__builtin_bit_complement'" } */
+}

	Jakub


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] c: Add __builtin_bit_complement
  2023-11-18 19:37 [PATCH] c: Add __builtin_bit_complement Jakub Jelinek
@ 2023-11-20  7:43 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2023-11-20  7:43 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Joseph S. Myers, gcc-patches, Florian Weimer

On Sat, Nov 18, 2023 at 8:38 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> 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 = arg;
 (__typeof (tem))~tem;

then?

>
> 2023-11-18  Jakub Jelinek  <jakub@redhat.com>
>
> 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 argument
> +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<c_expr_t, va_gc> *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) != 1)
> +             {
> +               error_at (loc, "wrong number of arguments to "
> +                              "%<__builtin_bit_complement%>");
> +               expr.set_error ();
> +               break;
> +             }
> +
> +           arg_p = &(*cexpr_list)[0];
> +           *arg_p = 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
> +             = 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=c11" } */
> +
> +#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) != (unsigned char) ~(unsigned char) 0
> +      || __builtin_bit_complement ((unsigned char) 0x33) != (unsigned char) ~(unsigned char) 0x33
> +      || !expr_has_type (__builtin_bit_complement ((unsigned char) 0), unsigned char)
> +      || __builtin_bit_complement ((unsigned short) 0) != (unsigned short) ~(unsigned short) 0
> +      || __builtin_bit_complement ((unsigned short) 0x5555) != (unsigned short) ~(unsigned short) 0x5555
> +      || !expr_has_type (__builtin_bit_complement ((unsigned short) 0), unsigned short)
> +      || __builtin_bit_complement (0U) != ~0U
> +      || __builtin_bit_complement (0xaaaaU) != ~0xaaaaU
> +      || !expr_has_type (__builtin_bit_complement (0U), unsigned int)
> +      || __builtin_bit_complement (0UL) != ~0UL
> +      || __builtin_bit_complement (0xaaaaaaaaUL) != ~0xaaaaaaaaUL
> +      || !expr_has_type (__builtin_bit_complement (0UL), unsigned long)
> +      || __builtin_bit_complement (0ULL) != ~0ULL
> +      || __builtin_bit_complement (0xaaaaaaaa55555555ULL) != ~0xaaaaaaaa55555555ULL
> +      || !expr_has_type (__builtin_bit_complement (0ULL), unsigned long long)
> +      || __builtin_bit_complement ((signed char) 0) != (signed char) ~(signed char) 0
> +      || __builtin_bit_complement ((signed char) 0x33) != (signed char) ~(signed char) 0x33
> +      || !expr_has_type (__builtin_bit_complement ((signed char) 0), signed char)
> +      || __builtin_bit_complement ((signed short) 0) != (signed short) ~(signed short) 0
> +      || __builtin_bit_complement ((signed short) 0x5555) != (signed short) ~(signed short) 0x5555
> +      || !expr_has_type (__builtin_bit_complement ((signed short) 0), signed short)
> +      || __builtin_bit_complement (0) != ~0
> +      || __builtin_bit_complement (0x5aaa) != ~0x5aaa
> +      || !expr_has_type (__builtin_bit_complement (0), signed int)
> +      || __builtin_bit_complement (0L) != ~0L
> +      || __builtin_bit_complement (0x5aaaaaaaL) != ~0x5aaaaaaaL
> +      || !expr_has_type (__builtin_bit_complement (0L), signed long)
> +      || __builtin_bit_complement (0LL) != ~0LL
> +      || __builtin_bit_complement (0x5aaaaaaa55555555LL) != ~0x5aaaaaaa55555555LL
> +      || !expr_has_type (__builtin_bit_complement (0LL), signed long long)
> +      || __builtin_bit_complement ((_Bool) 0) != (_Bool) 1
> +      || __builtin_bit_complement ((_Bool) 1) != (_Bool) 0
> +      || !expr_has_type (__builtin_bit_complement ((_Bool) 0), _Bool)
> +      || __builtin_bit_complement ((enum E) E0) != (enum E) ~0
> +      || __builtin_bit_complement ((enum E) E1) != (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) != ~(unsigned __int128) 0
> +      || __builtin_bit_complement ((unsigned __int128) 0xaaaaaaaa55555555ULL) != ~(unsigned __int128) 0xaaaaaaaa55555555ULL
> +      || !expr_has_type (__builtin_bit_complement ((unsigned __int128) 0), unsigned __int128)
> +      || __builtin_bit_complement ((signed __int128) 0) != ~(signed __int128) 0
> +      || __builtin_bit_complement ((signed __int128) 0x5aaaaaaa55555555LL) != ~(signed __int128) 0x5aaaaaaa55555555LL
> +      || !expr_has_type (__builtin_bit_complement ((signed __int128) 0), signed __int128))
> +    __builtin_abort ();
> +#endif
> +#if __has_builtin (__builtin_bit_complement) != 1
> +#error __builtin_bit_complement not implemented
> +#endif
> +  unsigned char a = 0;
> +  if (__builtin_bit_complement (a++) != (unsigned char) ~(unsigned char) 0
> +      || a != 1)
> +    __builtin_abort ();
> +  if (!expr_has_type (__builtin_bit_complement (a++), unsigned char)
> +      || a != 1)
> +    __builtin_abort ();
> +  unsigned short b = 0;
> +  if (__builtin_bit_complement (b++) != (unsigned short) ~(unsigned short) 0
> +      || b != 1)
> +    __builtin_abort ();
> +  if (!expr_has_type (__builtin_bit_complement (b++), unsigned short)
> +      || b != 1)
> +    __builtin_abort ();
> +  int c = 0;
> +  if (__builtin_bit_complement (c++) != ~0
> +      || c != 1)
> +    __builtin_abort ();
> +  if (!expr_has_type (__builtin_bit_complement (c++), int)
> +      || c != 1)
> +    __builtin_abort ();
> +#if __BITINT_MAXWIDTH__ >= 256
> +  if (__builtin_bit_complement (0uwb) != ~0uwb
> +      || !expr_has_type (__builtin_bit_complement (0uwb), unsigned _BitInt(1))
> +      || __builtin_bit_complement ((signed _BitInt(256)) 0) != ~(signed _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_complement' operand not an integral type" } */
> +  __builtin_bit_complement (0.0);      /* { dg-error "'__builtin_bit_complement' operand not an integral type" } */
> +  __builtin_bit_complement (0.0L);     /* { dg-error "'__builtin_bit_complement' operand not an integral type" } */
> +  __builtin_bit_complement ((V) {});   /* { dg-error "'__builtin_bit_complement' 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 arguments to '__builtin_bit_complement'" } */
> +  __builtin_bit_complement (0, 0);     /* { dg-error "wrong number of arguments to '__builtin_bit_complement'" } */
> +}
>
>         Jakub
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-11-20  7:47 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-18 19:37 [PATCH] c: Add __builtin_bit_complement Jakub Jelinek
2023-11-20  7:43 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).