public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
@ 2023-11-18 19:42 Jakub Jelinek
  2023-11-20 14:55 ` Joseph Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2023-11-18 19:42 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches, Florian Weimer

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  <jakub@redhat.com>

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.cc	2023-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_COMPATIBLE_P, D_CONLY },
--- gcc/c/c-parser.cc.jj	2023-11-18 17:16:23.228591823 +0100
+++ gcc/c/c-parser.cc	2023-11-18 20:15:47.609493782 +0100
@@ -11744,14 +11744,18 @@ c_parser_postfix_expression (c_parser *p
 	  }
 	  break;
 	case RID_BUILTIN_BIT_COMPLEMENT:
+	case RID_BUILTIN_STDC_BIT_CEIL:
+	case RID_BUILTIN_STDC_BIT_FLOOR:
+	case RID_BUILTIN_STDC_BIT_WIDTH:
 	  {
 	    vec<c_expr_t, va_gc> *cexpr_list;
 	    c_expr_t *arg_p;
 	    location_t close_paren_loc;
+	    enum rid rid = c_parser_peek_token (parser)->keyword;
+	    const char *name = IDENTIFIER_POINTER (ridpointers[rid]);
 
 	    c_parser_consume_token (parser);
-	    if (!c_parser_get_builtin_args (parser,
-					    "__builtin_bit_complement",
+	    if (!c_parser_get_builtin_args (parser, name,
 					    &cexpr_list, false,
 					    &close_paren_loc))
 	      {
@@ -11761,8 +11765,7 @@ c_parser_postfix_expression (c_parser *p
 
 	    if (vec_safe_length (cexpr_list) != 1)
 	      {
-		error_at (loc, "wrong number of arguments to "
-			       "%<__builtin_bit_complement%>");
+		error_at (loc, "wrong number of arguments to %qs", name);
 		expr.set_error ();
 		break;
 	      }
@@ -11771,16 +11774,92 @@ c_parser_postfix_expression (c_parser *p
 	    *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");
+		error_at (loc, "%qs operand not an integral type", name);
 		expr.set_error ();
 		break;
 	      }
-	    expr.value
-	      = build1_loc (loc, BIT_NOT_EXPR,
-			    TYPE_MAIN_VARIANT (TREE_TYPE (arg_p->value)),
-			    arg_p->value);
+	    tree arg = arg_p->value;
+	    tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
+	    if (rid == RID_BUILTIN_BIT_COMPLEMENT)
+	      {
+		/* Expand __builtin_bit_complement (arg) as ~arg.  */
+		expr.value = build1_loc (loc, BIT_NOT_EXPR, type, arg);
+		set_c_expr_source_range (&expr, loc, close_paren_loc);
+		break;
+	      }
+	    /* Expand __builtin_stdc_bit_width (arg) as
+	       (unsigned int) (prec - __builtin_clzg (arg, prec)).
+	       Expand __builtin_stdc_bit_floor (arg) as
+	       arg == 0 ? (type) 0
+			: (type) 1 << (prec - 1 - __builtin_clzg (arg))
+	       without evaluating arg multiple times.
+	       Expand __builtin_stdc_bit_ceil (arg) as
+	       arg <= 1 ? (type) 1
+			: (type) 1 << (prec - __builtin_clzg (arg - 1))
+	       without evaluating arg multiple times.  */
+	    int prec = TYPE_PRECISION (type);
+	    if (rid != RID_BUILTIN_STDC_BIT_WIDTH)
+	      arg = save_expr (arg);
+	    /* Construct a call to __builtin_clzg.  */
+	    int nargs = rid == RID_BUILTIN_STDC_BIT_WIDTH ? 2 : 1;
+	    vec<tree, va_gc> *args;
+	    vec_alloc (args, nargs);
+	    vec<tree, va_gc> *origtypes;
+	    vec_alloc (origtypes, nargs);
+	    auto_vec<location_t> arg_loc (nargs);
+	    if (rid == RID_BUILTIN_STDC_BIT_CEIL)
+	      args->quick_push (build2_loc (loc, PLUS_EXPR, type,
+					    arg, build_int_cst (type, -1)));
+	    else
+	      args->quick_push (arg);
+	    arg_loc.quick_push (arg_p->get_location ());
+	    origtypes->quick_push (arg_p->original_type);
+	    if (nargs == 2)
+	      {
+		args->quick_push (build_int_cst (integer_type_node, prec));
+		arg_loc.quick_push (loc);
+		origtypes->quick_push (integer_type_node);
+	      }
+	    tree fndecl = builtin_decl_explicit (BUILT_IN_CLZG);
+	    expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
+						    args, origtypes);
 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
+	    if (expr.value == error_mark_node)
+	      break;
+	    if (rid == RID_BUILTIN_STDC_BIT_FLOOR)
+	      --prec;
+	    expr.value = build2_loc (loc, MINUS_EXPR, integer_type_node,
+				     build_int_cst (integer_type_node, prec),
+				     expr.value);
+	    if (rid == RID_BUILTIN_STDC_BIT_WIDTH)
+	      {
+		expr.value = fold_convert_loc (loc, unsigned_type_node,
+					       expr.value);
+		break;
+	      }
+	    /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
+	       or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
+	       warnings.  The LSHIFT_EXPR is in dead code in that case.  */
+	    if (integer_zerop (arg)
+		|| (rid == RID_BUILTIN_STDC_BIT_CEIL && integer_onep (arg)))
+	      expr.value = build_int_cst (type, 1);
+	    else
+	      expr.value = build2_loc (loc, LSHIFT_EXPR, type,
+				       build_int_cst (type, 1), expr.value);
+	    if (rid == RID_BUILTIN_STDC_BIT_CEIL)
+	      expr.value = build3_loc (loc, COND_EXPR, type,
+				       build2_loc (loc, LE_EXPR,
+						   boolean_type_node, arg,
+						   build_int_cst (type, 1)),
+				       build_int_cst (type, 1),
+				       expr.value);
+	    else
+	      expr.value = build3_loc (loc, COND_EXPR, type,
+				       build2_loc (loc, EQ_EXPR,
+						   boolean_type_node, arg,
+						   build_int_cst (type, 0)),
+				       build_int_cst (type, 0),
+				       expr.value);
 	    break;
 	  }
 	case RID_AT_SELECTOR:
--- gcc/c/c-decl.cc.jj	2023-11-18 17:31:39.298880201 +0100
+++ gcc/c/c-decl.cc	2023-11-18 18:48:26.796048523 +0100
@@ -11376,6 +11376,9 @@ names_builtin_p (const char *name)
     case RID_BUILTIN_HAS_ATTRIBUTE:
     case RID_BUILTIN_SHUFFLE:
     case RID_BUILTIN_SHUFFLEVECTOR:
+    case RID_BUILTIN_STDC_BIT_CEIL:
+    case RID_BUILTIN_STDC_BIT_FLOOR:
+    case RID_BUILTIN_STDC_BIT_WIDTH:
     case RID_CHOOSE_EXPR:
     case RID_OFFSETOF:
     case RID_TYPES_COMPATIBLE_P:
--- gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c.jj	2023-11-18 19:36:34.422984124 +0100
+++ gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c	2023-11-18 20:05:32.678976258 +0100
@@ -0,0 +1,185 @@
+/* { dg-do run } */
+/* { dg-options "-std=c11" } */
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+
+int
+main ()
+{
+  if (__builtin_stdc_bit_width ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_bit_width ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_bit_width (0U) != 0
+      || !expr_has_type (__builtin_stdc_bit_width (0U), unsigned int)
+      || __builtin_stdc_bit_width (0UL) != 0
+      || !expr_has_type (__builtin_stdc_bit_width (0UL), unsigned int)
+      || __builtin_stdc_bit_width (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_bit_width (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned char) ~0U) != __CHAR_BIT__
+      || __builtin_stdc_bit_width ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || __builtin_stdc_bit_width (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || __builtin_stdc_bit_width (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || __builtin_stdc_bit_width (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned char) ((unsigned char) ~0U >> 1)) != __CHAR_BIT__ - 1
+      || __builtin_stdc_bit_width ((unsigned char) 6) != 3
+      || __builtin_stdc_bit_width ((unsigned short) 12U) != 4
+      || __builtin_stdc_bit_width ((unsigned short) ((unsigned short) ~0U >> 5)) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 5
+      || __builtin_stdc_bit_width (137U) != 8
+      || __builtin_stdc_bit_width (269U) != 9
+      || __builtin_stdc_bit_width (39UL) != 6
+      || __builtin_stdc_bit_width (~0UL >> 2) != __SIZEOF_LONG__ * __CHAR_BIT__ - 2
+      || __builtin_stdc_bit_width (1023ULL) != 10
+      || __builtin_stdc_bit_width (1024ULL) != 11)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned char) 0), unsigned char)
+      || __builtin_stdc_bit_floor ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned short) 0), unsigned short)
+      || __builtin_stdc_bit_floor (0U) != 0U
+      || !expr_has_type (__builtin_stdc_bit_floor (0U), unsigned int)
+      || __builtin_stdc_bit_floor (0UL) != 0UL
+      || !expr_has_type (__builtin_stdc_bit_floor (0UL), unsigned long)
+      || __builtin_stdc_bit_floor (0ULL) != 0ULL
+      || !expr_has_type (__builtin_stdc_bit_floor (0ULL), unsigned long long))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned char) ~0U) != (1U << (__CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor ((unsigned short) ~0U) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor (~0U) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor (~0UL) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor (~0ULL) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned char) 4) != 4
+      || __builtin_stdc_bit_floor ((unsigned char) 7) != 4
+      || __builtin_stdc_bit_floor ((unsigned short) 8U) != 8
+      || __builtin_stdc_bit_floor ((unsigned short) 31U) != 16
+      || __builtin_stdc_bit_floor (137U) != 128U
+      || __builtin_stdc_bit_floor (269U) != 256U
+      || __builtin_stdc_bit_floor (511UL) != 256UL
+      || __builtin_stdc_bit_floor (512UL) != 512UL
+      || __builtin_stdc_bit_floor (513UL) != 512ULL
+      || __builtin_stdc_bit_floor (1024ULL) != 1024ULL)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned char) 0), unsigned char)
+      || __builtin_stdc_bit_ceil ((unsigned short) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned short) 0), unsigned short)
+      || __builtin_stdc_bit_ceil (0U) != 1U
+      || !expr_has_type (__builtin_stdc_bit_ceil (0U), unsigned int)
+      || __builtin_stdc_bit_ceil (0UL) != 1UL
+      || !expr_has_type (__builtin_stdc_bit_ceil (0UL), unsigned long)
+      || __builtin_stdc_bit_ceil (0ULL) != 1ULL
+      || !expr_has_type (__builtin_stdc_bit_ceil (0ULL), unsigned long long))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) ((unsigned char) ~0U >> 1)) != (1U << (__CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil ((unsigned char) ((unsigned char) ~0U >> 1)) != (1U << (__CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil ((unsigned short) ((unsigned short) ~0U >> 1)) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil ((unsigned short) ((unsigned short) ~0U >> 1)) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0U >> 1) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1)) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0UL >> 1) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0UL >> 1) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0ULL >> 1) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) 1) != 1
+      || __builtin_stdc_bit_ceil ((unsigned char) 2) != 2
+      || __builtin_stdc_bit_ceil ((unsigned short) 3U) != 4
+      || __builtin_stdc_bit_ceil ((unsigned short) 4U) != 4
+      || __builtin_stdc_bit_ceil (5U) != 8U
+      || __builtin_stdc_bit_ceil (269U) != 512U
+      || __builtin_stdc_bit_ceil (511UL) != 512UL
+      || __builtin_stdc_bit_ceil (512UL) != 512UL
+      || __builtin_stdc_bit_ceil (513ULL) != 1024ULL
+      || __builtin_stdc_bit_ceil (1025ULL) != 2048ULL)
+    __builtin_abort ();
+#ifdef __SIZEOF_INT128__
+  if (__builtin_stdc_bit_width ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_bit_width (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned __int128) 0), unsigned __int128)
+      || __builtin_stdc_bit_floor (~(unsigned __int128) 0) != ((unsigned __int128) 1) << (__SIZEOF_INT128__ * __CHAR_BIT__ - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned __int128) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned __int128) 0), unsigned __int128)
+      || __builtin_stdc_bit_ceil ((unsigned __int128) 1) != 1
+      || __builtin_stdc_bit_ceil ((~(unsigned __int128) 0) >> 1) != ((unsigned __int128) 1) << (__SIZEOF_INT128__ * __CHAR_BIT__ - 1))
+    __builtin_abort ();
+#endif
+#if __has_builtin (__builtin_stdc_bit_width) != 1
+#error __builtin_stdc_bit_width not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_floor) != 1
+#error __builtin_stdc_bit_floor not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_ceil) != 1
+#error __builtin_stdc_bit_ceil not implemented
+#endif
+  unsigned char a = 0;
+  if (__builtin_stdc_bit_width (a++) != 0 || a != 1)
+    __builtin_abort ();
+  unsigned long long b = 0;
+  if (__builtin_stdc_bit_width (b++) != 0 || b != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (a++) != 1 || a != 2)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (b++) != 1 || b != 2)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (a++) != 2 || a != 3)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (b++) != 2 || b != 3)
+    __builtin_abort ();
+#if BITINT_MAXWIDTH >= 512
+  if (__builtin_stdc_bit_width ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_bit_width ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width (~(unsigned _BitInt(512)) 0) != 512
+      || __builtin_stdc_bit_width (~(unsigned _BitInt(373)) 0) != 373)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width (((unsigned _BitInt(512)) 1023) << 405) != 405 + 10
+      || __builtin_stdc_bit_width (((unsigned _BitInt(373)) 1024) << 242) != 242 + 11)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned _BitInt(512)) 0), unsigned _BitInt(512))
+      || __builtin_stdc_bit_floor ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned _BitInt(373)) 0), unsigned _BitInt(373)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (~(unsigned _BitInt(512)) 0) != ((unsigned _BitInt(512)) 1) << (512 - 1)
+      || __builtin_stdc_bit_floor (~(unsigned _BitInt(373)) 0) != ((unsigned _BitInt(373)) 1) << (373 - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (((unsigned _BitInt(512)) 511) << 405) != (((unsigned _BitInt(512)) 256) << 405)
+      || __builtin_stdc_bit_floor (((unsigned _BitInt(373)) 512) << 242) != (((unsigned _BitInt(512)) 512) << 242))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned _BitInt(512)) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned _BitInt(512)) 0), unsigned _BitInt(512))
+      || __builtin_stdc_bit_ceil ((unsigned _BitInt(373)) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned _BitInt(373)) 0), unsigned _BitInt(373)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(512)) 1) << (512 - 1)) != ((unsigned _BitInt(512)) 1) << (512 - 1)
+      || __builtin_stdc_bit_ceil ((~(unsigned _BitInt(373)) 0) >> 1) != ((unsigned _BitInt(373)) 1) << (373 - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(512)) 512) << 405) != (((unsigned _BitInt(512)) 512) << 405)
+      || __builtin_stdc_bit_ceil (((unsigned _BitInt(373)) 513) << 242) != (((unsigned _BitInt(512)) 1024) << 242))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned _BitInt(BITINT_MAXWIDTH)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (~(unsigned _BitInt(BITINT_MAXWIDTH)) 0) != ((unsigned _BitInt(BITINT_MAXWIDTH)) 1) << (BITINT_MAXWIDTH - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (((unsigned _BitInt(BITINT_MAXWIDTH)) 511) << 405) != (((unsigned _BitInt(BITINT_MAXWIDTH)) 256) << 405)
+      || __builtin_stdc_bit_floor (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) << 405) != (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) << 405))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned _BitInt(BITINT_MAXWIDTH)) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(BITINT_MAXWIDTH)) 1) << (BITINT_MAXWIDTH - 1)) != ((unsigned _BitInt(BITINT_MAXWIDTH)) 1) << (BITINT_MAXWIDTH - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) << 405) != (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) << 405)
+      || __builtin_stdc_bit_ceil (((unsigned _BitInt(BITINT_MAXWIDTH)) 513) << 405) != (((unsigned _BitInt(BITINT_MAXWIDTH)) 1024) << 405))
+    __builtin_abort ();
+#endif
+}
--- gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c.jj	2023-11-18 19:55:50.956983185 +0100
+++ gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c	2023-11-18 20:18:06.339579450 +0100
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+  typedef int V __attribute__ ((vector_size (4 * sizeof (int))));
+  struct S { int s; };
+  enum E { E0, E1 };
+  __builtin_stdc_bit_width (0.0f);	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width (0.0);	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width (0.0L);	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width ((V) {});	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_width'" } */
+  __builtin_stdc_bit_width (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_width'" } */
+  __builtin_stdc_bit_width ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_bit_width ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_bit_width (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_bit_floor (0.0f);	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor (0.0);	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor (0.0L);	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor ((V) {});	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_floor'" } */
+  __builtin_stdc_bit_floor (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_floor'" } */
+  __builtin_stdc_bit_floor ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_bit_floor ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_bit_floor (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_bit_ceil (0.0f);	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil (0.0);	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil (0.0L);	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil ((V) {});	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_ceil'" } */
+  __builtin_stdc_bit_ceil (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_ceil'" } */
+  __builtin_stdc_bit_ceil ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_bit_ceil ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_bit_ceil (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+}

	Jakub


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

* Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
  2023-11-18 19:42 [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins Jakub Jelinek
@ 2023-11-20 14:55 ` Joseph Myers
  2023-11-20 15:03   ` Jakub Jelinek
  2023-11-20 15:12   ` Jakub Jelinek
  0 siblings, 2 replies; 9+ messages in thread
From: Joseph Myers @ 2023-11-20 14:55 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, Florian Weimer

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
joseph@codesourcery.com

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

* Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
  2023-11-20 14:55 ` Joseph Myers
@ 2023-11-20 15:03   ` Jakub Jelinek
  2023-11-20 15:29     ` Jakub Jelinek
  2023-11-20 15:12   ` Jakub Jelinek
  1 sibling, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2023-11-20 15:03 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc-patches, Florian Weimer

On Mon, Nov 20, 2023 at 02:55:33PM +0000, 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  <jakub@redhat.com>

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.cc	2023-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_stdc_first_trailing_one", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_first_trailing_zero", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_has_single_bit", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_leading_ones", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_leading_zeros", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_trailing_ones", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_trailing_zeros", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_tgmath", RID_BUILTIN_TGMATH, D_CONLY },
   { "__builtin_offsetof", RID_OFFSETOF, 0 },
   { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
--- gcc/doc/extend.texi.jj	2023-11-20 10:37:47.181394361 +0100
+++ gcc/doc/extend.texi	2023-11-20 12:23:04.218820519 +0100
@@ -15075,6 +15075,125 @@ unsigned integer (standard, extended or
 promotions are performed on the argument.
 @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{@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{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{unsigned int __builtin_stdc_count_ones (@var{type} @var{arg})}
+The @code{__builtin_stdc_count_ones} 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) __builtin_popcountg (@var{arg})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_count_zeros (@var{type} @var{arg})}
+The @code{__builtin_stdc_count_zeros} 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) __builtin_popcountg ((@var{type}) ~@var{arg})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_leading_one (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_leading_one} 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{__builtin_clzg (@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_leading_zero (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_leading_zero} 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{__builtin_clzg ((@var{type}) ~@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_trailing_one (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_trailing_one} 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{__builtin_ctzg (@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_trailing_zero (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_trailing_zero} 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{__builtin_ctzg ((@var{type}) ~@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_has_single_bit (@var{type} @var{arg})}
+The @code{__builtin_stdc_has_single_bit} 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{(_Bool) (__builtin_popcountg (@var{arg}) == 1)}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_leading_ones (@var{type} @var{arg})}
+The @code{__builtin_stdc_leading_ones} 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) __builtin_clzg ((@var{type}) ~@var{arg}, @var{prec})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_leading_zeros (@var{type} @var{arg})}
+The @code{__builtin_stdc_leading_zeros} 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) __builtin_clzg (@var{arg}, @var{prec})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_trailing_ones (@var{type} @var{arg})}
+The @code{__builtin_stdc_trailing_ones} 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) __builtin_ctzg ((@var{type}) ~@var{arg}, @var{prec})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_trailing_zeros (@var{type} @var{arg})}
+The @code{__builtin_stdc_trailing_zeros} 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) __builtin_ctzg (@var{arg}, @var{prec})}
+@enddefbuiltin
+
 @defbuiltin{double __builtin_powi (double, int)}
 @defbuiltinx{float __builtin_powif (float, int)}
 @defbuiltinx{{long double} __builtin_powil (long double, int)}
--- gcc/c/c-parser.cc.jj	2023-11-20 09:49:34.778674562 +0100
+++ gcc/c/c-parser.cc	2023-11-20 14:39:36.457423933 +0100
@@ -11743,6 +11743,292 @@ c_parser_postfix_expression (c_parser *p
 	    set_c_expr_source_range (&expr, start_loc, end_loc);
 	  }
 	  break;
+	case RID_BUILTIN_STDC:
+	  {
+	    vec<c_expr_t, va_gc> *cexpr_list;
+	    c_expr_t *arg_p;
+	    location_t close_paren_loc;
+	    enum c_builtin_stdc {
+	      C_BUILTIN_STDC_BIT_CEIL,
+	      C_BUILTIN_STDC_BIT_FLOOR,
+	      C_BUILTIN_STDC_BIT_WIDTH,
+	      C_BUILTIN_STDC_COUNT_ONES,
+	      C_BUILTIN_STDC_COUNT_ZEROS,
+	      C_BUILTIN_STDC_FIRST_LEADING_ONE,
+	      C_BUILTIN_STDC_FIRST_LEADING_ZERO,
+	      C_BUILTIN_STDC_FIRST_TRAILING_ONE,
+	      C_BUILTIN_STDC_FIRST_TRAILING_ZERO,
+	      C_BUILTIN_STDC_HAS_SINGLE_BIT,
+	      C_BUILTIN_STDC_LEADING_ONES,
+	      C_BUILTIN_STDC_LEADING_ZEROS,
+	      C_BUILTIN_STDC_TRAILING_ONES,
+	      C_BUILTIN_STDC_TRAILING_ZEROS,
+	      C_BUILTIN_STDC_MAX
+	    } stdc_rid = C_BUILTIN_STDC_MAX;
+	    const char *name
+	      = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+	    switch (name[sizeof ("__builtin_stdc_") - 1])
+	      {
+	      case 'b':
+		switch (name[sizeof ("__builtin_stdc_bit_") - 1])
+		  {
+		  case 'c':
+		    stdc_rid = C_BUILTIN_STDC_BIT_CEIL;
+		    break;
+		  case 'f':
+		    stdc_rid = C_BUILTIN_STDC_BIT_FLOOR;
+		    break;
+		  default:
+		    stdc_rid = C_BUILTIN_STDC_BIT_WIDTH;
+		    break;
+		  }
+		break;
+	      case 'c':
+		if (name[sizeof ("__builtin_stdc_count_") - 1] == 'o')
+		  stdc_rid = C_BUILTIN_STDC_COUNT_ONES;
+		else
+		  stdc_rid = C_BUILTIN_STDC_COUNT_ZEROS;
+		break;
+	      case 'f':
+		switch (name[sizeof ("__builtin_stdc_first_trailing_") - 1])
+		  {
+		  case 'n':
+		    stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ONE;
+		    break;
+		  case 'e':
+		    stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ZERO;
+		    break;
+		  case 'o':
+		    stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ONE;
+		    break;
+		  default:
+		    stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ZERO;
+		    break;
+		  }
+		break;
+	      case 'h':
+		stdc_rid = C_BUILTIN_STDC_HAS_SINGLE_BIT;
+		break;
+	      case 'l':
+		if (name[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
+		  stdc_rid = C_BUILTIN_STDC_LEADING_ONES;
+		else
+		  stdc_rid = C_BUILTIN_STDC_LEADING_ZEROS;
+		break;
+	      case 't':
+		if (name[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
+		  stdc_rid = C_BUILTIN_STDC_TRAILING_ONES;
+		else
+		  stdc_rid = C_BUILTIN_STDC_TRAILING_ZEROS;
+		break;
+	      }
+	    gcc_checking_assert (stdc_rid != C_BUILTIN_STDC_MAX);
+
+	    c_parser_consume_token (parser);
+	    if (!c_parser_get_builtin_args (parser, name,
+					    &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 %qs", name);
+		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, "%qs operand not an integral type", name);
+		expr.set_error ();
+		break;
+	      }
+	    tree arg = arg_p->value;
+	    tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
+	    /* Expand (without evaluating arg multiple times, type
+	       being __typeof (arg) and prec __builtin_popcountg ((type) ~0)):
+	       __builtin_stdc_leading_zeros (arg) as
+		 (unsigned int) __builtin_clzg (arg, prec)
+	       __builtin_stdc_leading_ones (arg) as
+		 (unsigned int) __builtin_clzg ((type) ~arg, prec)
+	       __builtin_stdc_trailing_zeros (arg) as
+		 (unsigned int) __builtin_ctzg (arg, prec)
+	       __builtin_stdc_trailing_ones (arg) as
+		 (unsigned int) __builtin_ctzg ((type) ~arg, prec)
+	       __builtin_stdc_first_leading_zero (arg) as
+		 __builtin_clzg ((type) ~arg, -1) + 1U
+	       __builtin_stdc_first_leading_one (arg) as
+		 __builtin_clzg (arg, -1) + 1U
+	       __builtin_stdc_first_trailing_zero (arg) as
+		 __builtin_ctzg ((type) ~arg, -1) + 1U
+	       __builtin_stdc_first_trailing_one (arg) as
+		 __builtin_ctzg (arg, -1) + 1U
+	       __builtin_stdc_count_zeros (arg) as
+		 (unsigned int) __builtin_popcountg ((type) ~arg)
+	       __builtin_stdc_count_ones (arg) as
+		 (unsigned int) __builtin_popcountg (arg)
+	       __builtin_stdc_has_single_bit (arg) as
+		 (_Bool) (__builtin_popcountg (arg) == 1)
+	       __builtin_stdc_bit_width (arg) as
+		 (unsigned int) (prec - __builtin_clzg (arg, prec))
+	       __builtin_stdc_bit_floor (arg) as
+		 arg == 0 ? (type) 0
+			  : (type) 1 << (prec - 1 - __builtin_clzg (arg))
+	       __builtin_stdc_bit_ceil (arg) as
+		 arg <= 1 ? (type) 1
+			  : (type) 1 << (prec - __builtin_clzg (arg - 1))  */
+	    int prec = TYPE_PRECISION (type);
+	    tree barg1 = arg;
+	    switch (stdc_rid)
+	      {
+	      case C_BUILTIN_STDC_BIT_CEIL:
+		arg = save_expr (arg);
+		barg1 = build2_loc (loc, PLUS_EXPR, type, arg,
+				    build_int_cst (type, -1));
+		break;
+	      case C_BUILTIN_STDC_BIT_FLOOR:
+		barg1 = arg = save_expr (arg);
+		break;
+	      case C_BUILTIN_STDC_COUNT_ZEROS:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+	      case C_BUILTIN_STDC_LEADING_ONES:
+	      case C_BUILTIN_STDC_TRAILING_ONES:
+		barg1 = build1_loc (loc, BIT_NOT_EXPR, type, arg);
+		break;
+	      default:
+		break;
+	      }
+	    tree barg2 = NULL_TREE;
+	    switch (stdc_rid)
+	      {
+	      case C_BUILTIN_STDC_BIT_WIDTH:
+	      case C_BUILTIN_STDC_LEADING_ONES:
+	      case C_BUILTIN_STDC_LEADING_ZEROS:
+	      case C_BUILTIN_STDC_TRAILING_ONES:
+	      case C_BUILTIN_STDC_TRAILING_ZEROS:
+		barg2 = build_int_cst (integer_type_node, prec);
+		break;
+	      case C_BUILTIN_STDC_FIRST_LEADING_ONE:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+		barg2 = integer_minus_one_node;
+		break;
+	      default:
+		break;
+	      }
+	    tree fndecl = NULL_TREE;
+	    switch (stdc_rid)
+	      {
+	      case C_BUILTIN_STDC_BIT_CEIL:
+	      case C_BUILTIN_STDC_BIT_FLOOR:
+	      case C_BUILTIN_STDC_BIT_WIDTH:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ONE:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+	      case C_BUILTIN_STDC_LEADING_ONES:
+	      case C_BUILTIN_STDC_LEADING_ZEROS:
+		fndecl = builtin_decl_explicit (BUILT_IN_CLZG);
+		break;
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+	      case C_BUILTIN_STDC_TRAILING_ONES:
+	      case C_BUILTIN_STDC_TRAILING_ZEROS:
+		fndecl = builtin_decl_explicit (BUILT_IN_CTZG);
+		break;
+	      case C_BUILTIN_STDC_COUNT_ONES:
+	      case C_BUILTIN_STDC_COUNT_ZEROS:
+	      case C_BUILTIN_STDC_HAS_SINGLE_BIT:
+		fndecl = builtin_decl_explicit (BUILT_IN_POPCOUNTG);
+		break;
+	      default:
+		gcc_unreachable ();
+	      }
+	    /* Construct a call to __builtin_{clz,ctz,popcount}g.  */
+	    int nargs = barg2 != NULL_TREE ? 2 : 1;
+	    vec<tree, va_gc> *args;
+	    vec_alloc (args, nargs);
+	    vec<tree, va_gc> *origtypes;
+	    vec_alloc (origtypes, nargs);
+	    auto_vec<location_t> arg_loc (nargs);
+	    args->quick_push (barg1);
+	    arg_loc.quick_push (arg_p->get_location ());
+	    origtypes->quick_push (arg_p->original_type);
+	    if (nargs == 2)
+	      {
+		args->quick_push (barg2);
+		arg_loc.quick_push (loc);
+		origtypes->quick_push (integer_type_node);
+	      }
+	    expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
+						    args, origtypes);
+	    set_c_expr_source_range (&expr, loc, close_paren_loc);
+	    if (expr.value == error_mark_node)
+	      break;
+	    switch (stdc_rid)
+	      {
+	      case C_BUILTIN_STDC_BIT_FLOOR:
+		--prec;
+		/* FALLTHRU */
+	      case C_BUILTIN_STDC_BIT_CEIL:
+	      case C_BUILTIN_STDC_BIT_WIDTH:
+		expr.value = build2_loc (loc, MINUS_EXPR, integer_type_node,
+					 build_int_cst (integer_type_node,
+							prec), expr.value);
+		break;
+	      case C_BUILTIN_STDC_FIRST_LEADING_ONE:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+		expr.value = build2_loc (loc, PLUS_EXPR, integer_type_node,
+					 expr.value, integer_one_node);
+		break;
+	      case C_BUILTIN_STDC_HAS_SINGLE_BIT:
+		expr.value = build2_loc (loc, EQ_EXPR, boolean_type_node,
+					 expr.value, integer_one_node);
+		break;
+	      default:
+		break;
+	      }
+
+	    if (stdc_rid != C_BUILTIN_STDC_BIT_CEIL
+		&& stdc_rid != C_BUILTIN_STDC_BIT_FLOOR)
+	      {
+		if (stdc_rid != C_BUILTIN_STDC_HAS_SINGLE_BIT)
+		  expr.value = fold_convert_loc (loc, unsigned_type_node,
+						 expr.value);
+		break;
+	      }
+	    /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
+	       or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
+	       warnings.  The LSHIFT_EXPR is in dead code in that case.  */
+	    if (integer_zerop (arg)
+		|| (stdc_rid == C_BUILTIN_STDC_BIT_CEIL && integer_onep (arg)))
+	      expr.value = build_int_cst (type, 1);
+	    else
+	      expr.value = build2_loc (loc, LSHIFT_EXPR, type,
+				       build_int_cst (type, 1), expr.value);
+	    if (stdc_rid == C_BUILTIN_STDC_BIT_CEIL)
+	      expr.value = build3_loc (loc, COND_EXPR, type,
+				       build2_loc (loc, LE_EXPR,
+						   boolean_type_node, arg,
+						   build_int_cst (type, 1)),
+				       build_int_cst (type, 1),
+				       expr.value);
+	    else
+	      expr.value = build3_loc (loc, COND_EXPR, type,
+				       build2_loc (loc, EQ_EXPR,
+						   boolean_type_node, arg,
+						   build_int_cst (type, 0)),
+				       build_int_cst (type, 0),
+				       expr.value);
+	    break;
+	  }
 	case RID_AT_SELECTOR:
 	  {
 	    gcc_assert (c_dialect_objc ());
--- gcc/c/c-decl.cc.jj	2023-11-20 09:49:34.767674716 +0100
+++ gcc/c/c-decl.cc	2023-11-20 14:21:23.460450475 +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_CONVERTVECTOR:
     case RID_BUILTIN_HAS_ATTRIBUTE:
     case RID_BUILTIN_SHUFFLE:
     case RID_BUILTIN_SHUFFLEVECTOR:
-    case RID_BUILTIN_ASSOC_BARRIER:
+    case RID_BUILTIN_STDC:
     case RID_CHOOSE_EXPR:
     case RID_OFFSETOF:
     case RID_TYPES_COMPATIBLE_P:
--- gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c.jj	2023-11-20 11:18:55.757125910 +0100
+++ gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c	2023-11-20 15:47:31.135895834 +0100
@@ -0,0 +1,834 @@
+/* { dg-do run } */
+/* { dg-options "-std=c11" } */
+
+unsigned int
+leading_zeros (unsigned char a, unsigned short b, unsigned int c,
+	       unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_leading_zeros (a)
+	  + __builtin_stdc_leading_zeros (b)
+	  + __builtin_stdc_leading_zeros (c)
+	  + __builtin_stdc_leading_zeros (d)
+	  + __builtin_stdc_leading_zeros (e));
+}
+
+unsigned int
+leading_ones (unsigned char a, unsigned short b, unsigned int c,
+	      unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_leading_ones (a)
+	  + __builtin_stdc_leading_ones (b)
+	  + __builtin_stdc_leading_ones (c)
+	  + __builtin_stdc_leading_ones (d)
+	  + __builtin_stdc_leading_ones (e));
+}
+
+unsigned int
+trailing_zeros (unsigned char a, unsigned short b, unsigned int c,
+		unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_trailing_zeros (a)
+	  + __builtin_stdc_trailing_zeros (b)
+	  + __builtin_stdc_trailing_zeros (c)
+	  + __builtin_stdc_trailing_zeros (d)
+	  + __builtin_stdc_trailing_zeros (e));
+}
+
+unsigned int
+trailing_ones (unsigned char a, unsigned short b, unsigned int c,
+	       unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_trailing_ones (a)
+	  + __builtin_stdc_trailing_ones (b)
+	  + __builtin_stdc_trailing_ones (c)
+	  + __builtin_stdc_trailing_ones (d)
+	  + __builtin_stdc_trailing_ones (e));
+}
+
+unsigned int
+first_leading_zero (unsigned char a, unsigned short b, unsigned int c,
+		    unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_first_leading_zero (a)
+	  + __builtin_stdc_first_leading_zero (b)
+	  + __builtin_stdc_first_leading_zero (c)
+	  + __builtin_stdc_first_leading_zero (d)
+	  + __builtin_stdc_first_leading_zero (e));
+}
+
+unsigned int
+first_leading_one (unsigned char a, unsigned short b, unsigned int c,
+		   unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_first_leading_one (a)
+	  + __builtin_stdc_first_leading_one (b)
+	  + __builtin_stdc_first_leading_one (c)
+	  + __builtin_stdc_first_leading_one (d)
+	  + __builtin_stdc_first_leading_one (e));
+}
+
+unsigned int
+first_trailing_zero (unsigned char a, unsigned short b, unsigned int c,
+		     unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_first_trailing_zero (a)
+	  + __builtin_stdc_first_trailing_zero (b)
+	  + __builtin_stdc_first_trailing_zero (c)
+	  + __builtin_stdc_first_trailing_zero (d)
+	  + __builtin_stdc_first_trailing_zero (e));
+}
+
+unsigned int
+first_trailing_one (unsigned char a, unsigned short b, unsigned int c,
+		    unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_first_trailing_one (a)
+	  + __builtin_stdc_first_trailing_one (b)
+	  + __builtin_stdc_first_trailing_one (c)
+	  + __builtin_stdc_first_trailing_one (d)
+	  + __builtin_stdc_first_trailing_one (e));
+}
+
+unsigned int
+count_zeros (unsigned char a, unsigned short b, unsigned int c,
+	     unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_count_zeros (a)
+	  + __builtin_stdc_count_zeros (b)
+	  + __builtin_stdc_count_zeros (c)
+	  + __builtin_stdc_count_zeros (d)
+	  + __builtin_stdc_count_zeros (e));
+}
+
+unsigned int
+count_ones (unsigned char a, unsigned short b, unsigned int c,
+	    unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_count_ones (a)
+	  + __builtin_stdc_count_ones (b)
+	  + __builtin_stdc_count_ones (c)
+	  + __builtin_stdc_count_ones (d)
+	  + __builtin_stdc_count_ones (e));
+}
+
+unsigned int
+has_single_bit (unsigned char a, unsigned short b, unsigned int c,
+		unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_has_single_bit (a)
+	  || __builtin_stdc_has_single_bit (b)
+	  || __builtin_stdc_has_single_bit (c)
+	  || __builtin_stdc_has_single_bit (d)
+	  || __builtin_stdc_has_single_bit (e));
+}
+
+unsigned int
+bit_width (unsigned char a, unsigned short b, unsigned int c,
+	   unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_bit_width (a)
+	  + __builtin_stdc_bit_width (b)
+	  + __builtin_stdc_bit_width (c)
+	  + __builtin_stdc_bit_width (d)
+	  + __builtin_stdc_bit_width (e));
+}
+
+unsigned long long
+bit_floor (unsigned char a, unsigned short b, unsigned int c,
+	   unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_bit_floor (a)
+	  + __builtin_stdc_bit_floor (b)
+	  + __builtin_stdc_bit_floor (c)
+	  + __builtin_stdc_bit_floor (d)
+	  + __builtin_stdc_bit_floor (e));
+}
+
+unsigned long long
+bit_ceil (unsigned char a, unsigned short b, unsigned int c,
+	  unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_bit_ceil (a)
+	  + __builtin_stdc_bit_ceil (b)
+	  + __builtin_stdc_bit_ceil (c)
+	  + __builtin_stdc_bit_ceil (d)
+	  + __builtin_stdc_bit_ceil (e));
+}
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+
+int
+main ()
+{
+  if (__builtin_stdc_leading_zeros ((unsigned char) 0) != __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_leading_zeros ((unsigned short) 0) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_leading_zeros (0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros (0U), unsigned int)
+      || __builtin_stdc_leading_zeros (0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros (0UL), unsigned int)
+      || __builtin_stdc_leading_zeros (0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros ((unsigned char) ~0U) != 0
+      || __builtin_stdc_leading_zeros ((unsigned short) ~0U) != 0
+      || __builtin_stdc_leading_zeros (~0U) != 0
+      || __builtin_stdc_leading_zeros (~0UL) != 0
+      || __builtin_stdc_leading_zeros (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros ((unsigned char) 3) != __CHAR_BIT__ - 2
+      || __builtin_stdc_leading_zeros ((unsigned short) 9) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 4
+      || __builtin_stdc_leading_zeros (34U) != __SIZEOF_INT__ * __CHAR_BIT__ - 6
+      || __builtin_stdc_leading_zeros (130UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 8
+      || __builtin_stdc_leading_zeros (512ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 10)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_leading_ones ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_leading_ones (0U) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones (0U), unsigned int)
+      || __builtin_stdc_leading_ones (0UL) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones (0UL), unsigned int)
+      || __builtin_stdc_leading_ones (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned char) ~0U) != __CHAR_BIT__
+      || __builtin_stdc_leading_ones ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || __builtin_stdc_leading_ones (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || __builtin_stdc_leading_ones (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || __builtin_stdc_leading_ones (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned char) ~3) != __CHAR_BIT__ - 2
+      || __builtin_stdc_leading_ones ((unsigned short) ~9) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 4
+      || __builtin_stdc_leading_ones (~34U) != __SIZEOF_INT__ * __CHAR_BIT__ - 6
+      || __builtin_stdc_leading_ones (~130UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 8
+      || __builtin_stdc_leading_ones (~512ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 10)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned char) 0) != __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_trailing_zeros ((unsigned short) 0) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_trailing_zeros (0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros (0U), unsigned int)
+      || __builtin_stdc_trailing_zeros (0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros (0UL), unsigned int)
+      || __builtin_stdc_trailing_zeros (0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned char) ~0U) != 0
+      || __builtin_stdc_trailing_zeros ((unsigned short) ~0U) != 0
+      || __builtin_stdc_trailing_zeros (~0U) != 0
+      || __builtin_stdc_trailing_zeros (~0UL) != 0
+      || __builtin_stdc_trailing_zeros (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned char) 2) != 1
+      || __builtin_stdc_trailing_zeros ((unsigned short) 24) != 3
+      || __builtin_stdc_trailing_zeros (32U) != 5
+      || __builtin_stdc_trailing_zeros (128UL) != 7
+      || __builtin_stdc_trailing_zeros (512ULL) != 9)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_trailing_ones ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_trailing_ones (0U) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones (0U), unsigned int)
+      || __builtin_stdc_trailing_ones (0UL) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones (0UL), unsigned int)
+      || __builtin_stdc_trailing_ones (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned char) ~0U) != __CHAR_BIT__
+      || __builtin_stdc_trailing_ones ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || __builtin_stdc_trailing_ones (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || __builtin_stdc_trailing_ones (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || __builtin_stdc_trailing_ones (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned char) 5) != 1
+      || __builtin_stdc_trailing_ones ((unsigned short) 15) != 4
+      || __builtin_stdc_trailing_ones (127U) != 7
+      || __builtin_stdc_trailing_ones (511UL) != 9
+      || __builtin_stdc_trailing_ones (~0ULL >> 2) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 2)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned char) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_first_leading_zero ((unsigned short) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_first_leading_zero (0U) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero (0U), unsigned int)
+      || __builtin_stdc_first_leading_zero (0UL) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero (0UL), unsigned int)
+      || __builtin_stdc_first_leading_zero (0ULL) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned char) ~0U) != 0
+      || __builtin_stdc_first_leading_zero ((unsigned short) ~0U) != 0
+      || __builtin_stdc_first_leading_zero (~0U) != 0
+      || __builtin_stdc_first_leading_zero (~0UL) != 0
+      || __builtin_stdc_first_leading_zero (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned char) ~3U) != __CHAR_BIT__ - 1
+      || __builtin_stdc_first_leading_zero ((unsigned short) ~15U) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+      || __builtin_stdc_first_leading_zero (~63U) != __SIZEOF_INT__ * __CHAR_BIT__ - 5
+      || __builtin_stdc_first_leading_zero (~255UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 7
+      || __builtin_stdc_first_leading_zero (~1023ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_first_leading_one ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_first_leading_one (0U) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one (0U), unsigned int)
+      || __builtin_stdc_first_leading_one (0UL) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one (0UL), unsigned int)
+      || __builtin_stdc_first_leading_one (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned char) ~0U) != 1
+      || __builtin_stdc_first_leading_one ((unsigned short) ~0U) != 1
+      || __builtin_stdc_first_leading_one (~0U) != 1
+      || __builtin_stdc_first_leading_one (~0UL) != 1
+      || __builtin_stdc_first_leading_one (~0ULL) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned char) 3) != __CHAR_BIT__ - 1
+      || __builtin_stdc_first_leading_one ((unsigned short) 9) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+      || __builtin_stdc_first_leading_one (34U) != __SIZEOF_INT__ * __CHAR_BIT__ - 5
+      || __builtin_stdc_first_leading_one (130UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 7
+      || __builtin_stdc_first_leading_one (512ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned char) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_first_trailing_zero ((unsigned short) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_first_trailing_zero (0U) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero (0U), unsigned int)
+      || __builtin_stdc_first_trailing_zero (0UL) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero (0UL), unsigned int)
+      || __builtin_stdc_first_trailing_zero (0ULL) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned char) ~0U) != 0
+      || __builtin_stdc_first_trailing_zero ((unsigned short) ~0U) != 0
+      || __builtin_stdc_first_trailing_zero (~0U) != 0
+      || __builtin_stdc_first_trailing_zero (~0UL) != 0
+      || __builtin_stdc_first_trailing_zero (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned char) 2) != 1
+      || __builtin_stdc_first_trailing_zero ((unsigned short) 15) != 5
+      || __builtin_stdc_first_trailing_zero (63U) != 7
+      || __builtin_stdc_first_trailing_zero (128UL) != 1
+      || __builtin_stdc_first_trailing_zero (511ULL) != 10)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_first_trailing_one ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_first_trailing_one (0U) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one (0U), unsigned int)
+      || __builtin_stdc_first_trailing_one (0UL) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one (0UL), unsigned int)
+      || __builtin_stdc_first_trailing_one (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned char) ~0U) != 1
+      || __builtin_stdc_first_trailing_one ((unsigned short) ~0U) != 1
+      || __builtin_stdc_first_trailing_one (~0U) != 1
+      || __builtin_stdc_first_trailing_one (~0UL) != 1
+      || __builtin_stdc_first_trailing_one (~0ULL) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned char) 4) != 3
+      || __builtin_stdc_first_trailing_one ((unsigned short) 96) != 6
+      || __builtin_stdc_first_trailing_one (127U) != 1
+      || __builtin_stdc_first_trailing_one (511UL) != 1
+      || __builtin_stdc_first_trailing_one (~0ULL << 12) != 13)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned char) 0) != __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_count_zeros ((unsigned short) 0) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_count_zeros (0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros (0U), unsigned int)
+      || __builtin_stdc_count_zeros (0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros (0UL), unsigned int)
+      || __builtin_stdc_count_zeros (0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned char) ~0U) != 0
+      || __builtin_stdc_count_zeros ((unsigned short) ~0U) != 0
+      || __builtin_stdc_count_zeros (~0U) != 0
+      || __builtin_stdc_count_zeros (~0UL) != 0
+      || __builtin_stdc_count_zeros (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned char) 1U) != __CHAR_BIT__ - 1
+      || __builtin_stdc_count_zeros ((unsigned short) 42) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+      || __builtin_stdc_count_zeros (291U) != __SIZEOF_INT__ * __CHAR_BIT__ - 4
+      || __builtin_stdc_count_zeros (~1315UL) != 5
+      || __builtin_stdc_count_zeros (3363ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 6)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_count_ones ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_count_ones (0U) != 0
+      || !expr_has_type (__builtin_stdc_count_ones (0U), unsigned int)
+      || __builtin_stdc_count_ones (0UL) != 0
+      || !expr_has_type (__builtin_stdc_count_ones (0UL), unsigned int)
+      || __builtin_stdc_count_ones (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_count_ones (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned char) ~0U) != __CHAR_BIT__
+      || __builtin_stdc_count_ones ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || __builtin_stdc_count_ones (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || __builtin_stdc_count_ones (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || __builtin_stdc_count_ones (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned char) ~1U) != __CHAR_BIT__ - 1
+      || __builtin_stdc_count_ones ((unsigned short) ~42) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+      || __builtin_stdc_count_ones (~291U) != __SIZEOF_INT__ * __CHAR_BIT__ - 4
+      || __builtin_stdc_count_ones (1315UL) != 5
+      || __builtin_stdc_count_ones (~3363ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 6)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit ((unsigned char) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned char) 0), _Bool)
+      || __builtin_stdc_has_single_bit ((unsigned short) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned short) 0), _Bool)
+      || __builtin_stdc_has_single_bit (0U)
+      || !expr_has_type (__builtin_stdc_has_single_bit (0U), _Bool)
+      || __builtin_stdc_has_single_bit (0UL)
+      || !expr_has_type (__builtin_stdc_has_single_bit (0UL), _Bool)
+      || __builtin_stdc_has_single_bit (0ULL)
+      || !expr_has_type (__builtin_stdc_has_single_bit (0ULL), _Bool))
+    __builtin_abort ();
+  if (!__builtin_stdc_has_single_bit ((unsigned char) 2)
+      || !__builtin_stdc_has_single_bit ((unsigned short) 8)
+      || !__builtin_stdc_has_single_bit (32U)
+      || !__builtin_stdc_has_single_bit (128UL)
+      || !__builtin_stdc_has_single_bit (512ULL))
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit ((unsigned char) 7)
+      || __builtin_stdc_has_single_bit ((unsigned short) 96)
+      || __builtin_stdc_has_single_bit (513U)
+      || __builtin_stdc_has_single_bit (1022UL)
+      || __builtin_stdc_has_single_bit (12ULL))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_bit_width ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_bit_width (0U) != 0
+      || !expr_has_type (__builtin_stdc_bit_width (0U), unsigned int)
+      || __builtin_stdc_bit_width (0UL) != 0
+      || !expr_has_type (__builtin_stdc_bit_width (0UL), unsigned int)
+      || __builtin_stdc_bit_width (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_bit_width (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned char) ~0U) != __CHAR_BIT__
+      || __builtin_stdc_bit_width ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || __builtin_stdc_bit_width (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || __builtin_stdc_bit_width (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || __builtin_stdc_bit_width (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned char) ((unsigned char) ~0U >> 1)) != __CHAR_BIT__ - 1
+      || __builtin_stdc_bit_width ((unsigned char) 6) != 3
+      || __builtin_stdc_bit_width ((unsigned short) 12U) != 4
+      || __builtin_stdc_bit_width ((unsigned short) ((unsigned short) ~0U >> 5)) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 5
+      || __builtin_stdc_bit_width (137U) != 8
+      || __builtin_stdc_bit_width (269U) != 9
+      || __builtin_stdc_bit_width (39UL) != 6
+      || __builtin_stdc_bit_width (~0UL >> 2) != __SIZEOF_LONG__ * __CHAR_BIT__ - 2
+      || __builtin_stdc_bit_width (1023ULL) != 10
+      || __builtin_stdc_bit_width (1024ULL) != 11)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned char) 0), unsigned char)
+      || __builtin_stdc_bit_floor ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned short) 0), unsigned short)
+      || __builtin_stdc_bit_floor (0U) != 0U
+      || !expr_has_type (__builtin_stdc_bit_floor (0U), unsigned int)
+      || __builtin_stdc_bit_floor (0UL) != 0UL
+      || !expr_has_type (__builtin_stdc_bit_floor (0UL), unsigned long)
+      || __builtin_stdc_bit_floor (0ULL) != 0ULL
+      || !expr_has_type (__builtin_stdc_bit_floor (0ULL), unsigned long long))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned char) ~0U) != (1U << (__CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor ((unsigned short) ~0U) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor (~0U) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor (~0UL) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor (~0ULL) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned char) 4) != 4
+      || __builtin_stdc_bit_floor ((unsigned char) 7) != 4
+      || __builtin_stdc_bit_floor ((unsigned short) 8U) != 8
+      || __builtin_stdc_bit_floor ((unsigned short) 31U) != 16
+      || __builtin_stdc_bit_floor (137U) != 128U
+      || __builtin_stdc_bit_floor (269U) != 256U
+      || __builtin_stdc_bit_floor (511UL) != 256UL
+      || __builtin_stdc_bit_floor (512UL) != 512UL
+      || __builtin_stdc_bit_floor (513UL) != 512ULL
+      || __builtin_stdc_bit_floor (1024ULL) != 1024ULL)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned char) 0), unsigned char)
+      || __builtin_stdc_bit_ceil ((unsigned short) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned short) 0), unsigned short)
+      || __builtin_stdc_bit_ceil (0U) != 1U
+      || !expr_has_type (__builtin_stdc_bit_ceil (0U), unsigned int)
+      || __builtin_stdc_bit_ceil (0UL) != 1UL
+      || !expr_has_type (__builtin_stdc_bit_ceil (0UL), unsigned long)
+      || __builtin_stdc_bit_ceil (0ULL) != 1ULL
+      || !expr_has_type (__builtin_stdc_bit_ceil (0ULL), unsigned long long))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) ((unsigned char) ~0U >> 1)) != (1U << (__CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil ((unsigned char) ((unsigned char) ~0U >> 1)) != (1U << (__CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil ((unsigned short) ((unsigned short) ~0U >> 1)) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil ((unsigned short) ((unsigned short) ~0U >> 1)) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0U >> 1) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1)) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0UL >> 1) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0UL >> 1) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0ULL >> 1) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) 1) != 1
+      || __builtin_stdc_bit_ceil ((unsigned char) 2) != 2
+      || __builtin_stdc_bit_ceil ((unsigned short) 3U) != 4
+      || __builtin_stdc_bit_ceil ((unsigned short) 4U) != 4
+      || __builtin_stdc_bit_ceil (5U) != 8U
+      || __builtin_stdc_bit_ceil (269U) != 512U
+      || __builtin_stdc_bit_ceil (511UL) != 512UL
+      || __builtin_stdc_bit_ceil (512UL) != 512UL
+      || __builtin_stdc_bit_ceil (513ULL) != 1024ULL
+      || __builtin_stdc_bit_ceil (1025ULL) != 2048ULL)
+    __builtin_abort ();
+#ifdef __SIZEOF_INT128__
+  if (__builtin_stdc_leading_zeros ((unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_leading_zeros (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_leading_ones (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_trailing_zeros (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_trailing_ones (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned __int128) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_first_leading_zero (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_first_leading_one (~(unsigned __int128) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned __int128) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_first_trailing_zero (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_first_trailing_one (~(unsigned __int128) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_count_zeros (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_count_ones (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit ((unsigned __int128) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned __int128) 0), _Bool)
+      || __builtin_stdc_has_single_bit (~(unsigned __int128) 0))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_bit_width (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned __int128) 0), unsigned __int128)
+      || __builtin_stdc_bit_floor (~(unsigned __int128) 0) != ((unsigned __int128) 1) << (__SIZEOF_INT128__ * __CHAR_BIT__ - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned __int128) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned __int128) 0), unsigned __int128)
+      || __builtin_stdc_bit_ceil ((unsigned __int128) 1) != 1
+      || __builtin_stdc_bit_ceil ((~(unsigned __int128) 0) >> 1) != ((unsigned __int128) 1) << (__SIZEOF_INT128__ * __CHAR_BIT__ - 1))
+    __builtin_abort ();
+#endif
+#if __has_builtin (__builtin_stdc_leading_zeros) != 1
+#error __builtin_stdc_leading_zeros not implemented
+#endif
+#if __has_builtin (__builtin_stdc_leading_ones) != 1
+#error __builtin_stdc_leading_ones not implemented
+#endif
+#if __has_builtin (__builtin_stdc_trailing_zeros) != 1
+#error __builtin_stdc_trailing_zeros not implemented
+#endif
+#if __has_builtin (__builtin_stdc_trailing_ones) != 1
+#error __builtin_stdc_trailing_ones not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_leading_zero) != 1
+#error __builtin_stdc_first_leading_zero not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_leading_one) != 1
+#error __builtin_stdc_first_leading_one not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_trailing_zero) != 1
+#error __builtin_stdc_first_trailing_zero not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_trailing_one) != 1
+#error __builtin_stdc_first_trailing_one not implemented
+#endif
+#if __has_builtin (__builtin_stdc_count_zeros) != 1
+#error __builtin_stdc_count_zeros not implemented
+#endif
+#if __has_builtin (__builtin_stdc_count_ones) != 1
+#error __builtin_stdc_count_ones not implemented
+#endif
+#if __has_builtin (__builtin_stdc_has_single_bit) != 1
+#error __builtin_stdc_single_bit not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_width) != 1
+#error __builtin_stdc_bit_width not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_floor) != 1
+#error __builtin_stdc_bit_floor not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_ceil) != 1
+#error __builtin_stdc_bit_ceil not implemented
+#endif
+  unsigned char a = 0;
+  if (__builtin_stdc_bit_width (a++) != 0 || a != 1)
+    __builtin_abort ();
+  unsigned long long b = 0;
+  if (__builtin_stdc_bit_width (b++) != 0 || b != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (a++) != 1 || a != 2)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (b++) != 1 || b != 2)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (a++) != 2 || a != 3)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (b++) != 2 || b != 3)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros (a++) != __CHAR_BIT__ - 2 || a != 4)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros (b++) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 2 || b != 4)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones (a++) != 0 || a != 5)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones (b++) != 0 || b != 5)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros (a++) != 0 || a != 6)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros (b++) != 0 || b != 6)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones (a++) != 0 || a != 7)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones (b++) != 0 || b != 7)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero (a++) != 1 || a != 8)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero (b++) != 1 || b != 8)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one (a++) != __CHAR_BIT__ - 3 || a != 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one (b++) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 3 || b != 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero (a++) != 2 || a != 10)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero (b++) != 2 || b != 10)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one (a++) != 2 || a != 11)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one (b++) != 2 || b != 11)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros (a++) != __CHAR_BIT__ - 3 || a != 12)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros (b++) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 3 || b != 12)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones (a++) != 2 || a != 13)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones (b++) != 2 || b != 13)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit (a++) || a != 14)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit (b++) || b != 14)
+    __builtin_abort ();
+#if __BITINT_MAXWIDTH__ >= 512
+  if (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 0) != 512
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_leading_zeros ((unsigned _BitInt(373)) 0) != 373
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_leading_zeros (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 275) != 512 - 9
+      || __builtin_stdc_leading_zeros ((unsigned _BitInt(373)) 512) != 373 - 10)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_leading_ones ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones (~(unsigned _BitInt(512)) 0) != 512
+      || __builtin_stdc_leading_ones (~(unsigned _BitInt(373)) 0) != 373)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones (~(unsigned _BitInt(512)) 275) != 512 - 9
+      || __builtin_stdc_leading_ones (~(unsigned _BitInt(373)) 512) != 373 - 10)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned _BitInt(512)) 0) != 512
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_trailing_zeros ((unsigned _BitInt(373)) 0) != 373
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_trailing_zeros (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned _BitInt(512)) 256) != 8
+      || __builtin_stdc_trailing_zeros ((unsigned _BitInt(373)) 512) != 9)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_trailing_ones ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones (~(unsigned _BitInt(512)) 0) != 512
+      || __builtin_stdc_trailing_ones (~(unsigned _BitInt(373)) 0) != 373)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned _BitInt(512)) 255) != 8
+      || __builtin_stdc_trailing_ones ((~(unsigned _BitInt(373)) 0) >> 2) != 373 - 2)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned _BitInt(512)) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_first_leading_zero ((unsigned _BitInt(373)) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_first_leading_zero (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero (~(unsigned _BitInt(512)) 511) != 512 - 8
+      || __builtin_stdc_first_leading_zero (~(unsigned _BitInt(373)) 1023) != 373 - 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_first_leading_one ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one (~(unsigned _BitInt(512)) 0) != 1
+      || __builtin_stdc_first_leading_one (~(unsigned _BitInt(373)) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned _BitInt(512)) 275) != 512 - 8
+      || __builtin_stdc_first_leading_one ((unsigned _BitInt(373)) 512) != 373 - 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(512)) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_first_trailing_zero ((unsigned _BitInt(373)) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_first_trailing_zero (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(512)) 255) != 9
+      || __builtin_stdc_first_trailing_zero ((unsigned _BitInt(373)) 511) != 10)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_first_trailing_one ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one (~(unsigned _BitInt(512)) 0) != 1
+      || __builtin_stdc_first_trailing_one (~(unsigned _BitInt(373)) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one (((unsigned _BitInt(512)) 255) << 175) != 176
+      || __builtin_stdc_first_trailing_one ((~(unsigned _BitInt(373)) 0) << 311) != 312)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned _BitInt(512)) 0) != 512
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_count_zeros ((unsigned _BitInt(373)) 0) != 373
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_count_zeros (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned _BitInt(512)) 1315) != 512 - 5
+      || __builtin_stdc_count_zeros ((unsigned _BitInt(373)) 3363) != 373 - 6)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_count_ones ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones (~(unsigned _BitInt(512)) 0) != 512
+      || __builtin_stdc_count_ones (~(unsigned _BitInt(373)) 0) != 373)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones (~(unsigned _BitInt(512)) 1315) != 512 - 5
+      || __builtin_stdc_count_ones (~(unsigned _BitInt(373)) 3363) != 373 - 6)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit ((unsigned _BitInt(512)) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned _BitInt(512)) 0), _Bool)
+      || __builtin_stdc_has_single_bit ((unsigned _BitInt(373)) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned _BitInt(373)) 0), _Bool))
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit (~(unsigned _BitInt(512)) 0)
+      || __builtin_stdc_has_single_bit (~(unsigned _BitInt(373)) 0))
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit (((unsigned _BitInt(512)) 1022) << 279)
+      || __builtin_stdc_has_single_bit (((unsigned _BitInt(373)) 12) << 305))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_bit_width ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width (~(unsigned _BitInt(512)) 0) != 512
+      || __builtin_stdc_bit_width (~(unsigned _BitInt(373)) 0) != 373)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width (((unsigned _BitInt(512)) 1023) << 405) != 405 + 10
+      || __builtin_stdc_bit_width (((unsigned _BitInt(373)) 1024) << 242) != 242 + 11)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned _BitInt(512)) 0), unsigned _BitInt(512))
+      || __builtin_stdc_bit_floor ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned _BitInt(373)) 0), unsigned _BitInt(373)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (~(unsigned _BitInt(512)) 0) != ((unsigned _BitInt(512)) 1) << (512 - 1)
+      || __builtin_stdc_bit_floor (~(unsigned _BitInt(373)) 0) != ((unsigned _BitInt(373)) 1) << (373 - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (((unsigned _BitInt(512)) 511) << 405) != (((unsigned _BitInt(512)) 256) << 405)
+      || __builtin_stdc_bit_floor (((unsigned _BitInt(373)) 512) << 242) != (((unsigned _BitInt(512)) 512) << 242))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned _BitInt(512)) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned _BitInt(512)) 0), unsigned _BitInt(512))
+      || __builtin_stdc_bit_ceil ((unsigned _BitInt(373)) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned _BitInt(373)) 0), unsigned _BitInt(373)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(512)) 1) << (512 - 1)) != ((unsigned _BitInt(512)) 1) << (512 - 1)
+      || __builtin_stdc_bit_ceil ((~(unsigned _BitInt(373)) 0) >> 1) != ((unsigned _BitInt(373)) 1) << (373 - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(512)) 512) << 405) != (((unsigned _BitInt(512)) 512) << 405)
+      || __builtin_stdc_bit_ceil (((unsigned _BitInt(373)) 513) << 242) != (((unsigned _BitInt(512)) 1024) << 242))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (~(unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1) << (__BITINT_MAXWIDTH__ - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 511) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 256) << 405)
+      || __builtin_stdc_bit_floor (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1) << (__BITINT_MAXWIDTH__ - 1)) != ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1) << (__BITINT_MAXWIDTH__ - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405)
+      || __builtin_stdc_bit_ceil (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 513) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1024) << 405))
+    __builtin_abort ();
+#endif
+}
--- gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c.jj	2023-11-20 11:18:55.758125897 +0100
+++ gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c	2023-11-20 15:04:20.126724395 +0100
@@ -0,0 +1,150 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+  typedef int V __attribute__ ((vector_size (4 * sizeof (int))));
+  struct S { int s; };
+  enum E { E0, E1 };
+  __builtin_stdc_leading_zeros (0.0f);	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros (0.0);	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros (0.0L);	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros ((V) {});	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_leading_zeros'" } */
+  __builtin_stdc_leading_zeros (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_leading_zeros'" } */
+  __builtin_stdc_leading_zeros ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_leading_zeros ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_leading_zeros (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_leading_ones (0.0f);	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones (0.0);	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones (0.0L);	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones ((V) {});	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_leading_ones'" } */
+  __builtin_stdc_leading_ones (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_leading_ones'" } */
+  __builtin_stdc_leading_ones ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_leading_ones ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_leading_ones (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_trailing_zeros (0.0f);	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros (0.0);	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros (0.0L);	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros ((V) {});	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_zeros'" } */
+  __builtin_stdc_trailing_zeros (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_zeros'" } */
+  __builtin_stdc_trailing_zeros ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+  __builtin_stdc_trailing_zeros ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+  __builtin_stdc_trailing_zeros (0);		/* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+  __builtin_stdc_trailing_ones (0.0f);	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones (0.0);	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones (0.0L);	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones ((V) {});	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_ones'" } */
+  __builtin_stdc_trailing_ones (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_ones'" } */
+  __builtin_stdc_trailing_ones ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+  __builtin_stdc_trailing_ones ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+  __builtin_stdc_trailing_ones (0);		/* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+  __builtin_stdc_first_leading_zero (0.0f);	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero (0.0);	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero (0.0L);	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero ((V) {});	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_zero'" } */
+  __builtin_stdc_first_leading_zero (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_zero'" } */
+  __builtin_stdc_first_leading_zero ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_first_leading_zero ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_first_leading_zero (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_first_leading_one (0.0f);	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one (0.0);	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one (0.0L);	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one ((V) {});	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_one'" } */
+  __builtin_stdc_first_leading_one (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_one'" } */
+  __builtin_stdc_first_leading_one ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_first_leading_one ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_first_leading_one (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_first_trailing_zero (0.0f);	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero (0.0);	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero (0.0L);	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero ((V) {});	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_zero'" } */
+  __builtin_stdc_first_trailing_zero (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_zero'" } */
+  __builtin_stdc_first_trailing_zero ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+  __builtin_stdc_first_trailing_zero ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+  __builtin_stdc_first_trailing_zero (0);		/* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+  __builtin_stdc_first_trailing_one (0.0f);	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one (0.0);	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one (0.0L);	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one ((V) {});	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_one'" } */
+  __builtin_stdc_first_trailing_one (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_one'" } */
+  __builtin_stdc_first_trailing_one ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+  __builtin_stdc_first_trailing_one ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+  __builtin_stdc_first_trailing_one (0);		/* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+  __builtin_stdc_count_zeros (0.0f);	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros (0.0);	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros (0.0L);	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros ((V) {});	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_count_zeros'" } */
+  __builtin_stdc_count_zeros (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_count_zeros'" } */
+  __builtin_stdc_count_zeros ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has boolean type" } */
+  __builtin_stdc_count_zeros ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has enumerated type" } */
+  __builtin_stdc_count_zeros (0);		/* { dg-error "argument 1 in call to function '__builtin_popcountg' has signed type" } */
+  __builtin_stdc_count_ones (0.0f);	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones (0.0);	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones (0.0L);	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones ((V) {});	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_count_ones'" } */
+  __builtin_stdc_count_ones (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_count_ones'" } */
+  __builtin_stdc_count_ones ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has boolean type" } */
+  __builtin_stdc_count_ones ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has enumerated type" } */
+  __builtin_stdc_count_ones (0);		/* { dg-error "argument 1 in call to function '__builtin_popcountg' has signed type" } */
+  __builtin_stdc_has_single_bit (0.0f);	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit (0.0);	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit (0.0L);	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit ((V) {});	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_has_single_bit'" } */
+  __builtin_stdc_has_single_bit (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_has_single_bit'" } */
+  __builtin_stdc_has_single_bit ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has boolean type" } */
+  __builtin_stdc_has_single_bit ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has enumerated type" } */
+  __builtin_stdc_has_single_bit (0);		/* { dg-error "argument 1 in call to function '__builtin_popcountg' has signed type" } */
+  __builtin_stdc_bit_width (0.0f);	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width (0.0);	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width (0.0L);	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width ((V) {});	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_width'" } */
+  __builtin_stdc_bit_width (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_width'" } */
+  __builtin_stdc_bit_width ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_bit_width ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_bit_width (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_bit_floor (0.0f);	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor (0.0);	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor (0.0L);	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor ((V) {});	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_floor'" } */
+  __builtin_stdc_bit_floor (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_floor'" } */
+  __builtin_stdc_bit_floor ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_bit_floor ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_bit_floor (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_bit_ceil (0.0f);	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil (0.0);	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil (0.0L);	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil ((V) {});	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_ceil'" } */
+  __builtin_stdc_bit_ceil (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_ceil'" } */
+  __builtin_stdc_bit_ceil ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_bit_ceil ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_bit_ceil (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+}


	Jakub


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

* Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
  2023-11-20 14:55 ` Joseph Myers
  2023-11-20 15:03   ` Jakub Jelinek
@ 2023-11-20 15:12   ` Jakub Jelinek
  2023-11-21 23:35     ` Joseph Myers
  1 sibling, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2023-11-20 15:12 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc-patches, Florian Weimer

On Mon, Nov 20, 2023 at 02:55:33PM +0000, 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


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

* Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
  2023-11-20 15:03   ` Jakub Jelinek
@ 2023-11-20 15:29     ` Jakub Jelinek
  2023-11-21  8:24       ` Jakub Jelinek
  2023-11-23  0:09       ` Joseph Myers
  0 siblings, 2 replies; 9+ messages in thread
From: Jakub Jelinek @ 2023-11-20 15:29 UTC (permalink / raw)
  To: Joseph Myers, gcc-patches, Florian Weimer

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  <jakub@redhat.com>

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.cc	2023-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_stdc_first_trailing_one", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_first_trailing_zero", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_has_single_bit", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_leading_ones", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_leading_zeros", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_trailing_ones", RID_BUILTIN_STDC, D_CONLY },
+  { "__builtin_stdc_trailing_zeros", RID_BUILTIN_STDC, D_CONLY },
   { "__builtin_tgmath", RID_BUILTIN_TGMATH, D_CONLY },
   { "__builtin_offsetof", RID_OFFSETOF, 0 },
   { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
--- gcc/doc/extend.texi.jj	2023-11-20 10:37:47.181394361 +0100
+++ gcc/doc/extend.texi	2023-11-20 16:13:31.686572023 +0100
@@ -15075,6 +15075,125 @@ unsigned integer (standard, extended or
 promotions are performed on the argument.
 @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}) 2 << (@var{prec} - 1 - __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{@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{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{unsigned int __builtin_stdc_count_ones (@var{type} @var{arg})}
+The @code{__builtin_stdc_count_ones} 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) __builtin_popcountg (@var{arg})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_count_zeros (@var{type} @var{arg})}
+The @code{__builtin_stdc_count_zeros} 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) __builtin_popcountg ((@var{type}) ~@var{arg})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_leading_one (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_leading_one} 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{__builtin_clzg (@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_leading_zero (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_leading_zero} 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{__builtin_clzg ((@var{type}) ~@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_trailing_one (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_trailing_one} 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{__builtin_ctzg (@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_first_trailing_zero (@var{type} @var{arg})}
+The @code{__builtin_stdc_first_trailing_zero} 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{__builtin_ctzg ((@var{type}) ~@var{arg}, -1) + 1U}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_has_single_bit (@var{type} @var{arg})}
+The @code{__builtin_stdc_has_single_bit} 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{(_Bool) (__builtin_popcountg (@var{arg}) == 1)}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_leading_ones (@var{type} @var{arg})}
+The @code{__builtin_stdc_leading_ones} 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) __builtin_clzg ((@var{type}) ~@var{arg}, @var{prec})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_leading_zeros (@var{type} @var{arg})}
+The @code{__builtin_stdc_leading_zeros} 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) __builtin_clzg (@var{arg}, @var{prec})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_trailing_ones (@var{type} @var{arg})}
+The @code{__builtin_stdc_trailing_ones} 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) __builtin_ctzg ((@var{type}) ~@var{arg}, @var{prec})}
+@enddefbuiltin
+
+@defbuiltin{unsigned int __builtin_stdc_trailing_zeros (@var{type} @var{arg})}
+The @code{__builtin_stdc_trailing_zeros} 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) __builtin_ctzg (@var{arg}, @var{prec})}
+@enddefbuiltin
+
 @defbuiltin{double __builtin_powi (double, int)}
 @defbuiltinx{float __builtin_powif (float, int)}
 @defbuiltinx{{long double} __builtin_powil (long double, int)}
--- gcc/c/c-parser.cc.jj	2023-11-20 09:49:34.778674562 +0100
+++ gcc/c/c-parser.cc	2023-11-20 16:21:52.632659333 +0100
@@ -11743,6 +11743,297 @@ c_parser_postfix_expression (c_parser *p
 	    set_c_expr_source_range (&expr, start_loc, end_loc);
 	  }
 	  break;
+	case RID_BUILTIN_STDC:
+	  {
+	    vec<c_expr_t, va_gc> *cexpr_list;
+	    c_expr_t *arg_p;
+	    location_t close_paren_loc;
+	    enum c_builtin_stdc {
+	      C_BUILTIN_STDC_BIT_CEIL,
+	      C_BUILTIN_STDC_BIT_FLOOR,
+	      C_BUILTIN_STDC_BIT_WIDTH,
+	      C_BUILTIN_STDC_COUNT_ONES,
+	      C_BUILTIN_STDC_COUNT_ZEROS,
+	      C_BUILTIN_STDC_FIRST_LEADING_ONE,
+	      C_BUILTIN_STDC_FIRST_LEADING_ZERO,
+	      C_BUILTIN_STDC_FIRST_TRAILING_ONE,
+	      C_BUILTIN_STDC_FIRST_TRAILING_ZERO,
+	      C_BUILTIN_STDC_HAS_SINGLE_BIT,
+	      C_BUILTIN_STDC_LEADING_ONES,
+	      C_BUILTIN_STDC_LEADING_ZEROS,
+	      C_BUILTIN_STDC_TRAILING_ONES,
+	      C_BUILTIN_STDC_TRAILING_ZEROS,
+	      C_BUILTIN_STDC_MAX
+	    } stdc_rid = C_BUILTIN_STDC_MAX;
+	    const char *name
+	      = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+	    switch (name[sizeof ("__builtin_stdc_") - 1])
+	      {
+	      case 'b':
+		switch (name[sizeof ("__builtin_stdc_bit_") - 1])
+		  {
+		  case 'c':
+		    stdc_rid = C_BUILTIN_STDC_BIT_CEIL;
+		    break;
+		  case 'f':
+		    stdc_rid = C_BUILTIN_STDC_BIT_FLOOR;
+		    break;
+		  default:
+		    stdc_rid = C_BUILTIN_STDC_BIT_WIDTH;
+		    break;
+		  }
+		break;
+	      case 'c':
+		if (name[sizeof ("__builtin_stdc_count_") - 1] == 'o')
+		  stdc_rid = C_BUILTIN_STDC_COUNT_ONES;
+		else
+		  stdc_rid = C_BUILTIN_STDC_COUNT_ZEROS;
+		break;
+	      case 'f':
+		switch (name[sizeof ("__builtin_stdc_first_trailing_") - 1])
+		  {
+		  case 'n':
+		    stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ONE;
+		    break;
+		  case 'e':
+		    stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ZERO;
+		    break;
+		  case 'o':
+		    stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ONE;
+		    break;
+		  default:
+		    stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ZERO;
+		    break;
+		  }
+		break;
+	      case 'h':
+		stdc_rid = C_BUILTIN_STDC_HAS_SINGLE_BIT;
+		break;
+	      case 'l':
+		if (name[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
+		  stdc_rid = C_BUILTIN_STDC_LEADING_ONES;
+		else
+		  stdc_rid = C_BUILTIN_STDC_LEADING_ZEROS;
+		break;
+	      case 't':
+		if (name[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
+		  stdc_rid = C_BUILTIN_STDC_TRAILING_ONES;
+		else
+		  stdc_rid = C_BUILTIN_STDC_TRAILING_ZEROS;
+		break;
+	      }
+	    gcc_checking_assert (stdc_rid != C_BUILTIN_STDC_MAX);
+
+	    c_parser_consume_token (parser);
+	    if (!c_parser_get_builtin_args (parser, name,
+					    &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 %qs", name);
+		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, "%qs operand not an integral type", name);
+		expr.set_error ();
+		break;
+	      }
+	    tree arg = arg_p->value;
+	    tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
+	    /* Expand:
+	       __builtin_stdc_leading_zeros (arg) as
+		 (unsigned int) __builtin_clzg (arg, prec)
+	       __builtin_stdc_leading_ones (arg) as
+		 (unsigned int) __builtin_clzg ((type) ~arg, prec)
+	       __builtin_stdc_trailing_zeros (arg) as
+		 (unsigned int) __builtin_ctzg (arg, prec)
+	       __builtin_stdc_trailing_ones (arg) as
+		 (unsigned int) __builtin_ctzg ((type) ~arg, prec)
+	       __builtin_stdc_first_leading_zero (arg) as
+		 __builtin_clzg ((type) ~arg, -1) + 1U
+	       __builtin_stdc_first_leading_one (arg) as
+		 __builtin_clzg (arg, -1) + 1U
+	       __builtin_stdc_first_trailing_zero (arg) as
+		 __builtin_ctzg ((type) ~arg, -1) + 1U
+	       __builtin_stdc_first_trailing_one (arg) as
+		 __builtin_ctzg (arg, -1) + 1U
+	       __builtin_stdc_count_zeros (arg) as
+		 (unsigned int) __builtin_popcountg ((type) ~arg)
+	       __builtin_stdc_count_ones (arg) as
+		 (unsigned int) __builtin_popcountg (arg)
+	       __builtin_stdc_has_single_bit (arg) as
+		 (_Bool) (__builtin_popcountg (arg) == 1)
+	       __builtin_stdc_bit_width (arg) as
+		 (unsigned int) (prec - __builtin_clzg (arg, prec))
+	       __builtin_stdc_bit_floor (arg) as
+		 arg == 0 ? (type) 0
+			  : (type) 1 << (prec - 1 - __builtin_clzg (arg))
+	       __builtin_stdc_bit_ceil (arg) as
+		 arg <= 1 ? (type) 1
+			  : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
+	       without evaluating arg multiple times, type being
+	       __typeof (arg) and prec __builtin_popcountg ((type) ~0)).  */
+	    int prec = TYPE_PRECISION (type);
+	    tree barg1 = arg;
+	    switch (stdc_rid)
+	      {
+	      case C_BUILTIN_STDC_BIT_CEIL:
+		arg = save_expr (arg);
+		barg1 = build2_loc (loc, PLUS_EXPR, type, arg,
+				    build_int_cst (type, -1));
+		break;
+	      case C_BUILTIN_STDC_BIT_FLOOR:
+		barg1 = arg = save_expr (arg);
+		break;
+	      case C_BUILTIN_STDC_COUNT_ZEROS:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+	      case C_BUILTIN_STDC_LEADING_ONES:
+	      case C_BUILTIN_STDC_TRAILING_ONES:
+		barg1 = build1_loc (loc, BIT_NOT_EXPR, type, arg);
+		break;
+	      default:
+		break;
+	      }
+	    tree barg2 = NULL_TREE;
+	    switch (stdc_rid)
+	      {
+	      case C_BUILTIN_STDC_BIT_WIDTH:
+	      case C_BUILTIN_STDC_LEADING_ONES:
+	      case C_BUILTIN_STDC_LEADING_ZEROS:
+	      case C_BUILTIN_STDC_TRAILING_ONES:
+	      case C_BUILTIN_STDC_TRAILING_ZEROS:
+		barg2 = build_int_cst (integer_type_node, prec);
+		break;
+	      case C_BUILTIN_STDC_FIRST_LEADING_ONE:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+		barg2 = integer_minus_one_node;
+		break;
+	      default:
+		break;
+	      }
+	    tree fndecl = NULL_TREE;
+	    switch (stdc_rid)
+	      {
+	      case C_BUILTIN_STDC_BIT_CEIL:
+	      case C_BUILTIN_STDC_BIT_FLOOR:
+	      case C_BUILTIN_STDC_BIT_WIDTH:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ONE:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+	      case C_BUILTIN_STDC_LEADING_ONES:
+	      case C_BUILTIN_STDC_LEADING_ZEROS:
+		fndecl = builtin_decl_explicit (BUILT_IN_CLZG);
+		break;
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+	      case C_BUILTIN_STDC_TRAILING_ONES:
+	      case C_BUILTIN_STDC_TRAILING_ZEROS:
+		fndecl = builtin_decl_explicit (BUILT_IN_CTZG);
+		break;
+	      case C_BUILTIN_STDC_COUNT_ONES:
+	      case C_BUILTIN_STDC_COUNT_ZEROS:
+	      case C_BUILTIN_STDC_HAS_SINGLE_BIT:
+		fndecl = builtin_decl_explicit (BUILT_IN_POPCOUNTG);
+		break;
+	      default:
+		gcc_unreachable ();
+	      }
+	    /* Construct a call to __builtin_{clz,ctz,popcount}g.  */
+	    int nargs = barg2 != NULL_TREE ? 2 : 1;
+	    vec<tree, va_gc> *args;
+	    vec_alloc (args, nargs);
+	    vec<tree, va_gc> *origtypes;
+	    vec_alloc (origtypes, nargs);
+	    auto_vec<location_t> arg_loc (nargs);
+	    args->quick_push (barg1);
+	    arg_loc.quick_push (arg_p->get_location ());
+	    origtypes->quick_push (arg_p->original_type);
+	    if (nargs == 2)
+	      {
+		args->quick_push (barg2);
+		arg_loc.quick_push (loc);
+		origtypes->quick_push (integer_type_node);
+	      }
+	    expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
+						    args, origtypes);
+	    set_c_expr_source_range (&expr, loc, close_paren_loc);
+	    if (expr.value == error_mark_node)
+	      break;
+	    switch (stdc_rid)
+	      {
+	      case C_BUILTIN_STDC_BIT_CEIL:
+	      case C_BUILTIN_STDC_BIT_FLOOR:
+		--prec;
+		/* FALLTHRU */
+	      case C_BUILTIN_STDC_BIT_WIDTH:
+		expr.value = build2_loc (loc, MINUS_EXPR, integer_type_node,
+					 build_int_cst (integer_type_node,
+							prec), expr.value);
+		break;
+	      case C_BUILTIN_STDC_FIRST_LEADING_ONE:
+	      case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
+	      case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
+		expr.value = build2_loc (loc, PLUS_EXPR, integer_type_node,
+					 expr.value, integer_one_node);
+		break;
+	      case C_BUILTIN_STDC_HAS_SINGLE_BIT:
+		expr.value = build2_loc (loc, EQ_EXPR, boolean_type_node,
+					 expr.value, integer_one_node);
+		break;
+	      default:
+		break;
+	      }
+
+	    if (stdc_rid != C_BUILTIN_STDC_BIT_CEIL
+		&& stdc_rid != C_BUILTIN_STDC_BIT_FLOOR)
+	      {
+		if (stdc_rid != C_BUILTIN_STDC_HAS_SINGLE_BIT)
+		  expr.value = fold_convert_loc (loc, unsigned_type_node,
+						 expr.value);
+		break;
+	      }
+	    /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
+	       or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
+	       warnings.  The LSHIFT_EXPR is in dead code in that case.  */
+	    if (integer_zerop (arg)
+		|| (stdc_rid == C_BUILTIN_STDC_BIT_CEIL && integer_onep (arg)))
+	      expr.value = build_int_cst (type, 0);
+	    else
+	      expr.value
+		= build2_loc (loc, LSHIFT_EXPR, type,
+			      build_int_cst (type,
+					     (stdc_rid
+					      == C_BUILTIN_STDC_BIT_CEIL
+					      ? 2 : 1)), expr.value);
+	    if (stdc_rid == C_BUILTIN_STDC_BIT_CEIL)
+	      expr.value = build3_loc (loc, COND_EXPR, type,
+				       build2_loc (loc, LE_EXPR,
+						   boolean_type_node, arg,
+						   build_int_cst (type, 1)),
+				       build_int_cst (type, 1),
+				       expr.value);
+	    else
+	      expr.value = build3_loc (loc, COND_EXPR, type,
+				       build2_loc (loc, EQ_EXPR,
+						   boolean_type_node, arg,
+						   build_int_cst (type, 0)),
+				       build_int_cst (type, 0),
+				       expr.value);
+	    break;
+	  }
 	case RID_AT_SELECTOR:
 	  {
 	    gcc_assert (c_dialect_objc ());
--- gcc/c/c-decl.cc.jj	2023-11-20 09:49:34.767674716 +0100
+++ gcc/c/c-decl.cc	2023-11-20 14:21:23.460450475 +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_CONVERTVECTOR:
     case RID_BUILTIN_HAS_ATTRIBUTE:
     case RID_BUILTIN_SHUFFLE:
     case RID_BUILTIN_SHUFFLEVECTOR:
-    case RID_BUILTIN_ASSOC_BARRIER:
+    case RID_BUILTIN_STDC:
     case RID_CHOOSE_EXPR:
     case RID_OFFSETOF:
     case RID_TYPES_COMPATIBLE_P:
--- gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c.jj	2023-11-20 11:18:55.757125910 +0100
+++ gcc/testsuite/gcc.dg/builtin-stdc-bit-1.c	2023-11-20 16:25:22.548758830 +0100
@@ -0,0 +1,846 @@
+/* { dg-do run } */
+/* { dg-options "-std=c11" } */
+
+unsigned int
+leading_zeros (unsigned char a, unsigned short b, unsigned int c,
+	       unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_leading_zeros (a)
+	  + __builtin_stdc_leading_zeros (b)
+	  + __builtin_stdc_leading_zeros (c)
+	  + __builtin_stdc_leading_zeros (d)
+	  + __builtin_stdc_leading_zeros (e));
+}
+
+unsigned int
+leading_ones (unsigned char a, unsigned short b, unsigned int c,
+	      unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_leading_ones (a)
+	  + __builtin_stdc_leading_ones (b)
+	  + __builtin_stdc_leading_ones (c)
+	  + __builtin_stdc_leading_ones (d)
+	  + __builtin_stdc_leading_ones (e));
+}
+
+unsigned int
+trailing_zeros (unsigned char a, unsigned short b, unsigned int c,
+		unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_trailing_zeros (a)
+	  + __builtin_stdc_trailing_zeros (b)
+	  + __builtin_stdc_trailing_zeros (c)
+	  + __builtin_stdc_trailing_zeros (d)
+	  + __builtin_stdc_trailing_zeros (e));
+}
+
+unsigned int
+trailing_ones (unsigned char a, unsigned short b, unsigned int c,
+	       unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_trailing_ones (a)
+	  + __builtin_stdc_trailing_ones (b)
+	  + __builtin_stdc_trailing_ones (c)
+	  + __builtin_stdc_trailing_ones (d)
+	  + __builtin_stdc_trailing_ones (e));
+}
+
+unsigned int
+first_leading_zero (unsigned char a, unsigned short b, unsigned int c,
+		    unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_first_leading_zero (a)
+	  + __builtin_stdc_first_leading_zero (b)
+	  + __builtin_stdc_first_leading_zero (c)
+	  + __builtin_stdc_first_leading_zero (d)
+	  + __builtin_stdc_first_leading_zero (e));
+}
+
+unsigned int
+first_leading_one (unsigned char a, unsigned short b, unsigned int c,
+		   unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_first_leading_one (a)
+	  + __builtin_stdc_first_leading_one (b)
+	  + __builtin_stdc_first_leading_one (c)
+	  + __builtin_stdc_first_leading_one (d)
+	  + __builtin_stdc_first_leading_one (e));
+}
+
+unsigned int
+first_trailing_zero (unsigned char a, unsigned short b, unsigned int c,
+		     unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_first_trailing_zero (a)
+	  + __builtin_stdc_first_trailing_zero (b)
+	  + __builtin_stdc_first_trailing_zero (c)
+	  + __builtin_stdc_first_trailing_zero (d)
+	  + __builtin_stdc_first_trailing_zero (e));
+}
+
+unsigned int
+first_trailing_one (unsigned char a, unsigned short b, unsigned int c,
+		    unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_first_trailing_one (a)
+	  + __builtin_stdc_first_trailing_one (b)
+	  + __builtin_stdc_first_trailing_one (c)
+	  + __builtin_stdc_first_trailing_one (d)
+	  + __builtin_stdc_first_trailing_one (e));
+}
+
+unsigned int
+count_zeros (unsigned char a, unsigned short b, unsigned int c,
+	     unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_count_zeros (a)
+	  + __builtin_stdc_count_zeros (b)
+	  + __builtin_stdc_count_zeros (c)
+	  + __builtin_stdc_count_zeros (d)
+	  + __builtin_stdc_count_zeros (e));
+}
+
+unsigned int
+count_ones (unsigned char a, unsigned short b, unsigned int c,
+	    unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_count_ones (a)
+	  + __builtin_stdc_count_ones (b)
+	  + __builtin_stdc_count_ones (c)
+	  + __builtin_stdc_count_ones (d)
+	  + __builtin_stdc_count_ones (e));
+}
+
+unsigned int
+has_single_bit (unsigned char a, unsigned short b, unsigned int c,
+		unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_has_single_bit (a)
+	  || __builtin_stdc_has_single_bit (b)
+	  || __builtin_stdc_has_single_bit (c)
+	  || __builtin_stdc_has_single_bit (d)
+	  || __builtin_stdc_has_single_bit (e));
+}
+
+unsigned int
+bit_width (unsigned char a, unsigned short b, unsigned int c,
+	   unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_bit_width (a)
+	  + __builtin_stdc_bit_width (b)
+	  + __builtin_stdc_bit_width (c)
+	  + __builtin_stdc_bit_width (d)
+	  + __builtin_stdc_bit_width (e));
+}
+
+unsigned long long
+bit_floor (unsigned char a, unsigned short b, unsigned int c,
+	   unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_bit_floor (a)
+	  + __builtin_stdc_bit_floor (b)
+	  + __builtin_stdc_bit_floor (c)
+	  + __builtin_stdc_bit_floor (d)
+	  + __builtin_stdc_bit_floor (e));
+}
+
+unsigned long long
+bit_ceil (unsigned char a, unsigned short b, unsigned int c,
+	  unsigned long d, unsigned long long e)
+{
+  return (__builtin_stdc_bit_ceil (a)
+	  + __builtin_stdc_bit_ceil (b)
+	  + __builtin_stdc_bit_ceil (c)
+	  + __builtin_stdc_bit_ceil (d)
+	  + __builtin_stdc_bit_ceil (e));
+}
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+
+int
+main ()
+{
+  if (__builtin_stdc_leading_zeros ((unsigned char) 0) != __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_leading_zeros ((unsigned short) 0) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_leading_zeros (0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros (0U), unsigned int)
+      || __builtin_stdc_leading_zeros (0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros (0UL), unsigned int)
+      || __builtin_stdc_leading_zeros (0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros ((unsigned char) ~0U) != 0
+      || __builtin_stdc_leading_zeros ((unsigned short) ~0U) != 0
+      || __builtin_stdc_leading_zeros (~0U) != 0
+      || __builtin_stdc_leading_zeros (~0UL) != 0
+      || __builtin_stdc_leading_zeros (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros ((unsigned char) 3) != __CHAR_BIT__ - 2
+      || __builtin_stdc_leading_zeros ((unsigned short) 9) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 4
+      || __builtin_stdc_leading_zeros (34U) != __SIZEOF_INT__ * __CHAR_BIT__ - 6
+      || __builtin_stdc_leading_zeros (130UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 8
+      || __builtin_stdc_leading_zeros (512ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 10)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_leading_ones ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_leading_ones (0U) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones (0U), unsigned int)
+      || __builtin_stdc_leading_ones (0UL) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones (0UL), unsigned int)
+      || __builtin_stdc_leading_ones (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned char) ~0U) != __CHAR_BIT__
+      || __builtin_stdc_leading_ones ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || __builtin_stdc_leading_ones (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || __builtin_stdc_leading_ones (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || __builtin_stdc_leading_ones (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned char) ~3) != __CHAR_BIT__ - 2
+      || __builtin_stdc_leading_ones ((unsigned short) ~9) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 4
+      || __builtin_stdc_leading_ones (~34U) != __SIZEOF_INT__ * __CHAR_BIT__ - 6
+      || __builtin_stdc_leading_ones (~130UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 8
+      || __builtin_stdc_leading_ones (~512ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 10)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned char) 0) != __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_trailing_zeros ((unsigned short) 0) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_trailing_zeros (0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros (0U), unsigned int)
+      || __builtin_stdc_trailing_zeros (0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros (0UL), unsigned int)
+      || __builtin_stdc_trailing_zeros (0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned char) ~0U) != 0
+      || __builtin_stdc_trailing_zeros ((unsigned short) ~0U) != 0
+      || __builtin_stdc_trailing_zeros (~0U) != 0
+      || __builtin_stdc_trailing_zeros (~0UL) != 0
+      || __builtin_stdc_trailing_zeros (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned char) 2) != 1
+      || __builtin_stdc_trailing_zeros ((unsigned short) 24) != 3
+      || __builtin_stdc_trailing_zeros (32U) != 5
+      || __builtin_stdc_trailing_zeros (128UL) != 7
+      || __builtin_stdc_trailing_zeros (512ULL) != 9)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_trailing_ones ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_trailing_ones (0U) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones (0U), unsigned int)
+      || __builtin_stdc_trailing_ones (0UL) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones (0UL), unsigned int)
+      || __builtin_stdc_trailing_ones (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned char) ~0U) != __CHAR_BIT__
+      || __builtin_stdc_trailing_ones ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || __builtin_stdc_trailing_ones (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || __builtin_stdc_trailing_ones (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || __builtin_stdc_trailing_ones (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned char) 5) != 1
+      || __builtin_stdc_trailing_ones ((unsigned short) 15) != 4
+      || __builtin_stdc_trailing_ones (127U) != 7
+      || __builtin_stdc_trailing_ones (511UL) != 9
+      || __builtin_stdc_trailing_ones (~0ULL >> 2) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 2)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned char) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_first_leading_zero ((unsigned short) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_first_leading_zero (0U) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero (0U), unsigned int)
+      || __builtin_stdc_first_leading_zero (0UL) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero (0UL), unsigned int)
+      || __builtin_stdc_first_leading_zero (0ULL) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned char) ~0U) != 0
+      || __builtin_stdc_first_leading_zero ((unsigned short) ~0U) != 0
+      || __builtin_stdc_first_leading_zero (~0U) != 0
+      || __builtin_stdc_first_leading_zero (~0UL) != 0
+      || __builtin_stdc_first_leading_zero (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned char) ~3U) != __CHAR_BIT__ - 1
+      || __builtin_stdc_first_leading_zero ((unsigned short) ~15U) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+      || __builtin_stdc_first_leading_zero (~63U) != __SIZEOF_INT__ * __CHAR_BIT__ - 5
+      || __builtin_stdc_first_leading_zero (~255UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 7
+      || __builtin_stdc_first_leading_zero (~1023ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_first_leading_one ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_first_leading_one (0U) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one (0U), unsigned int)
+      || __builtin_stdc_first_leading_one (0UL) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one (0UL), unsigned int)
+      || __builtin_stdc_first_leading_one (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned char) ~0U) != 1
+      || __builtin_stdc_first_leading_one ((unsigned short) ~0U) != 1
+      || __builtin_stdc_first_leading_one (~0U) != 1
+      || __builtin_stdc_first_leading_one (~0UL) != 1
+      || __builtin_stdc_first_leading_one (~0ULL) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned char) 3) != __CHAR_BIT__ - 1
+      || __builtin_stdc_first_leading_one ((unsigned short) 9) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+      || __builtin_stdc_first_leading_one (34U) != __SIZEOF_INT__ * __CHAR_BIT__ - 5
+      || __builtin_stdc_first_leading_one (130UL) != __SIZEOF_LONG__ * __CHAR_BIT__ - 7
+      || __builtin_stdc_first_leading_one (512ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned char) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_first_trailing_zero ((unsigned short) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_first_trailing_zero (0U) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero (0U), unsigned int)
+      || __builtin_stdc_first_trailing_zero (0UL) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero (0UL), unsigned int)
+      || __builtin_stdc_first_trailing_zero (0ULL) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned char) ~0U) != 0
+      || __builtin_stdc_first_trailing_zero ((unsigned short) ~0U) != 0
+      || __builtin_stdc_first_trailing_zero (~0U) != 0
+      || __builtin_stdc_first_trailing_zero (~0UL) != 0
+      || __builtin_stdc_first_trailing_zero (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned char) 2) != 1
+      || __builtin_stdc_first_trailing_zero ((unsigned short) 15) != 5
+      || __builtin_stdc_first_trailing_zero (63U) != 7
+      || __builtin_stdc_first_trailing_zero (128UL) != 1
+      || __builtin_stdc_first_trailing_zero (511ULL) != 10)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_first_trailing_one ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_first_trailing_one (0U) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one (0U), unsigned int)
+      || __builtin_stdc_first_trailing_one (0UL) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one (0UL), unsigned int)
+      || __builtin_stdc_first_trailing_one (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned char) ~0U) != 1
+      || __builtin_stdc_first_trailing_one ((unsigned short) ~0U) != 1
+      || __builtin_stdc_first_trailing_one (~0U) != 1
+      || __builtin_stdc_first_trailing_one (~0UL) != 1
+      || __builtin_stdc_first_trailing_one (~0ULL) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned char) 4) != 3
+      || __builtin_stdc_first_trailing_one ((unsigned short) 96) != 6
+      || __builtin_stdc_first_trailing_one (127U) != 1
+      || __builtin_stdc_first_trailing_one (511UL) != 1
+      || __builtin_stdc_first_trailing_one (~0ULL << 12) != 13)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned char) 0) != __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_count_zeros ((unsigned short) 0) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_count_zeros (0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros (0U), unsigned int)
+      || __builtin_stdc_count_zeros (0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros (0UL), unsigned int)
+      || __builtin_stdc_count_zeros (0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned char) ~0U) != 0
+      || __builtin_stdc_count_zeros ((unsigned short) ~0U) != 0
+      || __builtin_stdc_count_zeros (~0U) != 0
+      || __builtin_stdc_count_zeros (~0UL) != 0
+      || __builtin_stdc_count_zeros (~0ULL) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned char) 1U) != __CHAR_BIT__ - 1
+      || __builtin_stdc_count_zeros ((unsigned short) 42) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+      || __builtin_stdc_count_zeros (291U) != __SIZEOF_INT__ * __CHAR_BIT__ - 4
+      || __builtin_stdc_count_zeros (~1315UL) != 5
+      || __builtin_stdc_count_zeros (3363ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 6)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_count_ones ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_count_ones (0U) != 0
+      || !expr_has_type (__builtin_stdc_count_ones (0U), unsigned int)
+      || __builtin_stdc_count_ones (0UL) != 0
+      || !expr_has_type (__builtin_stdc_count_ones (0UL), unsigned int)
+      || __builtin_stdc_count_ones (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_count_ones (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned char) ~0U) != __CHAR_BIT__
+      || __builtin_stdc_count_ones ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || __builtin_stdc_count_ones (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || __builtin_stdc_count_ones (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || __builtin_stdc_count_ones (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned char) ~1U) != __CHAR_BIT__ - 1
+      || __builtin_stdc_count_ones ((unsigned short) ~42) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 3
+      || __builtin_stdc_count_ones (~291U) != __SIZEOF_INT__ * __CHAR_BIT__ - 4
+      || __builtin_stdc_count_ones (1315UL) != 5
+      || __builtin_stdc_count_ones (~3363ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 6)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit ((unsigned char) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned char) 0), _Bool)
+      || __builtin_stdc_has_single_bit ((unsigned short) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned short) 0), _Bool)
+      || __builtin_stdc_has_single_bit (0U)
+      || !expr_has_type (__builtin_stdc_has_single_bit (0U), _Bool)
+      || __builtin_stdc_has_single_bit (0UL)
+      || !expr_has_type (__builtin_stdc_has_single_bit (0UL), _Bool)
+      || __builtin_stdc_has_single_bit (0ULL)
+      || !expr_has_type (__builtin_stdc_has_single_bit (0ULL), _Bool))
+    __builtin_abort ();
+  if (!__builtin_stdc_has_single_bit ((unsigned char) 2)
+      || !__builtin_stdc_has_single_bit ((unsigned short) 8)
+      || !__builtin_stdc_has_single_bit (32U)
+      || !__builtin_stdc_has_single_bit (128UL)
+      || !__builtin_stdc_has_single_bit (512ULL))
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit ((unsigned char) 7)
+      || __builtin_stdc_has_single_bit ((unsigned short) 96)
+      || __builtin_stdc_has_single_bit (513U)
+      || __builtin_stdc_has_single_bit (1022UL)
+      || __builtin_stdc_has_single_bit (12ULL))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned char) 0), unsigned int)
+      || __builtin_stdc_bit_width ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned short) 0), unsigned int)
+      || __builtin_stdc_bit_width (0U) != 0
+      || !expr_has_type (__builtin_stdc_bit_width (0U), unsigned int)
+      || __builtin_stdc_bit_width (0UL) != 0
+      || !expr_has_type (__builtin_stdc_bit_width (0UL), unsigned int)
+      || __builtin_stdc_bit_width (0ULL) != 0
+      || !expr_has_type (__builtin_stdc_bit_width (0ULL), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned char) ~0U) != __CHAR_BIT__
+      || __builtin_stdc_bit_width ((unsigned short) ~0U) != __SIZEOF_SHORT__ * __CHAR_BIT__
+      || __builtin_stdc_bit_width (~0U) != __SIZEOF_INT__ * __CHAR_BIT__
+      || __builtin_stdc_bit_width (~0UL) != __SIZEOF_LONG__ * __CHAR_BIT__
+      || __builtin_stdc_bit_width (~0ULL) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned char) ((unsigned char) ~0U >> 1)) != __CHAR_BIT__ - 1
+      || __builtin_stdc_bit_width ((unsigned char) 6) != 3
+      || __builtin_stdc_bit_width ((unsigned short) 12U) != 4
+      || __builtin_stdc_bit_width ((unsigned short) ((unsigned short) ~0U >> 5)) != __SIZEOF_SHORT__ * __CHAR_BIT__ - 5
+      || __builtin_stdc_bit_width (137U) != 8
+      || __builtin_stdc_bit_width (269U) != 9
+      || __builtin_stdc_bit_width (39UL) != 6
+      || __builtin_stdc_bit_width (~0UL >> 2) != __SIZEOF_LONG__ * __CHAR_BIT__ - 2
+      || __builtin_stdc_bit_width (1023ULL) != 10
+      || __builtin_stdc_bit_width (1024ULL) != 11)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned char) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned char) 0), unsigned char)
+      || __builtin_stdc_bit_floor ((unsigned short) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned short) 0), unsigned short)
+      || __builtin_stdc_bit_floor (0U) != 0U
+      || !expr_has_type (__builtin_stdc_bit_floor (0U), unsigned int)
+      || __builtin_stdc_bit_floor (0UL) != 0UL
+      || !expr_has_type (__builtin_stdc_bit_floor (0UL), unsigned long)
+      || __builtin_stdc_bit_floor (0ULL) != 0ULL
+      || !expr_has_type (__builtin_stdc_bit_floor (0ULL), unsigned long long))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned char) ~0U) != (1U << (__CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor ((unsigned short) ~0U) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor (~0U) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor (~0UL) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_floor (~0ULL) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned char) 4) != 4
+      || __builtin_stdc_bit_floor ((unsigned char) 7) != 4
+      || __builtin_stdc_bit_floor ((unsigned short) 8U) != 8
+      || __builtin_stdc_bit_floor ((unsigned short) 31U) != 16
+      || __builtin_stdc_bit_floor (137U) != 128U
+      || __builtin_stdc_bit_floor (269U) != 256U
+      || __builtin_stdc_bit_floor (511UL) != 256UL
+      || __builtin_stdc_bit_floor (512UL) != 512UL
+      || __builtin_stdc_bit_floor (513UL) != 512ULL
+      || __builtin_stdc_bit_floor (1024ULL) != 1024ULL)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned char) 0), unsigned char)
+      || __builtin_stdc_bit_ceil ((unsigned short) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned short) 0), unsigned short)
+      || __builtin_stdc_bit_ceil (0U) != 1U
+      || !expr_has_type (__builtin_stdc_bit_ceil (0U), unsigned int)
+      || __builtin_stdc_bit_ceil (0UL) != 1UL
+      || !expr_has_type (__builtin_stdc_bit_ceil (0UL), unsigned long)
+      || __builtin_stdc_bit_ceil (0ULL) != 1ULL
+      || !expr_has_type (__builtin_stdc_bit_ceil (0ULL), unsigned long long))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) ~0U) != 0
+      || __builtin_stdc_bit_ceil ((unsigned short) ~0U) != 0
+      || __builtin_stdc_bit_ceil (~0U) != 0U
+      || __builtin_stdc_bit_ceil (~0UL) != 0UL
+      || __builtin_stdc_bit_ceil (~0ULL) != 0ULL)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) ((unsigned char) ~0U >> 1)) != (1U << (__CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil ((unsigned char) ((unsigned char) ~0U >> 1)) != (1U << (__CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil ((unsigned short) ((unsigned short) ~0U >> 1)) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil ((unsigned short) ((unsigned short) ~0U >> 1)) != (1U << (__SIZEOF_SHORT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0U >> 1) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1)) != (1U << (__SIZEOF_INT__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0UL >> 1) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0UL >> 1) != (1UL << (__SIZEOF_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1))
+      || __builtin_stdc_bit_ceil (~0ULL >> 1) != (1ULL << (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned char) 1) != 1
+      || __builtin_stdc_bit_ceil ((unsigned char) 2) != 2
+      || __builtin_stdc_bit_ceil ((unsigned short) 3U) != 4
+      || __builtin_stdc_bit_ceil ((unsigned short) 4U) != 4
+      || __builtin_stdc_bit_ceil (5U) != 8U
+      || __builtin_stdc_bit_ceil (269U) != 512U
+      || __builtin_stdc_bit_ceil (511UL) != 512UL
+      || __builtin_stdc_bit_ceil (512UL) != 512UL
+      || __builtin_stdc_bit_ceil (513ULL) != 1024ULL
+      || __builtin_stdc_bit_ceil (1025ULL) != 2048ULL)
+    __builtin_abort ();
+#ifdef __SIZEOF_INT128__
+  if (__builtin_stdc_leading_zeros ((unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_leading_zeros (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_leading_ones (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_trailing_zeros (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_trailing_ones (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned __int128) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_first_leading_zero (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_first_leading_one (~(unsigned __int128) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned __int128) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_first_trailing_zero (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_first_trailing_one (~(unsigned __int128) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_count_zeros (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_count_ones (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit ((unsigned __int128) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned __int128) 0), _Bool)
+      || __builtin_stdc_has_single_bit (~(unsigned __int128) 0))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned __int128) 0), unsigned int)
+      || __builtin_stdc_bit_width (~(unsigned __int128) 0) != __SIZEOF_INT128__ * __CHAR_BIT__)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned __int128) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned __int128) 0), unsigned __int128)
+      || __builtin_stdc_bit_floor (~(unsigned __int128) 0) != ((unsigned __int128) 1) << (__SIZEOF_INT128__ * __CHAR_BIT__ - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned __int128) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned __int128) 0), unsigned __int128)
+      || __builtin_stdc_bit_ceil ((unsigned __int128) 1) != 1
+      || __builtin_stdc_bit_ceil ((~(unsigned __int128) 0) >> 1) != ((unsigned __int128) 1) << (__SIZEOF_INT128__ * __CHAR_BIT__ - 1)
+      || __builtin_stdc_bit_ceil (~(unsigned __int128) 0) != 0)
+    __builtin_abort ();
+#endif
+#if __has_builtin (__builtin_stdc_leading_zeros) != 1
+#error __builtin_stdc_leading_zeros not implemented
+#endif
+#if __has_builtin (__builtin_stdc_leading_ones) != 1
+#error __builtin_stdc_leading_ones not implemented
+#endif
+#if __has_builtin (__builtin_stdc_trailing_zeros) != 1
+#error __builtin_stdc_trailing_zeros not implemented
+#endif
+#if __has_builtin (__builtin_stdc_trailing_ones) != 1
+#error __builtin_stdc_trailing_ones not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_leading_zero) != 1
+#error __builtin_stdc_first_leading_zero not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_leading_one) != 1
+#error __builtin_stdc_first_leading_one not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_trailing_zero) != 1
+#error __builtin_stdc_first_trailing_zero not implemented
+#endif
+#if __has_builtin (__builtin_stdc_first_trailing_one) != 1
+#error __builtin_stdc_first_trailing_one not implemented
+#endif
+#if __has_builtin (__builtin_stdc_count_zeros) != 1
+#error __builtin_stdc_count_zeros not implemented
+#endif
+#if __has_builtin (__builtin_stdc_count_ones) != 1
+#error __builtin_stdc_count_ones not implemented
+#endif
+#if __has_builtin (__builtin_stdc_has_single_bit) != 1
+#error __builtin_stdc_single_bit not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_width) != 1
+#error __builtin_stdc_bit_width not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_floor) != 1
+#error __builtin_stdc_bit_floor not implemented
+#endif
+#if __has_builtin (__builtin_stdc_bit_ceil) != 1
+#error __builtin_stdc_bit_ceil not implemented
+#endif
+  unsigned char a = 0;
+  if (__builtin_stdc_bit_width (a++) != 0 || a != 1)
+    __builtin_abort ();
+  unsigned long long b = 0;
+  if (__builtin_stdc_bit_width (b++) != 0 || b != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (a++) != 1 || a != 2)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (b++) != 1 || b != 2)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (a++) != 2 || a != 3)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (b++) != 2 || b != 3)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros (a++) != __CHAR_BIT__ - 2 || a != 4)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros (b++) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 2 || b != 4)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones (a++) != 0 || a != 5)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones (b++) != 0 || b != 5)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros (a++) != 0 || a != 6)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros (b++) != 0 || b != 6)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones (a++) != 0 || a != 7)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones (b++) != 0 || b != 7)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero (a++) != 1 || a != 8)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero (b++) != 1 || b != 8)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one (a++) != __CHAR_BIT__ - 3 || a != 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one (b++) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 3 || b != 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero (a++) != 2 || a != 10)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero (b++) != 2 || b != 10)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one (a++) != 2 || a != 11)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one (b++) != 2 || b != 11)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros (a++) != __CHAR_BIT__ - 3 || a != 12)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros (b++) != __SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 3 || b != 12)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones (a++) != 2 || a != 13)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones (b++) != 2 || b != 13)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit (a++) || a != 14)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit (b++) || b != 14)
+    __builtin_abort ();
+#if __BITINT_MAXWIDTH__ >= 512
+  if (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 0) != 512
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_leading_zeros ((unsigned _BitInt(373)) 0) != 373
+      || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_leading_zeros (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 275) != 512 - 9
+      || __builtin_stdc_leading_zeros ((unsigned _BitInt(373)) 512) != 373 - 10)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_leading_ones ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_leading_ones ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones (~(unsigned _BitInt(512)) 0) != 512
+      || __builtin_stdc_leading_ones (~(unsigned _BitInt(373)) 0) != 373)
+    __builtin_abort ();
+  if (__builtin_stdc_leading_ones (~(unsigned _BitInt(512)) 275) != 512 - 9
+      || __builtin_stdc_leading_ones (~(unsigned _BitInt(373)) 512) != 373 - 10)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned _BitInt(512)) 0) != 512
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_trailing_zeros ((unsigned _BitInt(373)) 0) != 373
+      || !expr_has_type (__builtin_stdc_trailing_zeros ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_trailing_zeros (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_zeros ((unsigned _BitInt(512)) 256) != 8
+      || __builtin_stdc_trailing_zeros ((unsigned _BitInt(373)) 512) != 9)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_trailing_ones ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_trailing_ones ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones (~(unsigned _BitInt(512)) 0) != 512
+      || __builtin_stdc_trailing_ones (~(unsigned _BitInt(373)) 0) != 373)
+    __builtin_abort ();
+  if (__builtin_stdc_trailing_ones ((unsigned _BitInt(512)) 255) != 8
+      || __builtin_stdc_trailing_ones ((~(unsigned _BitInt(373)) 0) >> 2) != 373 - 2)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero ((unsigned _BitInt(512)) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_first_leading_zero ((unsigned _BitInt(373)) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_leading_zero ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_first_leading_zero (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_zero (~(unsigned _BitInt(512)) 511) != 512 - 8
+      || __builtin_stdc_first_leading_zero (~(unsigned _BitInt(373)) 1023) != 373 - 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_first_leading_one ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_leading_one ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one (~(unsigned _BitInt(512)) 0) != 1
+      || __builtin_stdc_first_leading_one (~(unsigned _BitInt(373)) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_leading_one ((unsigned _BitInt(512)) 275) != 512 - 8
+      || __builtin_stdc_first_leading_one ((unsigned _BitInt(373)) 512) != 373 - 9)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(512)) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_first_trailing_zero ((unsigned _BitInt(373)) 0) != 1
+      || !expr_has_type (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_first_trailing_zero (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_zero ((unsigned _BitInt(512)) 255) != 9
+      || __builtin_stdc_first_trailing_zero ((unsigned _BitInt(373)) 511) != 10)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_first_trailing_one ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_first_trailing_one ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one (~(unsigned _BitInt(512)) 0) != 1
+      || __builtin_stdc_first_trailing_one (~(unsigned _BitInt(373)) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_first_trailing_one (((unsigned _BitInt(512)) 255) << 175) != 176
+      || __builtin_stdc_first_trailing_one ((~(unsigned _BitInt(373)) 0) << 311) != 312)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned _BitInt(512)) 0) != 512
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_count_zeros ((unsigned _BitInt(373)) 0) != 373
+      || !expr_has_type (__builtin_stdc_count_zeros ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_count_zeros (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_count_zeros ((unsigned _BitInt(512)) 1315) != 512 - 5
+      || __builtin_stdc_count_zeros ((unsigned _BitInt(373)) 3363) != 373 - 6)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_count_ones ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_count_ones ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones (~(unsigned _BitInt(512)) 0) != 512
+      || __builtin_stdc_count_ones (~(unsigned _BitInt(373)) 0) != 373)
+    __builtin_abort ();
+  if (__builtin_stdc_count_ones (~(unsigned _BitInt(512)) 1315) != 512 - 5
+      || __builtin_stdc_count_ones (~(unsigned _BitInt(373)) 3363) != 373 - 6)
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit ((unsigned _BitInt(512)) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned _BitInt(512)) 0), _Bool)
+      || __builtin_stdc_has_single_bit ((unsigned _BitInt(373)) 0)
+      || !expr_has_type (__builtin_stdc_has_single_bit ((unsigned _BitInt(373)) 0), _Bool))
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit (~(unsigned _BitInt(512)) 0)
+      || __builtin_stdc_has_single_bit (~(unsigned _BitInt(373)) 0))
+    __builtin_abort ();
+  if (__builtin_stdc_has_single_bit (((unsigned _BitInt(512)) 1022) << 279)
+      || __builtin_stdc_has_single_bit (((unsigned _BitInt(373)) 12) << 305))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned _BitInt(512)) 0), unsigned int)
+      || __builtin_stdc_bit_width ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_width ((unsigned _BitInt(373)) 0), unsigned int))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width (~(unsigned _BitInt(512)) 0) != 512
+      || __builtin_stdc_bit_width (~(unsigned _BitInt(373)) 0) != 373)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_width (((unsigned _BitInt(512)) 1023) << 405) != 405 + 10
+      || __builtin_stdc_bit_width (((unsigned _BitInt(373)) 1024) << 242) != 242 + 11)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned _BitInt(512)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned _BitInt(512)) 0), unsigned _BitInt(512))
+      || __builtin_stdc_bit_floor ((unsigned _BitInt(373)) 0) != 0
+      || !expr_has_type (__builtin_stdc_bit_floor ((unsigned _BitInt(373)) 0), unsigned _BitInt(373)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (~(unsigned _BitInt(512)) 0) != ((unsigned _BitInt(512)) 1) << (512 - 1)
+      || __builtin_stdc_bit_floor (~(unsigned _BitInt(373)) 0) != ((unsigned _BitInt(373)) 1) << (373 - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (((unsigned _BitInt(512)) 511) << 405) != (((unsigned _BitInt(512)) 256) << 405)
+      || __builtin_stdc_bit_floor (((unsigned _BitInt(373)) 512) << 242) != (((unsigned _BitInt(512)) 512) << 242))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned _BitInt(512)) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned _BitInt(512)) 0), unsigned _BitInt(512))
+      || __builtin_stdc_bit_ceil ((unsigned _BitInt(373)) 0) != 1
+      || !expr_has_type (__builtin_stdc_bit_ceil ((unsigned _BitInt(373)) 0), unsigned _BitInt(373)))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (~(unsigned _BitInt(512)) 0) != 0
+      || __builtin_stdc_bit_ceil (~(unsigned _BitInt(373)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(512)) 1) << (512 - 1)) != ((unsigned _BitInt(512)) 1) << (512 - 1)
+      || __builtin_stdc_bit_ceil ((~(unsigned _BitInt(373)) 0) >> 1) != ((unsigned _BitInt(373)) 1) << (373 - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(512)) 512) << 405) != (((unsigned _BitInt(512)) 512) << 405)
+      || __builtin_stdc_bit_ceil (((unsigned _BitInt(373)) 513) << 242) != (((unsigned _BitInt(512)) 1024) << 242))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (~(unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1) << (__BITINT_MAXWIDTH__ - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 511) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 256) << 405)
+      || __builtin_stdc_bit_floor (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (~(unsigned _BitInt(__BITINT_MAXWIDTH__)) 0) != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1) << (__BITINT_MAXWIDTH__ - 1)) != ((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1) << (__BITINT_MAXWIDTH__ - 1))
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 512) << 405)
+      || __builtin_stdc_bit_ceil (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 513) << 405) != (((unsigned _BitInt(__BITINT_MAXWIDTH__)) 1024) << 405))
+    __builtin_abort ();
+#endif
+}
--- gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c.jj	2023-11-20 11:18:55.758125897 +0100
+++ gcc/testsuite/gcc.dg/builtin-stdc-bit-2.c	2023-11-20 15:04:20.126724395 +0100
@@ -0,0 +1,150 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+  typedef int V __attribute__ ((vector_size (4 * sizeof (int))));
+  struct S { int s; };
+  enum E { E0, E1 };
+  __builtin_stdc_leading_zeros (0.0f);	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros (0.0);	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros (0.0L);	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros ((V) {});	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_leading_zeros' operand not an integral type" } */
+  __builtin_stdc_leading_zeros ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_leading_zeros'" } */
+  __builtin_stdc_leading_zeros (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_leading_zeros'" } */
+  __builtin_stdc_leading_zeros ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_leading_zeros ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_leading_zeros (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_leading_ones (0.0f);	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones (0.0);	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones (0.0L);	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones ((V) {});	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_leading_ones' operand not an integral type" } */
+  __builtin_stdc_leading_ones ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_leading_ones'" } */
+  __builtin_stdc_leading_ones (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_leading_ones'" } */
+  __builtin_stdc_leading_ones ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_leading_ones ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_leading_ones (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_trailing_zeros (0.0f);	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros (0.0);	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros (0.0L);	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros ((V) {});	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_trailing_zeros' operand not an integral type" } */
+  __builtin_stdc_trailing_zeros ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_zeros'" } */
+  __builtin_stdc_trailing_zeros (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_zeros'" } */
+  __builtin_stdc_trailing_zeros ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+  __builtin_stdc_trailing_zeros ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+  __builtin_stdc_trailing_zeros (0);		/* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+  __builtin_stdc_trailing_ones (0.0f);	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones (0.0);	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones (0.0L);	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones ((V) {});	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_trailing_ones' operand not an integral type" } */
+  __builtin_stdc_trailing_ones ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_ones'" } */
+  __builtin_stdc_trailing_ones (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_trailing_ones'" } */
+  __builtin_stdc_trailing_ones ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+  __builtin_stdc_trailing_ones ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+  __builtin_stdc_trailing_ones (0);		/* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+  __builtin_stdc_first_leading_zero (0.0f);	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero (0.0);	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero (0.0L);	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero ((V) {});	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_first_leading_zero' operand not an integral type" } */
+  __builtin_stdc_first_leading_zero ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_zero'" } */
+  __builtin_stdc_first_leading_zero (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_zero'" } */
+  __builtin_stdc_first_leading_zero ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_first_leading_zero ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_first_leading_zero (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_first_leading_one (0.0f);	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one (0.0);	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one (0.0L);	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one ((V) {});	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_first_leading_one' operand not an integral type" } */
+  __builtin_stdc_first_leading_one ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_one'" } */
+  __builtin_stdc_first_leading_one (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_first_leading_one'" } */
+  __builtin_stdc_first_leading_one ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_first_leading_one ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_first_leading_one (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_first_trailing_zero (0.0f);	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero (0.0);	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero (0.0L);	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero ((V) {});	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_first_trailing_zero' operand not an integral type" } */
+  __builtin_stdc_first_trailing_zero ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_zero'" } */
+  __builtin_stdc_first_trailing_zero (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_zero'" } */
+  __builtin_stdc_first_trailing_zero ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+  __builtin_stdc_first_trailing_zero ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+  __builtin_stdc_first_trailing_zero (0);		/* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+  __builtin_stdc_first_trailing_one (0.0f);	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one (0.0);	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one (0.0L);	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one ((V) {});	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_first_trailing_one' operand not an integral type" } */
+  __builtin_stdc_first_trailing_one ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_one'" } */
+  __builtin_stdc_first_trailing_one (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_first_trailing_one'" } */
+  __builtin_stdc_first_trailing_one ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has boolean type" } */
+  __builtin_stdc_first_trailing_one ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_ctzg' has enumerated type" } */
+  __builtin_stdc_first_trailing_one (0);		/* { dg-error "argument 1 in call to function '__builtin_ctzg' has signed type" } */
+  __builtin_stdc_count_zeros (0.0f);	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros (0.0);	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros (0.0L);	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros ((V) {});	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_count_zeros' operand not an integral type" } */
+  __builtin_stdc_count_zeros ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_count_zeros'" } */
+  __builtin_stdc_count_zeros (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_count_zeros'" } */
+  __builtin_stdc_count_zeros ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has boolean type" } */
+  __builtin_stdc_count_zeros ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has enumerated type" } */
+  __builtin_stdc_count_zeros (0);		/* { dg-error "argument 1 in call to function '__builtin_popcountg' has signed type" } */
+  __builtin_stdc_count_ones (0.0f);	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones (0.0);	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones (0.0L);	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones ((V) {});	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_count_ones' operand not an integral type" } */
+  __builtin_stdc_count_ones ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_count_ones'" } */
+  __builtin_stdc_count_ones (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_count_ones'" } */
+  __builtin_stdc_count_ones ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has boolean type" } */
+  __builtin_stdc_count_ones ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has enumerated type" } */
+  __builtin_stdc_count_ones (0);		/* { dg-error "argument 1 in call to function '__builtin_popcountg' has signed type" } */
+  __builtin_stdc_has_single_bit (0.0f);	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit (0.0);	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit (0.0L);	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit ((V) {});	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_has_single_bit' operand not an integral type" } */
+  __builtin_stdc_has_single_bit ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_has_single_bit'" } */
+  __builtin_stdc_has_single_bit (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_has_single_bit'" } */
+  __builtin_stdc_has_single_bit ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has boolean type" } */
+  __builtin_stdc_has_single_bit ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_popcountg' has enumerated type" } */
+  __builtin_stdc_has_single_bit (0);		/* { dg-error "argument 1 in call to function '__builtin_popcountg' has signed type" } */
+  __builtin_stdc_bit_width (0.0f);	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width (0.0);	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width (0.0L);	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width ((V) {});	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_bit_width' operand not an integral type" } */
+  __builtin_stdc_bit_width ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_width'" } */
+  __builtin_stdc_bit_width (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_width'" } */
+  __builtin_stdc_bit_width ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_bit_width ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_bit_width (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_bit_floor (0.0f);	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor (0.0);	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor (0.0L);	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor ((V) {});	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_bit_floor' operand not an integral type" } */
+  __builtin_stdc_bit_floor ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_floor'" } */
+  __builtin_stdc_bit_floor (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_floor'" } */
+  __builtin_stdc_bit_floor ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_bit_floor ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_bit_floor (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+  __builtin_stdc_bit_ceil (0.0f);	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil (0.0);	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil (0.0L);	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil ((V) {});	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil ((struct S) { 0 });	/* { dg-error "'__builtin_stdc_bit_ceil' operand not an integral type" } */
+  __builtin_stdc_bit_ceil ();		/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_ceil'" } */
+  __builtin_stdc_bit_ceil (0U, 0U);	/* { dg-error "wrong number of arguments to '__builtin_stdc_bit_ceil'" } */
+  __builtin_stdc_bit_ceil ((_Bool) 0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has boolean type" } */
+  __builtin_stdc_bit_ceil ((enum E) E0);	/* { dg-error "argument 1 in call to function '__builtin_clzg' has enumerated type" } */
+  __builtin_stdc_bit_ceil (0);		/* { dg-error "argument 1 in call to function '__builtin_clzg' has signed type" } */
+}


	Jakub


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

* Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
  2023-11-20 15:29     ` Jakub Jelinek
@ 2023-11-21  8:24       ` Jakub Jelinek
  2023-11-23  0:09       ` Joseph Myers
  1 sibling, 0 replies; 9+ messages in thread
From: Jakub Jelinek @ 2023-11-21  8:24 UTC (permalink / raw)
  To: Joseph Myers, gcc-patches, Florian Weimer

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  <jakub@redhat.com>
> 
> 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


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

* Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
  2023-11-20 15:12   ` Jakub Jelinek
@ 2023-11-21 23:35     ` Joseph Myers
  0 siblings, 0 replies; 9+ messages in thread
From: Joseph Myers @ 2023-11-21 23:35 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, Florian Weimer

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
joseph@codesourcery.com

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

* Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
  2023-11-20 15:29     ` Jakub Jelinek
  2023-11-21  8:24       ` Jakub Jelinek
@ 2023-11-23  0:09       ` Joseph Myers
  2023-11-23 10:05         ` Jakub Jelinek
  1 sibling, 1 reply; 9+ messages in thread
From: Joseph Myers @ 2023-11-23  0:09 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, Florian Weimer

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  <jakub@redhat.com>
> 
> 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
joseph@codesourcery.com

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

* Re: [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins
  2023-11-23  0:09       ` Joseph Myers
@ 2023-11-23 10:05         ` Jakub Jelinek
  0 siblings, 0 replies; 9+ messages in thread
From: Jakub Jelinek @ 2023-11-23 10:05 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc-patches, Florian Weimer

On Thu, Nov 23, 2023 at 12:09:05AM +0000, 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 ();
+  unsigned _BitInt(1) c = 0;
+  if (__builtin_stdc_bit_floor (c++) != 0 || c != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_floor (c++) != 1 || c != 0)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (c++) != 1 || c != 1)
+    __builtin_abort ();
+  if (__builtin_stdc_bit_ceil (c++) != 1 || c != 0)
+    __builtin_abort ();
+#endif
 #if __BITINT_MAXWIDTH__ >= 512
   if (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 0) != 512
       || !expr_has_type (__builtin_stdc_leading_zeros ((unsigned _BitInt(512)) 0), unsigned int)


	Jakub


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

end of thread, other threads:[~2023-11-23 10:06 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-18 19:42 [PATCH] c: Add __builtin_stdc_bit_{width,floor,ceil} builtins Jakub Jelinek
2023-11-20 14:55 ` Joseph Myers
2023-11-20 15:03   ` Jakub Jelinek
2023-11-20 15:29     ` Jakub Jelinek
2023-11-21  8:24       ` Jakub Jelinek
2023-11-23  0:09       ` Joseph Myers
2023-11-23 10:05         ` Jakub Jelinek
2023-11-20 15:12   ` Jakub Jelinek
2023-11-21 23:35     ` Joseph Myers

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).