[clang] e270662 - [clang]Implement the c23 stdc bit builtins (#185978)

via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 17 05:05:25 PDT 2026


Author: NagaChaitanya Vellanki
Date: 2026-04-17T08:05:19-04:00
New Revision: e270662c0b2c3a24211f200fe758a84b45b25fcd

URL: https://github.com/llvm/llvm-project/commit/e270662c0b2c3a24211f200fe758a84b45b25fcd
DIFF: https://github.com/llvm/llvm-project/commit/e270662c0b2c3a24211f200fe758a84b45b25fcd.diff

LOG: [clang]Implement the c23 stdc bit builtins (#185978)

This patch implements the following C23 bit builtins

  __builtin_stdc_leading_zeros/ones
  __builtin_stdc_trailing_zeros/ones
  __builtin_stdc_first_leading/trailing_zero/one
  __builtin_stdc_count_zeros/ones
  __builtin_stdc_has_single_bit
  __builtin_stdc_bit_width
  __builtin_stdc_bit_floor
  __builtin_stdc_bit_ceil

Additional Notes:
* Supports all unsigned integer types including _BitInt and __int128
 * lowers to llvm.ctlz / llvm.cttz / llvm.ctpop intrinsics
* constexpr support 

Addresses: #79630

Added: 
    clang/test/CodeGen/Inputs/stdbit.h
    clang/test/CodeGen/builtin-stdc-bit-functions.c
    clang/test/Sema/Inputs/stdbit.h
    clang/test/Sema/builtin-stdc-bit-functions.c
    clang/test/SemaCXX/constexpr-builtin-stdc-bit-functions.cpp

Modified: 
    clang/docs/LanguageExtensions.rst
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/BuiltinHeaders.def
    clang/include/clang/Basic/Builtins.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/AST/ByteCode/InterpBuiltin.cpp
    clang/lib/AST/ExprConstant.cpp
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/CodeGen/CodeGenFunction.h
    clang/lib/Sema/SemaChecking.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 8f6826c3891ac..e2e98604008ea 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3997,6 +3997,63 @@ be used within constant expressions.
   unsigned _BitInt(20) value = 0xABCDE;
   unsigned _BitInt(20) rotated = __builtin_stdc_rotate_left(value, 5);
 
+``__builtin_stdc_*`` bit utilities
+----------------------------------
+
+**Syntax**:
+
+.. code-block:: c
+
+  unsigned int __builtin_stdc_leading_zeros(T value);
+  unsigned int __builtin_stdc_leading_ones(T value);
+  unsigned int __builtin_stdc_trailing_zeros(T value);
+  unsigned int __builtin_stdc_trailing_ones(T value);
+  unsigned int __builtin_stdc_first_leading_zero(T value);
+  unsigned int __builtin_stdc_first_leading_one(T value);
+  unsigned int __builtin_stdc_first_trailing_zero(T value);
+  unsigned int __builtin_stdc_first_trailing_one(T value);
+  unsigned int __builtin_stdc_count_zeros(T value);
+  unsigned int __builtin_stdc_count_ones(T value);
+  bool         __builtin_stdc_has_single_bit(T value);
+  unsigned int __builtin_stdc_bit_width(T value);
+  T            __builtin_stdc_bit_floor(T value);
+  T            __builtin_stdc_bit_ceil(T value);
+
+where ``T`` is any unsigned integer type except ``bool`` and enumeration types,
+including ``_BitInt`` types.
+
+**Description**:
+
+These builtins implement the C23 ``<stdbit.h>`` operations. Following the C23
+standard, ``unsigned int`` is used as the ``generic_return_type`` for count and
+position queries (``leading_zeros``, ``leading_ones``, ``trailing_zeros``,
+``trailing_ones``, ``first_leading_zero``, ``first_leading_one``,
+``first_trailing_zero``, ``first_trailing_one``, ``count_zeros``,
+``count_ones``, ``bit_width``); ``has_single_bit`` returns ``bool``; and
+``bit_floor``/``bit_ceil`` return the same type as the operand. Zero and
+all-ones cases follow the C23 definitions. All are usable in constant
+expressions.
+
+``bool`` and enumeration types are rejected as arguments because C23 does not
+permit them for these functions.
+
+As a Clang extension, ``_BitInt`` types of arbitrary widths are supported. C23
+only requires support for bit-precise integers whose width matches a standard
+or extended integer type.
+
+**Examples**:
+
+.. code-block:: c
+
+  unsigned _BitInt(9) x = 0x11;
+  unsigned int lz  = __builtin_stdc_leading_zeros(x);
+  unsigned int tz  = __builtin_stdc_trailing_zeros(x);
+  unsigned int fto = __builtin_stdc_first_trailing_one(x);
+  unsigned int cz  = __builtin_stdc_count_zeros(x);
+  bool has_one    = __builtin_stdc_has_single_bit(x);
+  unsigned _BitInt(9) ceilv  = __builtin_stdc_bit_ceil((unsigned _BitInt(9))5);
+  unsigned _BitInt(9) floorv = __builtin_stdc_bit_floor((unsigned _BitInt(9))5);
+
 ``__builtin_unreachable``
 -------------------------
 

diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6e1ebe11dee3d..d1eefd57a2e1e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -179,6 +179,15 @@ Non-comprehensive list of changes in this release
   counts are normalized modulo the bit-width and support negative values.
   Usable in constant expressions. Implicit conversion is supported for
   class/struct types with conversion operators.
+- Implemented the following C23 ``<stdbit.h>`` builtins with ``_BitInt``
+  support and constexpr evaluation:
+  ``__builtin_stdc_leading_zeros``, ``__builtin_stdc_leading_ones``,
+  ``__builtin_stdc_trailing_zeros``, ``__builtin_stdc_trailing_ones``,
+  ``__builtin_stdc_first_leading_zero``, ``__builtin_stdc_first_leading_one``,
+  ``__builtin_stdc_first_trailing_zero``, ``__builtin_stdc_first_trailing_one``,
+  ``__builtin_stdc_count_zeros``, ``__builtin_stdc_count_ones``,
+  ``__builtin_stdc_has_single_bit``, ``__builtin_stdc_bit_width``,
+  ``__builtin_stdc_bit_floor``, and ``__builtin_stdc_bit_ceil``.
 
 - A new generic bit-reverse builtin function ``__builtin_bitreverseg`` that
   extends bit-reversal support to all standard integers type, including

diff  --git a/clang/include/clang/Basic/BuiltinHeaders.def b/clang/include/clang/Basic/BuiltinHeaders.def
index bca40c0e4deea..23889a22769ed 100644
--- a/clang/include/clang/Basic/BuiltinHeaders.def
+++ b/clang/include/clang/Basic/BuiltinHeaders.def
@@ -32,6 +32,7 @@ HEADER(OBJC_RUNTIME_H, "objc/runtime.h")
 HEADER(PTHREAD_H, "pthread.h")
 HEADER(SETJMPEX_H, "setjmpex.h")
 HEADER(SETJMP_H, "setjmp.h")
+HEADER(STDBIT_H, "stdbit.h")
 HEADER(STDARG_H, "stdarg.h")
 HEADER(STDIO_H, "stdio.h")
 HEADER(STDLIB_H, "stdlib.h")

diff  --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index b8bbc544595e2..5b6e45de14994 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -797,6 +797,175 @@ def StdcRotateRight : Builtin {
   let Prototype = "void(...)";
 }
 
+def StdcLeadingZeros: Builtin {
+  let Spellings = ["__builtin_stdc_leading_zeros"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcLeadingOnes: Builtin {
+  let Spellings = ["__builtin_stdc_leading_ones"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcTrailingZeros: Builtin {
+  let Spellings = ["__builtin_stdc_trailing_zeros"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcTrailingOnes: Builtin {
+  let Spellings = ["__builtin_stdc_trailing_ones"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcFirstLeadingZero: Builtin {
+  let Spellings = ["__builtin_stdc_first_leading_zero"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcFirstLeadingOne: Builtin {
+  let Spellings = ["__builtin_stdc_first_leading_one"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcFirstTrailingZero: Builtin {
+  let Spellings = ["__builtin_stdc_first_trailing_zero"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcFirstTrailingOne: Builtin {
+  let Spellings = ["__builtin_stdc_first_trailing_one"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcCountZeros: Builtin {
+  let Spellings = ["__builtin_stdc_count_zeros"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcCountOnes: Builtin {
+  let Spellings = ["__builtin_stdc_count_ones"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcHasSingleBit: Builtin {
+  let Spellings = ["__builtin_stdc_has_single_bit"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "bool(...)";
+}
+
+def StdcBitWidth: Builtin {
+  let Spellings = ["__builtin_stdc_bit_width"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcBitFloor: Builtin {
+  let Spellings = ["__builtin_stdc_bit_floor"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcBitCeil: Builtin {
+  let Spellings = ["__builtin_stdc_bit_ceil"];
+  let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcLeadingZerosLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_leading_zeros"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcLeadingOnesLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_leading_ones"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcTrailingZerosLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_trailing_zeros"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcTrailingOnesLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_trailing_ones"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcFirstLeadingZeroLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_first_leading_zero"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcFirstLeadingOneLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_first_leading_one"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcFirstTrailingZeroLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_first_trailing_zero"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcFirstTrailingOneLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_first_trailing_one"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcCountZerosLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_count_zeros"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcCountOnesLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_count_ones"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcHasSingleBitLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_has_single_bit"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "bool(...)";
+}
+
+def StdcBitWidthLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_bit_width"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcBitFloorLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_bit_floor"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+def StdcBitCeilLib: LibBuiltin<"stdbit.h", "C23_LANG"> {
+  let Spellings = ["stdc_bit_ceil"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
+
 // Random GCC builtins
 // FIXME: The builtins marked FunctionWithBuiltinPrefix below should be
 //        merged with the library definitions. They are currently not because

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 95b702b927852..96c87b2fecad8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13308,6 +13308,15 @@ def err_builtin_requires_double_type: Error<
 def err_bswapg_invalid_bit_width : Error<
   "_BitInt type %0 (%1 bits) must be a multiple of 16 bits for byte swapping">;
 
+def err_builtin_stdc_invalid_arg_type: Error<
+  "%ordinal0 argument must be a scalar unsigned integer type (was %1)">;
+
+def err_builtin_stdc_invalid_arg_type_bool_or_enum: Error<
+  "%ordinal0 argument must not be a boolean or enumeration type (was %1)">;
+def err_builtin_stdc_result_overflow: Error<
+  "argument type %0 has bit width that exceeds the range of the return type "
+  "'unsigned int' on this target">;
+
 def err_builtin_trivially_relocate_invalid_arg_type: Error <
   "first%select{||| and second}0 argument%select{|||s}0 to "
   "'__builtin_trivially_relocate' must be"

diff  --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 11baf308d6427..e8336b91b515d 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -4413,6 +4413,142 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
         });
   }
 
+  case Builtin::BIstdc_leading_zeros:
+  case Builtin::BI__builtin_stdc_leading_zeros: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.countl_zero());
+        });
+  }
+
+  case Builtin::BIstdc_leading_ones:
+  case Builtin::BI__builtin_stdc_leading_ones: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.countl_one());
+        });
+  }
+
+  case Builtin::BIstdc_trailing_zeros:
+  case Builtin::BI__builtin_stdc_trailing_zeros: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.countr_zero());
+        });
+  }
+
+  case Builtin::BIstdc_trailing_ones:
+  case Builtin::BI__builtin_stdc_trailing_ones: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.countr_one());
+        });
+  }
+
+  case Builtin::BIstdc_first_leading_zero:
+  case Builtin::BI__builtin_stdc_first_leading_zero: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1);
+        });
+  }
+
+  case Builtin::BIstdc_first_leading_one:
+  case Builtin::BI__builtin_stdc_first_leading_one: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.isZero() ? 0 : Val.countl_zero() + 1);
+        });
+  }
+
+  case Builtin::BIstdc_first_trailing_zero:
+  case Builtin::BI__builtin_stdc_first_trailing_zero: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1);
+        });
+  }
+
+  case Builtin::BIstdc_first_trailing_one:
+  case Builtin::BI__builtin_stdc_first_trailing_one: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.isZero() ? 0 : Val.countr_zero() + 1);
+        });
+  }
+
+  case Builtin::BIstdc_count_zeros:
+  case Builtin::BI__builtin_stdc_count_zeros: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          unsigned BitWidth = Val.getBitWidth();
+          return APInt(ResWidth, BitWidth - Val.popcount());
+        });
+  }
+
+  case Builtin::BIstdc_count_ones:
+  case Builtin::BI__builtin_stdc_count_ones: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.popcount());
+        });
+  }
+
+  case Builtin::BIstdc_has_single_bit:
+  case Builtin::BI__builtin_stdc_has_single_bit: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          return APInt(ResWidth, Val.popcount() == 1 ? 1 : 0);
+        });
+  }
+
+  case Builtin::BIstdc_bit_width:
+  case Builtin::BI__builtin_stdc_bit_width: {
+    unsigned ResWidth = S.getASTContext().getIntWidth(Call->getType());
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [ResWidth](const APSInt &Val) {
+          unsigned BitWidth = Val.getBitWidth();
+          return APInt(ResWidth, BitWidth - Val.countl_zero());
+        });
+  }
+
+  case Builtin::BIstdc_bit_floor:
+  case Builtin::BI__builtin_stdc_bit_floor:
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [](const APSInt &Val) {
+          unsigned BitWidth = Val.getBitWidth();
+          if (Val.isZero())
+            return APInt::getZero(BitWidth);
+          return APInt::getOneBitSet(BitWidth,
+                                     BitWidth - Val.countl_zero() - 1);
+        });
+
+  case Builtin::BIstdc_bit_ceil:
+  case Builtin::BI__builtin_stdc_bit_ceil:
+    return interp__builtin_elementwise_int_unaryop(
+        S, OpPC, Call, [](const APSInt &Val) {
+          unsigned BitWidth = Val.getBitWidth();
+          if (Val.ule(1))
+            return APInt(BitWidth, 1);
+          APInt V = Val;
+          APInt ValMinusOne = V - 1;
+          unsigned LeadingZeros = ValMinusOne.countl_zero();
+          if (LeadingZeros == 0)
+            return APInt(BitWidth, 0); // overflows; wrap to 0
+          return APInt::getOneBitSet(BitWidth, BitWidth - LeadingZeros);
+        });
+
   case Builtin::BI__builtin_ffs:
   case Builtin::BI__builtin_ffsl:
   case Builtin::BI__builtin_ffsll:

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6418497c0e1e7..f2f9aeaec2588 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -16829,6 +16829,99 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     }
   }
 
+  case Builtin::BIstdc_leading_zeros:
+  case Builtin::BIstdc_leading_ones:
+  case Builtin::BIstdc_trailing_zeros:
+  case Builtin::BIstdc_trailing_ones:
+  case Builtin::BIstdc_first_leading_zero:
+  case Builtin::BIstdc_first_leading_one:
+  case Builtin::BIstdc_first_trailing_zero:
+  case Builtin::BIstdc_first_trailing_one:
+  case Builtin::BIstdc_count_zeros:
+  case Builtin::BIstdc_count_ones:
+  case Builtin::BIstdc_has_single_bit:
+  case Builtin::BIstdc_bit_width:
+  case Builtin::BIstdc_bit_floor:
+  case Builtin::BIstdc_bit_ceil:
+  case Builtin::BI__builtin_stdc_leading_zeros:
+  case Builtin::BI__builtin_stdc_leading_ones:
+  case Builtin::BI__builtin_stdc_trailing_zeros:
+  case Builtin::BI__builtin_stdc_trailing_ones:
+  case Builtin::BI__builtin_stdc_first_leading_zero:
+  case Builtin::BI__builtin_stdc_first_leading_one:
+  case Builtin::BI__builtin_stdc_first_trailing_zero:
+  case Builtin::BI__builtin_stdc_first_trailing_one:
+  case Builtin::BI__builtin_stdc_count_zeros:
+  case Builtin::BI__builtin_stdc_count_ones:
+  case Builtin::BI__builtin_stdc_has_single_bit:
+  case Builtin::BI__builtin_stdc_bit_width:
+  case Builtin::BI__builtin_stdc_bit_floor:
+  case Builtin::BI__builtin_stdc_bit_ceil: {
+    APSInt Val;
+    if (!EvaluateInteger(E->getArg(0), Val, Info))
+      return false;
+
+    unsigned BitWidth = Val.getBitWidth();
+    const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->getType());
+
+    switch (BuiltinOp) {
+    case Builtin::BI__builtin_stdc_leading_zeros:
+      return Success(APInt(ResBitWidth, Val.countl_zero()), E);
+    case Builtin::BI__builtin_stdc_leading_ones:
+      return Success(APInt(ResBitWidth, Val.countl_one()), E);
+    case Builtin::BI__builtin_stdc_trailing_zeros:
+      return Success(APInt(ResBitWidth, Val.countr_zero()), E);
+    case Builtin::BI__builtin_stdc_trailing_ones:
+      return Success(APInt(ResBitWidth, Val.countr_one()), E);
+    case Builtin::BI__builtin_stdc_first_leading_zero:
+      return Success(
+          APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
+    case Builtin::BI__builtin_stdc_first_leading_one:
+      return Success(
+          APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
+    case Builtin::BI__builtin_stdc_first_trailing_zero:
+      return Success(
+          APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
+    case Builtin::BI__builtin_stdc_first_trailing_one:
+      return Success(
+          APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
+    case Builtin::BI__builtin_stdc_count_zeros: {
+      APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
+      return Success(APSInt(Cnt, /*IsUnsigned*/ true), E);
+    }
+    case Builtin::BI__builtin_stdc_count_ones: {
+      APInt Cnt(ResBitWidth, Val.popcount());
+      return Success(APSInt(Cnt, /*IsUnsigned*/ true), E);
+    }
+    case Builtin::BI__builtin_stdc_has_single_bit: {
+      APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
+      return Success(APSInt(Res, /*IsUnsigned*/ true), E);
+    }
+    case Builtin::BI__builtin_stdc_bit_width:
+      return Success(APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
+    case Builtin::BI__builtin_stdc_bit_floor: {
+      if (Val.isZero())
+        return Success(APInt(BitWidth, 0), E);
+      unsigned Exp = BitWidth - Val.countl_zero() - 1;
+      return Success(
+          APSInt(APInt::getOneBitSet(BitWidth, Exp), /*IsUnsigned*/ true), E);
+    }
+    case Builtin::BI__builtin_stdc_bit_ceil: {
+      if (Val.ule(1))
+        return Success(APSInt(APInt(BitWidth, 1), /*IsUnsigned*/ true), E);
+      APInt ValMinusOne = Val - 1;
+      unsigned LZ = ValMinusOne.countl_zero();
+      if (LZ == 0)
+        return Success(APSInt(APInt(BitWidth, 0), /*IsUnsigned*/ true),
+                       E); // overflows; wrap to 0
+      APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
+      return Success(APSInt(Result, /*IsUnsigned*/ true), E);
+    }
+    default:
+      llvm_unreachable("Unknown stdc builtin");
+    }
+  }
+
   case Builtin::BI__builtin_elementwise_add_sat: {
     APSInt LHS, RHS;
     if (!EvaluateInteger(E->getArg(0), LHS, Info) ||

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 4d74d681cd320..453db290243d2 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2642,6 +2642,63 @@ static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF,
   return RValue::get(CGF->Builder.CreateCall(UBF, Args));
 }
 
+// stdc_{leading,trailing}_{zeros,ones} and stdc_count_ones: counts bits using
+// ctlz, cttz, or ctpop (IsPop). InvertArg flips the input to count the
+// opposite bit value.
+RValue CodeGenFunction::emitStdcCountIntrinsic(const CallExpr *E,
+                                               Intrinsic::ID IntID,
+                                               bool InvertArg, bool IsPop) {
+  Value *ArgValue = EmitScalarExpr(E->getArg(0));
+  llvm::Type *ArgType = ArgValue->getType();
+  llvm::Type *ResultType = ConvertType(E->getType());
+  Value *ActualArg = InvertArg ? Builder.CreateNot(ArgValue) : ArgValue;
+  Function *F = CGM.getIntrinsic(IntID, ArgType);
+  Value *Result = IsPop
+                      ? Builder.CreateCall(F, ActualArg)
+                      : Builder.CreateCall(F, {ActualArg, Builder.getFalse()});
+  if (Result->getType() != ResultType)
+    Result = Builder.CreateIntCast(Result, ResultType, false);
+  return RValue::get(Result);
+}
+
+// stdc_count_zeros (BitWidth - ctpop) and stdc_bit_width (BitWidth - ctlz).
+// IsPop selects ctpop; otherwise ctlz is used.
+RValue CodeGenFunction::emitStdcBitWidthMinus(const CallExpr *E,
+                                              Intrinsic::ID IntID, bool IsPop) {
+  Value *ArgValue = EmitScalarExpr(E->getArg(0));
+  llvm::Type *ArgType = ArgValue->getType();
+  llvm::Type *ResultType = ConvertType(E->getType());
+  unsigned BitWidth = ArgType->getIntegerBitWidth();
+  Function *F = CGM.getIntrinsic(IntID, ArgType);
+  Value *Cnt = IsPop ? Builder.CreateCall(F, ArgValue)
+                     : Builder.CreateCall(F, {ArgValue, Builder.getFalse()});
+  Value *Result = Builder.CreateSub(ConstantInt::get(ArgType, BitWidth), Cnt);
+  if (Result->getType() != ResultType)
+    Result = Builder.CreateIntCast(Result, ResultType, false);
+  return RValue::get(Result);
+}
+
+// stdc_first_{leading,trailing}_{zero,one}: returns the 1-based position of
+// the first matching bit, or 0 if no such bit exists. InvertArg flips the
+// input to search for zeros instead of ones.
+RValue CodeGenFunction::emitStdcFirstBit(const CallExpr *E, Intrinsic::ID IntID,
+                                         bool InvertArg) {
+  Value *ArgValue = EmitScalarExpr(E->getArg(0));
+  llvm::Type *ArgType = ArgValue->getType();
+  llvm::Type *ResultType = ConvertType(E->getType());
+  Value *Zero = ConstantInt::get(ArgType, 0);
+  Value *One = ConstantInt::get(ArgType, 1);
+  Value *ActualArg = InvertArg ? Builder.CreateNot(ArgValue) : ArgValue;
+  Function *F = CGM.getIntrinsic(IntID, ArgType);
+  Value *Cnt = Builder.CreateCall(F, {ActualArg, Builder.getFalse()});
+  Value *Tmp = Builder.CreateAdd(Cnt, One);
+  Value *IsZero = Builder.CreateICmpEQ(ActualArg, Zero);
+  Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp);
+  if (Result->getType() != ResultType)
+    Result = Builder.CreateIntCast(Result, ResultType, false);
+  return RValue::get(Result);
+}
+
 RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
                                         const CallExpr *E,
                                         ReturnValueSlot ReturnValue) {
@@ -3733,6 +3790,100 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
   case Builtin::BI_rotr64:
     return emitRotate(E, true);
 
+  case Builtin::BIstdc_leading_zeros:
+  case Builtin::BI__builtin_stdc_leading_zeros:
+    return emitStdcCountIntrinsic(E, Intrinsic::ctlz, /*InvertArg=*/false);
+  case Builtin::BIstdc_leading_ones:
+  case Builtin::BI__builtin_stdc_leading_ones:
+    return emitStdcCountIntrinsic(E, Intrinsic::ctlz, /*InvertArg=*/true);
+  case Builtin::BIstdc_trailing_zeros:
+  case Builtin::BI__builtin_stdc_trailing_zeros:
+    return emitStdcCountIntrinsic(E, Intrinsic::cttz, /*InvertArg=*/false);
+  case Builtin::BIstdc_trailing_ones:
+  case Builtin::BI__builtin_stdc_trailing_ones:
+    return emitStdcCountIntrinsic(E, Intrinsic::cttz, /*InvertArg=*/true);
+  case Builtin::BIstdc_first_leading_zero:
+  case Builtin::BI__builtin_stdc_first_leading_zero:
+    return emitStdcFirstBit(E, Intrinsic::ctlz, /*InvertArg=*/true);
+  case Builtin::BIstdc_first_leading_one:
+  case Builtin::BI__builtin_stdc_first_leading_one:
+    return emitStdcFirstBit(E, Intrinsic::ctlz, /*InvertArg=*/false);
+  case Builtin::BIstdc_first_trailing_zero:
+  case Builtin::BI__builtin_stdc_first_trailing_zero:
+    return emitStdcFirstBit(E, Intrinsic::cttz, /*InvertArg=*/true);
+  case Builtin::BIstdc_first_trailing_one:
+  case Builtin::BI__builtin_stdc_first_trailing_one:
+    return emitStdcFirstBit(E, Intrinsic::cttz, /*InvertArg=*/false);
+  case Builtin::BIstdc_count_zeros:
+  case Builtin::BI__builtin_stdc_count_zeros:
+    return emitStdcBitWidthMinus(E, Intrinsic::ctpop, /*IsPop=*/true);
+  case Builtin::BIstdc_count_ones:
+  case Builtin::BI__builtin_stdc_count_ones:
+    return emitStdcCountIntrinsic(E, Intrinsic::ctpop, /*InvertArg=*/false,
+                                  /*IsPop=*/true);
+  case Builtin::BIstdc_has_single_bit:
+  case Builtin::BI__builtin_stdc_has_single_bit: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    Value *One = ConstantInt::get(ArgType, 1);
+    Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
+    Value *PopCnt = Builder.CreateCall(F, ArgValue);
+    return RValue::get(Builder.CreateICmpEQ(PopCnt, One));
+  }
+  case Builtin::BIstdc_bit_width:
+  case Builtin::BI__builtin_stdc_bit_width:
+    return emitStdcBitWidthMinus(E, Intrinsic::ctlz, /*IsPop=*/false);
+  case Builtin::BIstdc_bit_floor:
+  case Builtin::BI__builtin_stdc_bit_floor: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    unsigned BitWidth = ArgType->getIntegerBitWidth();
+    Value *Zero = ConstantInt::get(ArgType, 0);
+    Value *One = ConstantInt::get(ArgType, 1);
+    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+    Value *LZ = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
+    Value *ShiftAmt =
+        Builder.CreateSub(ConstantInt::get(ArgType, BitWidth - 1), LZ);
+    Value *Shifted = Builder.CreateShl(One, ShiftAmt);
+    Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero);
+    Value *Result = Builder.CreateSelect(IsZero, Zero, Shifted);
+    return RValue::get(Result);
+  }
+  case Builtin::BIstdc_bit_ceil:
+  case Builtin::BI__builtin_stdc_bit_ceil: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    unsigned BitWidth = ArgType->getIntegerBitWidth();
+    Value *One = ConstantInt::get(ArgType, 1);
+    Value *Two = ConstantInt::get(ArgType, 2);
+
+    Value *IsLEOne = Builder.CreateICmpULE(ArgValue, One, "isleone");
+
+    BasicBlock *EntryBB = Builder.GetInsertBlock();
+    BasicBlock *CalcBB = createBasicBlock("bitceil.calc", CurFn);
+    BasicBlock *MergeBB = createBasicBlock("bitceil.merge", CurFn);
+
+    Builder.CreateCondBr(IsLEOne, MergeBB, CalcBB);
+
+    Builder.SetInsertPoint(CalcBB);
+    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+    Value *ArgMinusOne = Builder.CreateSub(ArgValue, One);
+    Value *LZ = Builder.CreateCall(F, {ArgMinusOne, Builder.getFalse()});
+    // 2<<(BitWidth-1-LZ) to get the next power of two. The shift
+    // amount is always in [0, BitWidth-1], so when LZ==0 (argument has its MSB
+    // set), the result wraps to 0
+    Value *ShiftAmt =
+        Builder.CreateSub(ConstantInt::get(ArgType, BitWidth - 1), LZ);
+    Value *Tmp = Builder.CreateShl(Two, ShiftAmt);
+    Builder.CreateBr(MergeBB);
+
+    Builder.SetInsertPoint(MergeBB);
+    PHINode *Phi = Builder.CreatePHI(ArgType, 2);
+    Phi->addIncoming(One, EntryBB);
+    Phi->addIncoming(Tmp, CalcBB);
+    return RValue::get(Phi);
+  }
+
   case Builtin::BI__builtin_constant_p: {
     llvm::Type *ResultType = ConvertType(E->getType());
 

diff  --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index f06c216e0c746..29b87a0616992 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4769,6 +4769,13 @@ class CodeGenFunction : public CodeGenTypeCache {
 
   RValue emitRotate(const CallExpr *E, bool IsRotateRight);
 
+  RValue emitStdcCountIntrinsic(const CallExpr *E, llvm::Intrinsic::ID IntID,
+                                bool InvertArg, bool IsPop = false);
+  RValue emitStdcBitWidthMinus(const CallExpr *E, llvm::Intrinsic::ID IntID,
+                               bool IsPop);
+  RValue emitStdcFirstBit(const CallExpr *E, llvm::Intrinsic::ID IntID,
+                          bool InvertArg);
+
   /// Emit IR for __builtin_os_log_format.
   RValue emitBuiltinOSLogFormat(const CallExpr &E);
 

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index b2288ff9b26d0..3f6e44b45a0a4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2356,6 +2356,45 @@ static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall) {
   return false;
 }
 
+/// Checks the __builtin_stdc_* builtins that take a single unsigned integer
+/// argument and return either int, bool, or the argument type.
+static bool BuiltinStdCBuiltin(Sema &S, CallExpr *TheCall,
+                               QualType ReturnType) {
+  if (S.checkArgCount(TheCall, 1))
+    return true;
+
+  ExprResult ArgRes = S.DefaultLvalueConversion(TheCall->getArg(0));
+  if (ArgRes.isInvalid())
+    return true;
+
+  Expr *Arg = ArgRes.get();
+  TheCall->setArg(0, Arg);
+
+  QualType ArgTy = Arg->getType();
+  // C23 stdbit.h functions do not permit bool or enumeration types.
+  if (ArgTy->isBooleanType() || ArgTy->isEnumeralType())
+    return S.Diag(Arg->getBeginLoc(),
+                  diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
+           << 1 /*1st argument*/ << ArgTy;
+  if (!ArgTy->isUnsignedIntegerType())
+    return S.Diag(Arg->getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
+           << 1 /*1st argument*/ << ArgTy;
+
+  // For builtins returning unsigned int, verify the argument's bit width fits.
+  // On targets where unsigned int is 16 bits, a large _BitInt argument could
+  // produce a count that overflows the return type.
+  if (!ReturnType.isNull() && ReturnType == S.Context.UnsignedIntTy) {
+    uint64_t ArgWidth = S.Context.getIntWidth(ArgTy);
+    uint64_t ReturnTypeWidth = S.Context.getIntWidth(S.Context.UnsignedIntTy);
+    if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
+      return S.Diag(Arg->getBeginLoc(), diag::err_builtin_stdc_result_overflow)
+             << ArgTy;
+  }
+
+  TheCall->setType(ReturnType.isNull() ? ArgTy : ReturnType);
+  return false;
+}
+
 /// Checks that __builtin_{clzg,ctzg} was called with a first argument, which is
 /// an unsigned integer, and an optional second argument, which is promoted to
 /// an 'int'.
@@ -3811,6 +3850,44 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
       return ExprError();
     break;
 
+  case Builtin::BI__builtin_stdc_bit_floor:
+  case Builtin::BI__builtin_stdc_bit_ceil:
+  case Builtin::BIstdc_bit_floor:
+  case Builtin::BIstdc_bit_ceil:
+    if (BuiltinStdCBuiltin(*this, TheCall, QualType()))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_stdc_has_single_bit:
+  case Builtin::BIstdc_has_single_bit:
+    if (BuiltinStdCBuiltin(*this, TheCall, Context.BoolTy))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_stdc_leading_zeros:
+  case Builtin::BI__builtin_stdc_leading_ones:
+  case Builtin::BI__builtin_stdc_trailing_zeros:
+  case Builtin::BI__builtin_stdc_trailing_ones:
+  case Builtin::BI__builtin_stdc_first_leading_zero:
+  case Builtin::BI__builtin_stdc_first_leading_one:
+  case Builtin::BI__builtin_stdc_first_trailing_zero:
+  case Builtin::BI__builtin_stdc_first_trailing_one:
+  case Builtin::BI__builtin_stdc_count_zeros:
+  case Builtin::BI__builtin_stdc_count_ones:
+  case Builtin::BI__builtin_stdc_bit_width:
+  case Builtin::BIstdc_leading_zeros:
+  case Builtin::BIstdc_leading_ones:
+  case Builtin::BIstdc_trailing_zeros:
+  case Builtin::BIstdc_trailing_ones:
+  case Builtin::BIstdc_first_leading_zero:
+  case Builtin::BIstdc_first_leading_one:
+  case Builtin::BIstdc_first_trailing_zero:
+  case Builtin::BIstdc_first_trailing_one:
+  case Builtin::BIstdc_count_zeros:
+  case Builtin::BIstdc_count_ones:
+  case Builtin::BIstdc_bit_width:
+    if (BuiltinStdCBuiltin(*this, TheCall, Context.UnsignedIntTy))
+      return ExprError();
+    break;
+
   case Builtin::BI__builtin_allow_runtime_check: {
     Expr *Arg = TheCall->getArg(0);
     // Check if the argument is a string literal.

diff  --git a/clang/test/CodeGen/Inputs/stdbit.h b/clang/test/CodeGen/Inputs/stdbit.h
new file mode 100644
index 0000000000000..f2f7aca355d94
--- /dev/null
+++ b/clang/test/CodeGen/Inputs/stdbit.h
@@ -0,0 +1,19 @@
+#ifndef LLVM_CLANG_TEST_STDBIT_H
+#define LLVM_CLANG_TEST_STDBIT_H
+
+#define stdc_leading_zeros(x) (__builtin_stdc_leading_zeros((x)))
+#define stdc_leading_ones(x) (__builtin_stdc_leading_ones((x)))
+#define stdc_trailing_zeros(x) (__builtin_stdc_trailing_zeros((x)))
+#define stdc_trailing_ones(x) (__builtin_stdc_trailing_ones((x)))
+#define stdc_first_leading_zero(x) (__builtin_stdc_first_leading_zero((x)))
+#define stdc_first_leading_one(x) (__builtin_stdc_first_leading_one((x)))
+#define stdc_first_trailing_zero(x) (__builtin_stdc_first_trailing_zero((x)))
+#define stdc_first_trailing_one(x) (__builtin_stdc_first_trailing_one((x)))
+#define stdc_count_zeros(x) (__builtin_stdc_count_zeros((x)))
+#define stdc_count_ones(x) (__builtin_stdc_count_ones((x)))
+#define stdc_has_single_bit(x) ((_Bool)__builtin_stdc_has_single_bit((x)))
+#define stdc_bit_width(x) (__builtin_stdc_bit_width((x)))
+#define stdc_bit_floor(x) (__builtin_stdc_bit_floor((x)))
+#define stdc_bit_ceil(x) (__builtin_stdc_bit_ceil((x)))
+
+#endif

diff  --git a/clang/test/CodeGen/builtin-stdc-bit-functions.c b/clang/test/CodeGen/builtin-stdc-bit-functions.c
new file mode 100644
index 0000000000000..5aec2703ad6e6
--- /dev/null
+++ b/clang/test/CodeGen/builtin-stdc-bit-functions.c
@@ -0,0 +1,486 @@
+// RUN: %clang_cc1 -ffreestanding -std=c23 %s -emit-llvm -o - | FileCheck %s
+// RUN: %if clang-target-64-bits %{ %clang_cc1 -ffreestanding -std=c23 %s -emit-llvm -o - | FileCheck %s --check-prefix=INT128 %}
+// RUN: %clang_cc1 -ffreestanding -std=c23 -isystem %S/Inputs -DTEST_LIB_SPELLINGS %s -emit-llvm -o - | FileCheck %s --check-prefix=LIB
+
+// CHECK-LABEL: test_leading_zeros
+// CHECK: call i8 @llvm.ctlz.i8(i8 %{{.*}}, i1 false)
+// CHECK: call i16 @llvm.ctlz.i16(i16 %{{.*}}, i1 false)
+// CHECK: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+// CHECK: call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 false)
+void test_leading_zeros(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_leading_zeros(uc);
+  r = __builtin_stdc_leading_zeros(us);
+  r = __builtin_stdc_leading_zeros(ui);
+  r = __builtin_stdc_leading_zeros(ull);
+}
+
+// CHECK-LABEL: test_leading_ones
+// CHECK: xor i8 %{{.*}}, -1
+// CHECK: call i8 @llvm.ctlz.i8(i8 %{{.*}}, i1 false)
+// CHECK: xor i16 %{{.*}}, -1
+// CHECK: call i16 @llvm.ctlz.i16(i16 %{{.*}}, i1 false)
+// CHECK: xor i32 %{{.*}}, -1
+// CHECK: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+// CHECK: xor i64 %{{.*}}, -1
+// CHECK: call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 false)
+void test_leading_ones(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_leading_ones(uc);
+  r = __builtin_stdc_leading_ones(us);
+  r = __builtin_stdc_leading_ones(ui);
+  r = __builtin_stdc_leading_ones(ull);
+}
+
+// CHECK-LABEL: test_trailing_zeros
+// CHECK: call i8 @llvm.cttz.i8(i8 %{{.*}}, i1 false)
+// CHECK: call i16 @llvm.cttz.i16(i16 %{{.*}}, i1 false)
+// CHECK: call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+// CHECK: call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
+void test_trailing_zeros(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_trailing_zeros(uc);
+  r = __builtin_stdc_trailing_zeros(us);
+  r = __builtin_stdc_trailing_zeros(ui);
+  r = __builtin_stdc_trailing_zeros(ull);
+}
+
+// CHECK-LABEL: test_trailing_ones
+// CHECK: xor i8 %{{.*}}, -1
+// CHECK: call i8 @llvm.cttz.i8(i8 %{{.*}}, i1 false)
+// CHECK: xor i16 %{{.*}}, -1
+// CHECK: call i16 @llvm.cttz.i16(i16 %{{.*}}, i1 false)
+// CHECK: xor i32 %{{.*}}, -1
+// CHECK: call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+// CHECK: xor i64 %{{.*}}, -1
+// CHECK: call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
+void test_trailing_ones(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_trailing_ones(uc);
+  r = __builtin_stdc_trailing_ones(us);
+  r = __builtin_stdc_trailing_ones(ui);
+  r = __builtin_stdc_trailing_ones(ull);
+}
+
+// CHECK-LABEL: test_first_leading_zero
+// CHECK: xor i8 %{{.*}}, -1
+// CHECK: call i8 @llvm.ctlz.i8(i8 %{{.*}}, i1 false)
+// CHECK: xor i16 %{{.*}}, -1
+// CHECK: call i16 @llvm.ctlz.i16(i16 %{{.*}}, i1 false)
+// CHECK: xor i32 %{{.*}}, -1
+// CHECK: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+// CHECK: xor i64 %{{.*}}, -1
+// CHECK: call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 false)
+void test_first_leading_zero(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_first_leading_zero(uc);
+  r = __builtin_stdc_first_leading_zero(us);
+  r = __builtin_stdc_first_leading_zero(ui);
+  r = __builtin_stdc_first_leading_zero(ull);
+}
+
+// CHECK-LABEL: test_first_leading_one
+// CHECK: call i8 @llvm.ctlz.i8(i8 %{{.*}}, i1 false)
+// CHECK: call i16 @llvm.ctlz.i16(i16 %{{.*}}, i1 false)
+// CHECK: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+// CHECK: call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 false)
+void test_first_leading_one(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_first_leading_one(uc);
+  r = __builtin_stdc_first_leading_one(us);
+  r = __builtin_stdc_first_leading_one(ui);
+  r = __builtin_stdc_first_leading_one(ull);
+}
+
+// CHECK-LABEL: test_first_trailing_zero
+// CHECK: xor i8 %{{.*}}, -1
+// CHECK: call i8 @llvm.cttz.i8(i8 %{{.*}}, i1 false)
+// CHECK: xor i16 %{{.*}}, -1
+// CHECK: call i16 @llvm.cttz.i16(i16 %{{.*}}, i1 false)
+// CHECK: xor i32 %{{.*}}, -1
+// CHECK: call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+// CHECK: xor i64 %{{.*}}, -1
+// CHECK: call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
+void test_first_trailing_zero(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_first_trailing_zero(uc);
+  r = __builtin_stdc_first_trailing_zero(us);
+  r = __builtin_stdc_first_trailing_zero(ui);
+  r = __builtin_stdc_first_trailing_zero(ull);
+}
+
+// CHECK-LABEL: test_first_trailing_one
+// CHECK: call i8 @llvm.cttz.i8(i8 %{{.*}}, i1 false)
+// CHECK: call i16 @llvm.cttz.i16(i16 %{{.*}}, i1 false)
+// CHECK: call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+// CHECK: call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
+void test_first_trailing_one(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_first_trailing_one(uc);
+  r = __builtin_stdc_first_trailing_one(us);
+  r = __builtin_stdc_first_trailing_one(ui);
+  r = __builtin_stdc_first_trailing_one(ull);
+}
+
+// CHECK-LABEL: test_count_zeros
+// CHECK: call i8 @llvm.ctpop.i8(i8 %{{.*}})
+// CHECK: call i16 @llvm.ctpop.i16(i16 %{{.*}})
+// CHECK: call i32 @llvm.ctpop.i32(i32 %{{.*}})
+// CHECK: call i64 @llvm.ctpop.i64(i64 %{{.*}})
+void test_count_zeros(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_count_zeros(uc);
+  r = __builtin_stdc_count_zeros(us);
+  r = __builtin_stdc_count_zeros(ui);
+  r = __builtin_stdc_count_zeros(ull);
+}
+
+// CHECK-LABEL: test_count_ones
+// CHECK: call i8 @llvm.ctpop.i8(i8 %{{.*}})
+// CHECK: call i16 @llvm.ctpop.i16(i16 %{{.*}})
+// CHECK: call i32 @llvm.ctpop.i32(i32 %{{.*}})
+// CHECK: call i64 @llvm.ctpop.i64(i64 %{{.*}})
+void test_count_ones(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_count_ones(uc);
+  r = __builtin_stdc_count_ones(us);
+  r = __builtin_stdc_count_ones(ui);
+  r = __builtin_stdc_count_ones(ull);
+}
+
+// CHECK-LABEL: test_has_single_bit
+// CHECK: call i8 @llvm.ctpop.i8(i8 %{{.*}})
+// CHECK: call i16 @llvm.ctpop.i16(i16 %{{.*}})
+// CHECK: call i32 @llvm.ctpop.i32(i32 %{{.*}})
+// CHECK: call i64 @llvm.ctpop.i64(i64 %{{.*}})
+void test_has_single_bit(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_has_single_bit(uc);
+  r = __builtin_stdc_has_single_bit(us);
+  r = __builtin_stdc_has_single_bit(ui);
+  r = __builtin_stdc_has_single_bit(ull);
+}
+
+// CHECK-LABEL: test_bit_width
+// CHECK: call i8 @llvm.ctlz.i8(i8 %{{.*}}, i1 false)
+// CHECK: call i16 @llvm.ctlz.i16(i16 %{{.*}}, i1 false)
+// CHECK: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+// CHECK: call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 false)
+void test_bit_width(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile int r;
+  r = __builtin_stdc_bit_width(uc);
+  r = __builtin_stdc_bit_width(us);
+  r = __builtin_stdc_bit_width(ui);
+  r = __builtin_stdc_bit_width(ull);
+}
+
+// CHECK-LABEL: test_bit_floor_uc
+// CHECK: [[LZ:%.*]] = call i8 @llvm.ctlz.i8(i8 %{{.*}}, i1 true)
+// CHECK: [[SHIFT:%.*]] = sub i8 7, [[LZ]]
+// CHECK: [[SHIFTED:%.*]] = shl i8 1, [[SHIFT]]
+// CHECK: [[ISZERO:%.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: select i1 [[ISZERO]], i8 0, i8 [[SHIFTED]]
+unsigned char test_bit_floor_uc(unsigned char uc) { return __builtin_stdc_bit_floor(uc); }
+
+// CHECK-LABEL: test_bit_floor_us
+// CHECK: [[LZ:%.*]] = call i16 @llvm.ctlz.i16(i16 %{{.*}}, i1 true)
+// CHECK: [[SHIFT:%.*]] = sub i16 15, [[LZ]]
+// CHECK: [[SHIFTED:%.*]] = shl i16 1, [[SHIFT]]
+// CHECK: [[ISZERO:%.*]] = icmp eq i16 %{{.*}}, 0
+// CHECK: select i1 [[ISZERO]], i16 0, i16 [[SHIFTED]]
+unsigned short test_bit_floor_us(unsigned short us) { return __builtin_stdc_bit_floor(us); }
+
+// CHECK-LABEL: test_bit_floor_ui
+// CHECK: [[LZ:%.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true)
+// CHECK: [[SHIFT:%.*]] = sub i32 31, [[LZ]]
+// CHECK: [[SHIFTED:%.*]] = shl i32 1, [[SHIFT]]
+// CHECK: [[ISZERO:%.*]] = icmp eq i32 %{{.*}}, 0
+// CHECK: select i1 [[ISZERO]], i32 0, i32 [[SHIFTED]]
+unsigned int test_bit_floor_ui(unsigned int ui) { return __builtin_stdc_bit_floor(ui); }
+
+// CHECK-LABEL: test_bit_floor_ull
+// CHECK: [[LZ:%.*]] = call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 true)
+// CHECK: [[SHIFT:%.*]] = sub i64 63, [[LZ]]
+// CHECK: [[SHIFTED:%.*]] = shl i64 1, [[SHIFT]]
+// CHECK: [[ISZERO:%.*]] = icmp eq i64 %{{.*}}, 0
+// CHECK: select i1 [[ISZERO]], i64 0, i64 [[SHIFTED]]
+unsigned long long test_bit_floor_ull(unsigned long long ull) { return __builtin_stdc_bit_floor(ull); }
+
+// CHECK-LABEL: test_bit_ceil_uc
+// CHECK: icmp ule i8 %{{.*}}, 1
+// CHECK: br i1 %{{.*}}, label %bitceil.merge, label %bitceil.calc
+// CHECK: bitceil.calc:
+// CHECK: sub i8 %{{.*}}, 1
+// CHECK: [[LZ:%.*]] = call i8 @llvm.ctlz.i8(i8 %{{.*}}, i1 false)
+// CHECK: [[SHIFT:%.*]] = sub i8 7, [[LZ]]
+// CHECK: shl i8 2, [[SHIFT]]
+// CHECK: bitceil.merge:
+// CHECK: phi i8 [ 1, %{{.*}} ], [ %{{.*}}, %bitceil.calc ]
+unsigned char test_bit_ceil_uc(unsigned char uc) { return __builtin_stdc_bit_ceil(uc); }
+
+// CHECK-LABEL: test_bit_ceil_us
+// CHECK: icmp ule i16 %{{.*}}, 1
+// CHECK: br i1 %{{.*}}, label %bitceil.merge, label %bitceil.calc
+// CHECK: bitceil.calc:
+// CHECK: sub i16 %{{.*}}, 1
+// CHECK: [[LZ:%.*]] = call i16 @llvm.ctlz.i16(i16 %{{.*}}, i1 false)
+// CHECK: [[SHIFT:%.*]] = sub i16 15, [[LZ]]
+// CHECK: shl i16 2, [[SHIFT]]
+// CHECK: bitceil.merge:
+// CHECK: phi i16 [ 1, %{{.*}} ], [ %{{.*}}, %bitceil.calc ]
+unsigned short test_bit_ceil_us(unsigned short us) { return __builtin_stdc_bit_ceil(us); }
+
+// CHECK-LABEL: test_bit_ceil_ui
+// CHECK: icmp ule i32 %{{.*}}, 1
+// CHECK: br i1 %{{.*}}, label %bitceil.merge, label %bitceil.calc
+// CHECK: bitceil.calc:
+// CHECK: sub i32 %{{.*}}, 1
+// CHECK: [[LZ:%.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+// CHECK: [[SHIFT:%.*]] = sub i32 31, [[LZ]]
+// CHECK: shl i32 2, [[SHIFT]]
+// CHECK: bitceil.merge:
+// CHECK: phi i32 [ 1, %{{.*}} ], [ %{{.*}}, %bitceil.calc ]
+unsigned int test_bit_ceil_ui(unsigned int ui) { return __builtin_stdc_bit_ceil(ui); }
+
+// CHECK-LABEL: test_bit_ceil_ull
+// CHECK: icmp ule i64 %{{.*}}, 1
+// CHECK: br i1 %{{.*}}, label %bitceil.merge, label %bitceil.calc
+// CHECK: bitceil.calc:
+// CHECK: sub i64 %{{.*}}, 1
+// CHECK: [[LZ:%.*]] = call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 false)
+// CHECK: [[SHIFT:%.*]] = sub i64 63, [[LZ]]
+// CHECK: shl i64 2, [[SHIFT]]
+// CHECK: bitceil.merge:
+// CHECK: phi i64 [ 1, %{{.*}} ], [ %{{.*}}, %bitceil.calc ]
+unsigned long long test_bit_ceil_ull(unsigned long long ull) { return __builtin_stdc_bit_ceil(ull); }
+
+// CHECK-LABEL: test_bit_floor
+// CHECK: call i8 @llvm.ctlz.i8(i8 %{{.*}}, i1 true)
+// CHECK: call i16 @llvm.ctlz.i16(i16 %{{.*}}, i1 true)
+// CHECK: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true)
+// CHECK: call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 true)
+void test_bit_floor(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile unsigned char rc;
+  volatile unsigned short rs;
+  volatile unsigned int ri;
+  volatile unsigned long long rll;
+  rc = __builtin_stdc_bit_floor(uc);
+  rs = __builtin_stdc_bit_floor(us);
+  ri = __builtin_stdc_bit_floor(ui);
+  rll = __builtin_stdc_bit_floor(ull);
+}
+
+// CHECK-LABEL: test_bit_ceil
+// CHECK: call i8 @llvm.ctlz.i8(i8 %{{.*}}, i1 false)
+// CHECK: call i16 @llvm.ctlz.i16(i16 %{{.*}}, i1 false)
+// CHECK: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+// CHECK: call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 false)
+void test_bit_ceil(unsigned char uc, unsigned short us, unsigned int ui, unsigned long long ull) {
+  volatile unsigned char rc;
+  volatile unsigned short rs;
+  volatile unsigned int ri;
+  volatile unsigned long long rll;
+  rc = __builtin_stdc_bit_ceil(uc);
+  rs = __builtin_stdc_bit_ceil(us);
+  ri = __builtin_stdc_bit_ceil(ui);
+  rll = __builtin_stdc_bit_ceil(ull);
+}
+
+// Test with _BitInt types
+// CHECK-LABEL: test_bitint
+// CHECK: call i37 @llvm.ctlz.i37(i37 %{{.*}}, i1 false)
+// CHECK: call i37 @llvm.cttz.i37(i37 %{{.*}}, i1 false)
+// CHECK: call i37 @llvm.ctpop.i37(i37 %{{.*}})
+void test_bitint(unsigned _BitInt(37) bi) {
+  volatile int r;
+  r = __builtin_stdc_leading_zeros(bi);
+  r = __builtin_stdc_trailing_zeros(bi);
+  r = __builtin_stdc_count_ones(bi);
+}
+
+// Additional _BitInt coverage
+// CHECK-LABEL: test_bitint_floor_ceil
+// CHECK: call i9 @llvm.ctlz.i9(i9 %{{.*}}, i1 true)
+// CHECK: call i9 @llvm.ctlz.i9(i9 %{{.*}}, i1 false)
+void test_bitint_floor_ceil(unsigned _BitInt(9) bi9) {
+  volatile unsigned _BitInt(9) rb;
+  rb = __builtin_stdc_bit_floor(bi9);
+  rb = __builtin_stdc_bit_ceil(bi9);
+}
+
+// CHECK-LABEL: test_bitint_first_and_count
+// CHECK: call i9 @llvm.ctlz.i9(i9 %{{.*}}, i1 false)
+// CHECK: call i9 @llvm.cttz.i9(i9 %{{.*}}, i1 false)
+// CHECK: call i9 @llvm.ctpop.i9(i9 %{{.*}})
+void test_bitint_first_and_count(unsigned _BitInt(9) bi9) {
+  volatile int r;
+  r = __builtin_stdc_first_leading_zero(bi9);
+  r = __builtin_stdc_first_trailing_zero(bi9);
+  r = __builtin_stdc_count_zeros(bi9);
+}
+
+// CHECK-LABEL: test_bit_floor_all_ones_bitint
+// CHECK: store volatile i32 65536, ptr %r
+void test_bit_floor_all_ones_bitint(void) {
+  volatile unsigned _BitInt(17) r =
+      __builtin_stdc_bit_floor((unsigned _BitInt(17))(-1));
+}
+
+// CHECK-LABEL: test_first_trailing_zero_all_ones_bitint
+// CHECK: store volatile i32 0, ptr %r
+void test_first_trailing_zero_all_ones_bitint(void) {
+  volatile unsigned _BitInt(17) r =
+      __builtin_stdc_first_trailing_zero((unsigned _BitInt(17))(-1));
+}
+
+#ifdef __SIZEOF_INT128__
+// INT128-LABEL: test_int128
+// INT128: call i128 @llvm.ctlz.i128(i128 %{{.*}}, i1 false)
+// INT128: call i128 @llvm.cttz.i128(i128 %{{.*}}, i1 false)
+// INT128: call i128 @llvm.ctpop.i128(i128 %{{.*}})
+void test_int128(unsigned __int128 u128) {
+  volatile int r;
+  r = __builtin_stdc_leading_zeros(u128);
+  r = __builtin_stdc_trailing_zeros(u128);
+  r = __builtin_stdc_count_ones(u128);
+}
+
+// INT128-LABEL: test_int128_leading_trailing_ones
+// INT128: xor i128 %{{.*}}, -1
+// INT128: call i128 @llvm.ctlz.i128(i128 %{{.*}}, i1 false)
+// INT128: xor i128 %{{.*}}, -1
+// INT128: call i128 @llvm.cttz.i128(i128 %{{.*}}, i1 false)
+void test_int128_leading_trailing_ones(unsigned __int128 u128) {
+  volatile int r;
+  r = __builtin_stdc_leading_ones(u128);
+  r = __builtin_stdc_trailing_ones(u128);
+}
+
+// INT128-LABEL: test_int128_first
+// INT128: xor i128 %{{.*}}, -1
+// INT128: call i128 @llvm.ctlz.i128(i128 %{{.*}}, i1 false)
+// INT128: call i128 @llvm.ctlz.i128(i128 %{{.*}}, i1 false)
+// INT128: xor i128 %{{.*}}, -1
+// INT128: call i128 @llvm.cttz.i128(i128 %{{.*}}, i1 false)
+// INT128: call i128 @llvm.cttz.i128(i128 %{{.*}}, i1 false)
+void test_int128_first(unsigned __int128 u128) {
+  volatile int r;
+  r = __builtin_stdc_first_leading_zero(u128);
+  r = __builtin_stdc_first_leading_one(u128);
+  r = __builtin_stdc_first_trailing_zero(u128);
+  r = __builtin_stdc_first_trailing_one(u128);
+}
+
+// INT128-LABEL: test_int128_count_has_width
+// INT128: call i128 @llvm.ctpop.i128(i128 %{{.*}})
+// INT128: call i128 @llvm.ctpop.i128(i128 %{{.*}})
+// INT128: call i128 @llvm.ctpop.i128(i128 %{{.*}})
+// INT128: call i128 @llvm.ctlz.i128(i128 %{{.*}}, i1 false)
+void test_int128_count_has_width(unsigned __int128 u128) {
+  volatile int r;
+  r = __builtin_stdc_count_zeros(u128);
+  r = __builtin_stdc_count_ones(u128);
+  r = __builtin_stdc_has_single_bit(u128);
+  r = __builtin_stdc_bit_width(u128);
+}
+
+// INT128-LABEL: test_int128_floor_ceil
+// INT128: call i128 @llvm.ctlz.i128(i128 %{{.*}}, i1 true)
+// INT128: call i128 @llvm.ctlz.i128(i128 %{{.*}}, i1 false)
+void test_int128_floor_ceil(unsigned __int128 u128) {
+  volatile unsigned __int128 r;
+  r = __builtin_stdc_bit_floor(u128);
+  r = __builtin_stdc_bit_ceil(u128);
+}
+#endif
+
+#ifdef TEST_LIB_SPELLINGS
+#include <stdbit.h>
+
+// LIB-LABEL: test_lib_leading_zeros
+// LIB: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+void test_lib_leading_zeros(unsigned ui) {
+  volatile unsigned r = stdc_leading_zeros(ui);
+}
+
+// LIB-LABEL: test_lib_leading_ones
+// LIB: xor i32 %{{.*}}, -1
+// LIB: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+void test_lib_leading_ones(unsigned ui) {
+  volatile unsigned r = stdc_leading_ones(ui);
+}
+
+// LIB-LABEL: test_lib_trailing_zeros
+// LIB: call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+void test_lib_trailing_zeros(unsigned ui) {
+  volatile unsigned r = stdc_trailing_zeros(ui);
+}
+
+// LIB-LABEL: test_lib_trailing_ones
+// LIB: xor i32 %{{.*}}, -1
+// LIB: call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+void test_lib_trailing_ones(unsigned ui) {
+  volatile unsigned r = stdc_trailing_ones(ui);
+}
+
+// LIB-LABEL: test_lib_first_leading_zero
+// LIB: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+void test_lib_first_leading_zero(unsigned ui) {
+  volatile unsigned r = stdc_first_leading_zero(ui);
+}
+
+// LIB-LABEL: test_lib_first_leading_one
+// LIB: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+void test_lib_first_leading_one(unsigned ui) {
+  volatile unsigned r = stdc_first_leading_one(ui);
+}
+
+// LIB-LABEL: test_lib_first_trailing_zero
+// LIB: xor i32 %{{.*}}, -1
+// LIB: call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+void test_lib_first_trailing_zero(unsigned ui) {
+  volatile unsigned r = stdc_first_trailing_zero(ui);
+}
+
+// LIB-LABEL: test_lib_first_trailing_one
+// LIB: call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+void test_lib_first_trailing_one(unsigned ui) {
+  volatile unsigned r = stdc_first_trailing_one(ui);
+}
+
+// LIB-LABEL: test_lib_count_zeros
+// LIB: call i32 @llvm.ctpop.i32(i32 %{{.*}})
+void test_lib_count_zeros(unsigned ui) {
+  volatile unsigned r = stdc_count_zeros(ui);
+}
+
+// LIB-LABEL: test_lib_count_ones
+// LIB: call i32 @llvm.ctpop.i32(i32 %{{.*}})
+void test_lib_count_ones(unsigned ui) {
+  volatile unsigned r = stdc_count_ones(ui);
+}
+
+// LIB-LABEL: test_lib_has_single_bit
+// LIB: call i32 @llvm.ctpop.i32(i32 %{{.*}})
+void test_lib_has_single_bit(unsigned ui) {
+  volatile _Bool r = stdc_has_single_bit(ui);
+}
+
+// LIB-LABEL: test_lib_bit_width
+// LIB: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+void test_lib_bit_width(unsigned ui) {
+  volatile unsigned r = stdc_bit_width(ui);
+}
+
+// LIB-LABEL: test_lib_bit_floor
+// LIB: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true)
+void test_lib_bit_floor(unsigned ui) {
+  volatile unsigned r = stdc_bit_floor(ui);
+}
+
+// LIB-LABEL: test_lib_bit_ceil
+// LIB: call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 false)
+void test_lib_bit_ceil(unsigned ui) {
+  volatile unsigned r = stdc_bit_ceil(ui);
+}
+#endif

diff  --git a/clang/test/Sema/Inputs/stdbit.h b/clang/test/Sema/Inputs/stdbit.h
new file mode 100644
index 0000000000000..f2f7aca355d94
--- /dev/null
+++ b/clang/test/Sema/Inputs/stdbit.h
@@ -0,0 +1,19 @@
+#ifndef LLVM_CLANG_TEST_STDBIT_H
+#define LLVM_CLANG_TEST_STDBIT_H
+
+#define stdc_leading_zeros(x) (__builtin_stdc_leading_zeros((x)))
+#define stdc_leading_ones(x) (__builtin_stdc_leading_ones((x)))
+#define stdc_trailing_zeros(x) (__builtin_stdc_trailing_zeros((x)))
+#define stdc_trailing_ones(x) (__builtin_stdc_trailing_ones((x)))
+#define stdc_first_leading_zero(x) (__builtin_stdc_first_leading_zero((x)))
+#define stdc_first_leading_one(x) (__builtin_stdc_first_leading_one((x)))
+#define stdc_first_trailing_zero(x) (__builtin_stdc_first_trailing_zero((x)))
+#define stdc_first_trailing_one(x) (__builtin_stdc_first_trailing_one((x)))
+#define stdc_count_zeros(x) (__builtin_stdc_count_zeros((x)))
+#define stdc_count_ones(x) (__builtin_stdc_count_ones((x)))
+#define stdc_has_single_bit(x) ((_Bool)__builtin_stdc_has_single_bit((x)))
+#define stdc_bit_width(x) (__builtin_stdc_bit_width((x)))
+#define stdc_bit_floor(x) (__builtin_stdc_bit_floor((x)))
+#define stdc_bit_ceil(x) (__builtin_stdc_bit_ceil((x)))
+
+#endif

diff  --git a/clang/test/Sema/builtin-stdc-bit-functions.c b/clang/test/Sema/builtin-stdc-bit-functions.c
new file mode 100644
index 0000000000000..818998e2086cc
--- /dev/null
+++ b/clang/test/Sema/builtin-stdc-bit-functions.c
@@ -0,0 +1,585 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c23 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c23 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c23 -isystem %S/Inputs -fsyntax-only -verify %s
+
+// Test stdc_leading_zeros
+_Static_assert(__builtin_stdc_leading_zeros((unsigned char)0) == 8, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned char)1) == 7, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned char)0x80) == 0, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned char)0xFF) == 0, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned short)0) == 16, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned short)1) == 15, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned short)0x8000) == 0, "");
+_Static_assert(__builtin_stdc_leading_zeros(0U) == 32, "");
+_Static_assert(__builtin_stdc_leading_zeros(1U) == 31, "");
+_Static_assert(__builtin_stdc_leading_zeros(0x80000000U) == 0, "");
+_Static_assert(__builtin_stdc_leading_zeros(0ULL) == 64, "");
+_Static_assert(__builtin_stdc_leading_zeros(1ULL) == 63, "");
+_Static_assert(__builtin_stdc_leading_zeros(0x8000000000000000ULL) == 0, "");
+
+// Test stdc_leading_ones
+_Static_assert(__builtin_stdc_leading_ones((unsigned char)0) == 0, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned char)0xFF) == 8, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned char)0xF0) == 4, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned short)0) == 0, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned short)0xFFFF) == 16, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned short)0xF000) == 4, "");
+_Static_assert(__builtin_stdc_leading_ones(0U) == 0, "");
+_Static_assert(__builtin_stdc_leading_ones(0xFFFFFFFFU) == 32, "");
+_Static_assert(__builtin_stdc_leading_ones(0xF0000000U) == 4, "");
+_Static_assert(__builtin_stdc_leading_ones(0ULL) == 0, "");
+_Static_assert(__builtin_stdc_leading_ones(0xFFFFFFFFFFFFFFFFULL) == 64, "");
+
+// Test stdc_trailing_zeros
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned char)0) == 8, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned char)1) == 0, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned char)0x80) == 7, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned short)0) == 16, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned short)1) == 0, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned short)0x8000) == 15, "");
+_Static_assert(__builtin_stdc_trailing_zeros(0U) == 32, "");
+_Static_assert(__builtin_stdc_trailing_zeros(1U) == 0, "");
+_Static_assert(__builtin_stdc_trailing_zeros(0x80000000U) == 31, "");
+_Static_assert(__builtin_stdc_trailing_zeros(0ULL) == 64, "");
+_Static_assert(__builtin_stdc_trailing_zeros(1ULL) == 0, "");
+_Static_assert(__builtin_stdc_trailing_zeros(0x8000000000000000ULL) == 63, "");
+
+// Test stdc_trailing_ones
+_Static_assert(__builtin_stdc_trailing_ones((unsigned char)0) == 0, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned char)0xFF) == 8, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned char)0x0F) == 4, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned short)0) == 0, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned short)0xFFFF) == 16, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned short)0x000F) == 4, "");
+_Static_assert(__builtin_stdc_trailing_ones(0U) == 0, "");
+_Static_assert(__builtin_stdc_trailing_ones(1U) == 1, "");
+_Static_assert(__builtin_stdc_trailing_ones(0xFFFFFFFFU) == 32, "");
+_Static_assert(__builtin_stdc_trailing_ones(0x0000000FU) == 4, "");
+_Static_assert(__builtin_stdc_trailing_ones(0ULL) == 0, "");
+_Static_assert(__builtin_stdc_trailing_ones(1ULL) == 1, "");
+_Static_assert(__builtin_stdc_trailing_ones(0xFFFFFFFFFFFFFFFFULL) == 64, "");
+
+// Test stdc_first_leading_zero
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned char)0) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned char)0xFF) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned char)0xF0) == 5, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned char)0x80) == 2, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned short)0) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned short)0xFFFF) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned short)0xF000) == 5, "");
+_Static_assert(__builtin_stdc_first_leading_zero(0xFFFFFFFFU) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_zero(0xF0000000U) == 5, "");
+_Static_assert(__builtin_stdc_first_leading_zero(0ULL) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_zero(0xFFFFFFFFFFFFFFFFULL) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_zero(0xF000000000000000ULL) == 5, "");
+
+// Test stdc_first_leading_one
+_Static_assert(__builtin_stdc_first_leading_one((unsigned char)0) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned char)0x80) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned char)0x01) == 8, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned char)0x0F) == 5, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned short)0) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned short)0x8000) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned short)1) == 16, "");
+_Static_assert(__builtin_stdc_first_leading_one(0U) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_one(0x80000000U) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_one(1U) == 32, "");
+_Static_assert(__builtin_stdc_first_leading_one(0ULL) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_one(0x8000000000000000ULL) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_one(1ULL) == 64, "");
+
+// Test stdc_first_trailing_zero
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0xFF) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0x0F) == 5, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0x01) == 2, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned short)0) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned short)0xFFFF) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned short)0x000F) == 5, "");
+_Static_assert(__builtin_stdc_first_trailing_zero(0xFFFFFFFFU) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_zero(0x0000000FU) == 5, "");
+_Static_assert(__builtin_stdc_first_trailing_zero(0ULL) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_zero(0xFFFFFFFFFFFFFFFFULL) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_zero(0x000000000000000FULL) == 5, "");
+
+// Test stdc_first_trailing_one
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned char)0) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned char)0x01) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned char)0x80) == 8, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned char)0xF0) == 5, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned short)0) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned short)1) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned short)0x8000) == 16, "");
+_Static_assert(__builtin_stdc_first_trailing_one(0U) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one(0x80000000U) == 32, "");
+_Static_assert(__builtin_stdc_first_trailing_one(1U) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_one(0ULL) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one(1ULL) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_one(0x8000000000000000ULL) == 64, "");
+
+// Test stdc_count_zeros
+_Static_assert(__builtin_stdc_count_zeros((unsigned char)0) == 8, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned char)0xFF) == 0, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned char)0xAA) == 4, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned short)0) == 16, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned short)0xFFFF) == 0, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned short)0xAAAA) == 8, "");
+_Static_assert(__builtin_stdc_count_zeros(0U) == 32, "");
+_Static_assert(__builtin_stdc_count_zeros(0xFFFFFFFFU) == 0, "");
+_Static_assert(__builtin_stdc_count_zeros(0xAAAAAAAAU) == 16, "");
+_Static_assert(__builtin_stdc_count_zeros(0ULL) == 64, "");
+_Static_assert(__builtin_stdc_count_zeros(0xFFFFFFFFFFFFFFFFULL) == 0, "");
+_Static_assert(__builtin_stdc_count_zeros(0xAAAAAAAAAAAAAAAAULL) == 32, "");
+
+// Test stdc_count_ones
+_Static_assert(__builtin_stdc_count_ones((unsigned char)0) == 0, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned char)0xFF) == 8, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned char)0xAA) == 4, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned short)0) == 0, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned short)0xFFFF) == 16, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned short)0xAAAA) == 8, "");
+_Static_assert(__builtin_stdc_count_ones(0U) == 0, "");
+_Static_assert(__builtin_stdc_count_ones(0xFFFFFFFFU) == 32, "");
+_Static_assert(__builtin_stdc_count_ones(0xAAAAAAAAU) == 16, "");
+_Static_assert(__builtin_stdc_count_ones(0ULL) == 0, "");
+_Static_assert(__builtin_stdc_count_ones(0xFFFFFFFFFFFFFFFFULL) == 64, "");
+_Static_assert(__builtin_stdc_count_ones(0xAAAAAAAAAAAAAAAAULL) == 32, "");
+
+// Test stdc_has_single_bit
+_Static_assert(__builtin_stdc_has_single_bit((unsigned char)0) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned char)1) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned char)2) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned char)3) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned char)0x80) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned short)0) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned short)1) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned short)0x8000) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned short)0xFFFF) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit(0U) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit(1U) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit(0x80000000U) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit(0xFFFFFFFFU) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit(0ULL) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit(1ULL) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit(0x8000000000000000ULL) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit(0xFFFFFFFFFFFFFFFFULL) == 0, "");
+
+// Test stdc_bit_width
+_Static_assert(__builtin_stdc_bit_width((unsigned char)0) == 0, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned char)1) == 1, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned char)2) == 2, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned char)3) == 2, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned char)0x80) == 8, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned char)0xFF) == 8, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned short)0) == 0, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned short)1) == 1, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned short)0x8000) == 16, "");
+_Static_assert(__builtin_stdc_bit_width(0U) == 0, "");
+_Static_assert(__builtin_stdc_bit_width(1U) == 1, "");
+_Static_assert(__builtin_stdc_bit_width(0x80000000U) == 32, "");
+_Static_assert(__builtin_stdc_bit_width(0ULL) == 0, "");
+_Static_assert(__builtin_stdc_bit_width(1ULL) == 1, "");
+_Static_assert(__builtin_stdc_bit_width(0x8000000000000000ULL) == 64, "");
+
+// Test stdc_bit_floor
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)0) == 0, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)1) == 1, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)2) == 2, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)3) == 2, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)4) == 4, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)5) == 4, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)0x80) == 0x80, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)0xFF) == 0x80, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned short)0) == 0, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned short)1) == 1, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned short)0xFFFF) == 0x8000, "");
+_Static_assert(__builtin_stdc_bit_floor(0U) == 0U, "");
+_Static_assert(__builtin_stdc_bit_floor(1U) == 1U, "");
+_Static_assert(__builtin_stdc_bit_floor(7U) == 4U, "");
+_Static_assert(__builtin_stdc_bit_floor(0x80000000U) == 0x80000000U, "");
+_Static_assert(__builtin_stdc_bit_floor(0xFFFFFFFFU) == 0x80000000U, "");
+_Static_assert(__builtin_stdc_bit_floor(0ULL) == 0ULL, "");
+_Static_assert(__builtin_stdc_bit_floor(1ULL) == 1ULL, "");
+_Static_assert(__builtin_stdc_bit_floor(0xFFFFFFFFFFFFFFFFULL) == 0x8000000000000000ULL, "");
+
+// Test stdc_bit_ceil
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)0) == 1, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)1) == 1, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)2) == 2, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)3) == 4, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)4) == 4, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)5) == 8, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)0x80) == 0x80, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)0x81) == 0, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)0xFE) == 0, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)0xFF) == 0, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned short)0) == 1, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned short)1) == 1, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned short)7) == 8, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned short)0x8000) == 0x8000, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned short)0x8001) == 0, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned short)0xFFFF) == 0, "");
+_Static_assert(__builtin_stdc_bit_ceil(0U) == 1U, "");
+_Static_assert(__builtin_stdc_bit_ceil(1U) == 1U, "");
+_Static_assert(__builtin_stdc_bit_ceil(7U) == 8U, "");
+_Static_assert(__builtin_stdc_bit_ceil(0x80000000U) == 0x80000000U, "");
+_Static_assert(__builtin_stdc_bit_ceil(0x80000001U) == 0U, "");
+_Static_assert(__builtin_stdc_bit_ceil(0xFFFFFFFFU) == 0U, "");
+_Static_assert(__builtin_stdc_bit_ceil(0ULL) == 1ULL, "");
+_Static_assert(__builtin_stdc_bit_ceil(1ULL) == 1ULL, "");
+_Static_assert(__builtin_stdc_bit_ceil(7ULL) == 8ULL, "");
+_Static_assert(__builtin_stdc_bit_ceil(0x8000000000000000ULL) == 0x8000000000000000ULL, "");
+_Static_assert(__builtin_stdc_bit_ceil(0x8000000000000001ULL) == 0ULL, "");
+_Static_assert(__builtin_stdc_bit_ceil(0xFFFFFFFFFFFFFFFFULL) == 0ULL, "");
+
+// Test with _BitInt types - cover all 14 builtins
+_Static_assert(__builtin_stdc_leading_zeros((unsigned _BitInt(37))0) == 37, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned _BitInt(37))1) == 36, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned _BitInt(37))0) == 0, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned _BitInt(37))-1) == 37, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned _BitInt(37))0) == 37, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned _BitInt(37))1) == 0, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned _BitInt(37))0) == 0, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned _BitInt(37))-1) == 37, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned _BitInt(37))0) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned _BitInt(37))-1) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned _BitInt(37))0) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned _BitInt(37))1) == 37, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned _BitInt(37))0) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned _BitInt(37))-1) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned _BitInt(37))0) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned _BitInt(37))1) == 1, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned _BitInt(37))0x1F) == 5, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned _BitInt(37))0) == 37, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned _BitInt(37))-1) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned _BitInt(37))0x10) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned _BitInt(37))0) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned _BitInt(37))3) == 0, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned _BitInt(37))0x10) == 5, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned _BitInt(37))0) == 0, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned _BitInt(37))-1) == 37, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned _BitInt(37))0x1F) == 0x10, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned _BitInt(37))0x11) == 0x20, "");
+
+#ifdef __SIZEOF_INT128__
+// Test with __int128 - cover all 14 builtins
+_Static_assert(__builtin_stdc_leading_zeros((unsigned __int128)0) == 128, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned __int128)1) == 127, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned __int128)0) == 0, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned __int128)-1) == 128, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned __int128)0) == 128, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned __int128)1) == 0, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned __int128)0) == 0, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned __int128)-1) == 128, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned __int128)0) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned __int128)-1) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned __int128)0) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned __int128)0) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned __int128)-1) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned __int128)0) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned __int128)1) == 1, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned __int128)0xFFFFFFFF) == 32, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned __int128)0) == 128, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned __int128)-1) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned __int128)1) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned __int128)0) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned __int128)3) == 0, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned __int128)1) == 1, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned __int128)0) == 0, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned __int128)0) == 0, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned __int128)1) == 1, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned __int128)0) == 1, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned __int128)1) == 1, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned __int128)3) == 4, "");
+#endif // __SIZEOF_INT128__
+
+// Test with unsigned long across all targets.
+enum { ULONG_WIDTH = __SIZEOF_LONG__ * 8 };
+
+_Static_assert(__builtin_stdc_leading_zeros(0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_leading_zeros(1UL) == ULONG_WIDTH - 1, "");
+_Static_assert(__builtin_stdc_leading_zeros(1UL << (ULONG_WIDTH - 1)) == 0, "");
+_Static_assert(__builtin_stdc_leading_ones(0UL) == 0, "");
+_Static_assert(__builtin_stdc_leading_ones(~0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_leading_ones(~0UL << (ULONG_WIDTH - 4)) == 4, "");
+_Static_assert(__builtin_stdc_trailing_zeros(0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_trailing_zeros(1UL) == 0, "");
+_Static_assert(__builtin_stdc_trailing_zeros(1UL << (ULONG_WIDTH - 1)) == ULONG_WIDTH - 1, "");
+_Static_assert(__builtin_stdc_trailing_ones(0UL) == 0, "");
+_Static_assert(__builtin_stdc_trailing_ones(~0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_trailing_ones(0xFUL) == 4, "");
+_Static_assert(__builtin_stdc_first_leading_zero(0UL) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_zero(~0UL) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_zero(~0UL << (ULONG_WIDTH - 4)) == 5, "");
+_Static_assert(__builtin_stdc_first_leading_one(0UL) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_one(1UL << (ULONG_WIDTH - 1)) == 1, "");
+_Static_assert(__builtin_stdc_first_leading_one(1UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_first_trailing_zero(0UL) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_zero(~0UL) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_zero(0xFUL) == 5, "");
+_Static_assert(__builtin_stdc_first_trailing_one(0UL) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one(1UL) == 1, "");
+_Static_assert(__builtin_stdc_first_trailing_one(1UL << (ULONG_WIDTH - 1)) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_count_zeros(0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_count_zeros(~0UL) == 0, "");
+_Static_assert(__builtin_stdc_count_zeros(1UL << (ULONG_WIDTH - 1)) == ULONG_WIDTH - 1, "");
+_Static_assert(__builtin_stdc_count_ones(0UL) == 0, "");
+_Static_assert(__builtin_stdc_count_ones(~0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_count_ones(1UL << (ULONG_WIDTH - 1)) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit(0UL) == 0, "");
+_Static_assert(__builtin_stdc_has_single_bit(1UL) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit(1UL << (ULONG_WIDTH - 1)) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit(~0UL) == 0, "");
+_Static_assert(__builtin_stdc_bit_width(0UL) == 0, "");
+_Static_assert(__builtin_stdc_bit_width(1UL) == 1, "");
+_Static_assert(__builtin_stdc_bit_width(1UL << (ULONG_WIDTH - 1)) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_bit_floor(0UL) == 0UL, "");
+_Static_assert(__builtin_stdc_bit_floor(1UL) == 1UL, "");
+_Static_assert(__builtin_stdc_bit_floor(~0UL) == (1UL << (ULONG_WIDTH - 1)), "");
+_Static_assert(__builtin_stdc_bit_ceil(0UL) == 1UL, "");
+_Static_assert(__builtin_stdc_bit_ceil(1UL) == 1UL, "");
+_Static_assert(__builtin_stdc_bit_ceil(7UL) == 8UL, "");
+_Static_assert(__builtin_stdc_bit_ceil(1UL << (ULONG_WIDTH - 1)) == (1UL << (ULONG_WIDTH - 1)), "");
+_Static_assert(__builtin_stdc_bit_ceil((1UL << (ULONG_WIDTH - 1)) + 1) == 0UL, "");
+_Static_assert(__builtin_stdc_bit_ceil(~0UL) == 0UL, "");
+
+// alternating bit patterns
+_Static_assert(__builtin_stdc_leading_zeros(0x55555555U) == 1, "");
+_Static_assert(__builtin_stdc_leading_ones(0xAAAAAAAAU) == 1, "");
+_Static_assert(__builtin_stdc_trailing_zeros(0xAAAAAAAAU) == 1, "");
+_Static_assert(__builtin_stdc_trailing_ones(0x55555555U) == 1, "");
+_Static_assert(__builtin_stdc_count_zeros(0x55555555U) == 16, "");
+_Static_assert(__builtin_stdc_count_ones(0x55555555U) == 16, "");
+_Static_assert(__builtin_stdc_count_zeros(0xAAAAAAAAU) == 16, "");
+_Static_assert(__builtin_stdc_count_ones(0xAAAAAAAAU) == 16, "");
+_Static_assert(__builtin_stdc_bit_width(0x55555555U) == 31, "");
+_Static_assert(__builtin_stdc_bit_width(0xAAAAAAAAU) == 32, "");
+_Static_assert(__builtin_stdc_bit_floor(0x55555555U) == 0x40000000U, "");
+_Static_assert(__builtin_stdc_bit_floor(0xAAAAAAAAU) == 0x80000000U, "");
+_Static_assert(__builtin_stdc_bit_ceil(0x55555555U) == 0x80000000U, "");
+_Static_assert(__builtin_stdc_bit_ceil(0xAAAAAAAAU) == 0U, "");
+
+// nibble patterns
+_Static_assert(__builtin_stdc_leading_zeros(0x0F0F0F0FU) == 4, "");
+_Static_assert(__builtin_stdc_leading_zeros(0xF0F0F0F0U) == 0, "");
+_Static_assert(__builtin_stdc_count_ones(0x0F0F0F0FU) == 16, "");
+_Static_assert(__builtin_stdc_count_ones(0xF0F0F0F0U) == 16, "");
+_Static_assert(__builtin_stdc_bit_ceil(0x0F0F0F0FU) == 0x10000000U, "");
+_Static_assert(__builtin_stdc_bit_ceil(0xF0F0F0F0U) == 0U, "");
+
+// Error cases - all 14 builtins reject bool and enumeration arguments
+enum UnsignedEnum { UE_A = 0, UE_B = 1 };
+enum SignedEnum { SE_A = -1, SE_B = 1 };
+void test_bool_enum_errors(_Bool b, enum UnsignedEnum ue, enum SignedEnum se) {
+  __builtin_stdc_leading_zeros(b);   // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_leading_zeros(ue);  // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+  __builtin_stdc_leading_zeros(se);  // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum SignedEnum')}}
+
+  __builtin_stdc_leading_ones(b);    // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_leading_ones(ue);   // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_trailing_zeros(b);  // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_trailing_zeros(ue); // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_trailing_ones(b);   // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_trailing_ones(ue);  // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_first_leading_zero(b);   // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_first_leading_zero(ue);  // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_first_leading_one(b);    // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_first_leading_one(ue);   // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_first_trailing_zero(b);  // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_first_trailing_zero(ue); // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_first_trailing_one(b);   // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_first_trailing_one(ue);  // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_count_ones(b);      // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_count_ones(ue);     // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_count_zeros(b);     // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_count_zeros(ue);    // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_has_single_bit(b);  // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_has_single_bit(ue); // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_bit_width(b);       // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_bit_width(ue);      // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_bit_floor(b);       // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_bit_floor(ue);      // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+
+  __builtin_stdc_bit_ceil(b);        // expected-error {{1st argument must not be a boolean or enumeration type (was 'bool')}}
+  __builtin_stdc_bit_ceil(ue);       // expected-error {{1st argument must not be a boolean or enumeration type (was 'enum UnsignedEnum')}}
+}
+
+// Error cases - all 14 builtins reject signed and floating-point arguments
+void test_errors(int si, float f) {
+  __builtin_stdc_leading_zeros(si);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_leading_zeros(f);   // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+  __builtin_stdc_leading_zeros(-1);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+
+  __builtin_stdc_leading_ones(si);   // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_leading_ones(f);    // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_trailing_zeros(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_trailing_zeros(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_trailing_ones(si);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_trailing_ones(f);   // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_first_leading_zero(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_first_leading_zero(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_first_leading_one(si);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_first_leading_one(f);   // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_first_trailing_zero(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_first_trailing_zero(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_first_trailing_one(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_first_trailing_one(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_count_ones(si);     // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_count_ones(f);      // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_count_zeros(si);    // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_count_zeros(f);     // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_has_single_bit(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_has_single_bit(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_bit_width(si);      // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_bit_width(f);       // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_bit_floor(si);      // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_bit_floor(f);       // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_bit_ceil(si);       // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_bit_ceil(f);        // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+}
+
+#ifdef __has_include
+#if __has_include(<stdbit.h>)
+#include <stdbit.h>
+
+_Static_assert(stdc_leading_zeros(0U) == 32, "");
+_Static_assert(stdc_leading_zeros(1U) == 31, "");
+_Static_assert(stdc_leading_ones(0xFFFFFFFFU) == 32, "");
+_Static_assert(stdc_trailing_zeros(0U) == 32, "");
+_Static_assert(stdc_trailing_ones(0xFFFFFFFFU) == 32, "");
+_Static_assert(stdc_first_leading_zero(0U) == 1, "");
+_Static_assert(stdc_first_leading_one(0U) == 0, "");
+_Static_assert(stdc_first_trailing_zero(0U) == 1, "");
+_Static_assert(stdc_first_trailing_one(0U) == 0, "");
+_Static_assert(stdc_count_zeros(0U) == 32, "");
+_Static_assert(stdc_count_ones(0xFFFFFFFFU) == 32, "");
+_Static_assert(stdc_has_single_bit(4U) == 1, "");
+_Static_assert(stdc_bit_width(7U) == 3, "");
+_Static_assert(stdc_bit_floor(6U) == 4U, "");
+_Static_assert(stdc_bit_ceil(6U) == 8U, "");
+
+// Type-specific: each builtin truncates to the target type before operating.
+_Static_assert(__builtin_stdc_leading_zeros((unsigned char)0) == 8, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned short)0) == 16, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned int)0) == 32, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned long)0) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_leading_zeros((unsigned long long)0) == 64, "");
+
+_Static_assert(__builtin_stdc_leading_ones((unsigned char)0xFF) == 8, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned short)0xFFFF) == 16, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned int)0xFFFFFFFF) == 32, "");
+_Static_assert(__builtin_stdc_leading_ones(~0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned long long)0xFFFFFFFFFFFFFFFF) == 64, "");
+
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned char)0) == 8, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned short)0) == 16, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned int)0) == 32, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned long)0) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned long long)0) == 64, "");
+
+_Static_assert(__builtin_stdc_trailing_ones((unsigned char)0xFF) == 8, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned short)0xFFFF) == 16, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned int)0xFFFFFFFF) == 32, "");
+_Static_assert(__builtin_stdc_trailing_ones(~0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned long long)0xFFFFFFFFFFFFFFFF) == 64, "");
+
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned char)0xFE) == 8, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned short)0xFFFE) == 16, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned int)0xFFFFFFFE) == 32, "");
+_Static_assert(__builtin_stdc_first_leading_zero(~1UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned long long)0xFFFFFFFFFFFFFFFE) == 64, "");
+
+_Static_assert(__builtin_stdc_first_leading_one((unsigned char)0x01) == 8, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned short)0x0001) == 16, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned int)0x00000001) == 32, "");
+_Static_assert(__builtin_stdc_first_leading_one(1UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned long long)0x0000000000000001) == 64, "");
+
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0x7F) == 8, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned short)0x7FFF) == 16, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned int)0x7FFFFFFF) == 32, "");
+_Static_assert(__builtin_stdc_first_trailing_zero(~0UL >> 1) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned long long)0x7FFFFFFFFFFFFFFF) == 64, "");
+
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned char)0x80) == 8, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned short)0x8000) == 16, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned int)0x80000000) == 32, "");
+_Static_assert(__builtin_stdc_first_trailing_one(1UL << (ULONG_WIDTH - 1)) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned long long)0x8000000000000000) == 64, "");
+
+_Static_assert(__builtin_stdc_count_zeros((unsigned char)0) == 8, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned short)0) == 16, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned int)0) == 32, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned long)0) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned long long)0) == 64, "");
+
+_Static_assert(__builtin_stdc_count_ones((unsigned char)0xFF) == 8, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned short)0xFFFF) == 16, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned int)0xFFFFFFFF) == 32, "");
+_Static_assert(__builtin_stdc_count_ones(~0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned long long)0xFFFFFFFFFFFFFFFF) == 64, "");
+
+_Static_assert(__builtin_stdc_has_single_bit((unsigned char)0x80) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned short)0x8000) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned int)0x80000000) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit(1UL << (ULONG_WIDTH - 1)) == 1, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned long long)0x8000000000000000) == 1, "");
+
+_Static_assert(__builtin_stdc_bit_width((unsigned char)0xFF) == 8, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned short)0xFFFF) == 16, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned int)0xFFFFFFFF) == 32, "");
+_Static_assert(__builtin_stdc_bit_width(~0UL) == ULONG_WIDTH, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned long long)0xFFFFFFFFFFFFFFFF) == 64, "");
+
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)0x80) == 0x80, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned short)0x8000) == 0x8000, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned int)0x80000000) == 0x80000000U, "");
+_Static_assert(__builtin_stdc_bit_floor(~0UL) == (1UL << (ULONG_WIDTH - 1)), "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned long long)0x8000000000000000) == 0x8000000000000000ULL, "");
+
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)0x7F) == 0x80, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned short)0x7FFF) == 0x8000, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned int)0x7FFFFFFF) == 0x80000000U, "");
+_Static_assert(__builtin_stdc_bit_ceil(1UL << (ULONG_WIDTH - 1)) == (1UL << (ULONG_WIDTH - 1)), "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned long long)0x7FFFFFFFFFFFFFFF) == 0x8000000000000000ULL, "");
+
+// Truncation: passing a large ull verifies only the low N bits are used.
+_Static_assert(__builtin_stdc_leading_zeros((unsigned char)0x8000000000000000ULL) == 8, "");
+_Static_assert(__builtin_stdc_leading_ones((unsigned char)0xFFFFFFFFFFFFFFFFULL) == 8, "");
+_Static_assert(__builtin_stdc_trailing_zeros((unsigned char)0x8000000000000000ULL) == 8, "");
+_Static_assert(__builtin_stdc_trailing_ones((unsigned char)0xFFFFFFFFFFFFFFFFULL) == 8, "");
+_Static_assert(__builtin_stdc_first_leading_zero((unsigned char)0xFFFFFFFFFFFFFFFFULL) == 0, "");
+_Static_assert(__builtin_stdc_first_leading_one((unsigned char)0xFF00000000000001ULL) == 8, "");
+_Static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0xFFFFFFFFFFFFFFFFULL) == 0, "");
+_Static_assert(__builtin_stdc_first_trailing_one((unsigned char)0x8000000000000080ULL) == 8, "");
+_Static_assert(__builtin_stdc_count_zeros((unsigned char)0x8000000000000000ULL) == 8, "");
+_Static_assert(__builtin_stdc_count_ones((unsigned char)0xFFFFFFFFFFFFFFFFULL) == 8, "");
+_Static_assert(__builtin_stdc_has_single_bit((unsigned char)0x8000000080008080ULL) == 1, "");
+_Static_assert(__builtin_stdc_bit_width((unsigned char)0xFFFFFFFFFFFFFFFFULL) == 8, "");
+_Static_assert(__builtin_stdc_bit_floor((unsigned char)0x8000000080008080ULL) == 0x80, "");
+_Static_assert(__builtin_stdc_bit_ceil((unsigned char)0x800000008000807FULL) == 0x80, "");
+#endif
+#endif

diff  --git a/clang/test/SemaCXX/constexpr-builtin-stdc-bit-functions.cpp b/clang/test/SemaCXX/constexpr-builtin-stdc-bit-functions.cpp
new file mode 100644
index 0000000000000..8bcaa16e991ad
--- /dev/null
+++ b/clang/test/SemaCXX/constexpr-builtin-stdc-bit-functions.cpp
@@ -0,0 +1,476 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++14 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++14 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter
+
+namespace test_stdc_leading_zeros {
+
+static_assert(__builtin_stdc_leading_zeros((unsigned char)0) == 8, "");
+static_assert(__builtin_stdc_leading_zeros((unsigned char)1) == 7, "");
+static_assert(__builtin_stdc_leading_zeros((unsigned char)0x80) == 0, "");
+static_assert(__builtin_stdc_leading_zeros((unsigned char)0xFF) == 0, "");
+static_assert(__builtin_stdc_leading_zeros((unsigned short)0) == 16, "");
+static_assert(__builtin_stdc_leading_zeros((unsigned short)1) == 15, "");
+static_assert(__builtin_stdc_leading_zeros((unsigned short)0x8000) == 0, "");
+static_assert(__builtin_stdc_leading_zeros(0U) == 32, "");
+static_assert(__builtin_stdc_leading_zeros(1U) == 31, "");
+static_assert(__builtin_stdc_leading_zeros(0x80000000U) == 0, "");
+static_assert(__builtin_stdc_leading_zeros(0ULL) == 64, "");
+static_assert(__builtin_stdc_leading_zeros(1ULL) == 63, "");
+static_assert(__builtin_stdc_leading_zeros(0x8000000000000000ULL) == 0, "");
+
+} // namespace test_stdc_leading_zeros
+
+namespace test_stdc_leading_ones {
+
+static_assert(__builtin_stdc_leading_ones((unsigned char)0) == 0, "");
+static_assert(__builtin_stdc_leading_ones((unsigned char)0xFF) == 8, "");
+static_assert(__builtin_stdc_leading_ones((unsigned char)0xF0) == 4, "");
+static_assert(__builtin_stdc_leading_ones((unsigned short)0) == 0, "");
+static_assert(__builtin_stdc_leading_ones((unsigned short)0xFFFF) == 16, "");
+static_assert(__builtin_stdc_leading_ones((unsigned short)0xF000) == 4, "");
+static_assert(__builtin_stdc_leading_ones(0U) == 0, "");
+static_assert(__builtin_stdc_leading_ones(0xFFFFFFFFU) == 32, "");
+static_assert(__builtin_stdc_leading_ones(0xF0000000U) == 4, "");
+static_assert(__builtin_stdc_leading_ones(0ULL) == 0, "");
+static_assert(__builtin_stdc_leading_ones(0xFFFFFFFFFFFFFFFFULL) == 64, "");
+
+} // namespace test_stdc_leading_ones
+
+namespace test_stdc_trailing_zeros {
+
+static_assert(__builtin_stdc_trailing_zeros((unsigned char)0) == 8, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned char)1) == 0, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned char)0x80) == 7, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned short)0) == 16, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned short)1) == 0, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned short)0x8000) == 15, "");
+static_assert(__builtin_stdc_trailing_zeros(0U) == 32, "");
+static_assert(__builtin_stdc_trailing_zeros(1U) == 0, "");
+static_assert(__builtin_stdc_trailing_zeros(0x80000000U) == 31, "");
+static_assert(__builtin_stdc_trailing_zeros(0ULL) == 64, "");
+static_assert(__builtin_stdc_trailing_zeros(1ULL) == 0, "");
+static_assert(__builtin_stdc_trailing_zeros(0x8000000000000000ULL) == 63, "");
+
+} // namespace test_stdc_trailing_zeros
+
+namespace test_stdc_trailing_ones {
+
+static_assert(__builtin_stdc_trailing_ones((unsigned char)0) == 0, "");
+static_assert(__builtin_stdc_trailing_ones((unsigned char)0xFF) == 8, "");
+static_assert(__builtin_stdc_trailing_ones((unsigned char)0x0F) == 4, "");
+static_assert(__builtin_stdc_trailing_ones((unsigned short)0) == 0, "");
+static_assert(__builtin_stdc_trailing_ones((unsigned short)0xFFFF) == 16, "");
+static_assert(__builtin_stdc_trailing_ones((unsigned short)0x000F) == 4, "");
+static_assert(__builtin_stdc_trailing_ones(0U) == 0, "");
+static_assert(__builtin_stdc_trailing_ones(1U) == 1, "");
+static_assert(__builtin_stdc_trailing_ones(0xFFFFFFFFU) == 32, "");
+static_assert(__builtin_stdc_trailing_ones(0x0000000FU) == 4, "");
+static_assert(__builtin_stdc_trailing_ones(0ULL) == 0, "");
+static_assert(__builtin_stdc_trailing_ones(1ULL) == 1, "");
+static_assert(__builtin_stdc_trailing_ones(0xFFFFFFFFFFFFFFFFULL) == 64, "");
+
+} // namespace test_stdc_trailing_ones
+
+namespace test_stdc_first_leading_zero {
+
+static_assert(__builtin_stdc_first_leading_zero((unsigned char)0) == 1, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned char)0xFF) == 0, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned char)0xF0) == 5, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned char)0x80) == 2, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned short)0) == 1, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned short)0xFFFF) == 0, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned short)0xF000) == 5, "");
+static_assert(__builtin_stdc_first_leading_zero(0xFFFFFFFFU) == 0, "");
+static_assert(__builtin_stdc_first_leading_zero(0xF0000000U) == 5, "");
+static_assert(__builtin_stdc_first_leading_zero(0ULL) == 1, "");
+static_assert(__builtin_stdc_first_leading_zero(0xFFFFFFFFFFFFFFFFULL) == 0, "");
+static_assert(__builtin_stdc_first_leading_zero(0xF000000000000000ULL) == 5, "");
+
+} // namespace test_stdc_first_leading_zero
+
+namespace test_stdc_first_leading_one {
+
+static_assert(__builtin_stdc_first_leading_one((unsigned char)0) == 0, "");
+static_assert(__builtin_stdc_first_leading_one((unsigned char)0x80) == 1, "");
+static_assert(__builtin_stdc_first_leading_one((unsigned char)0x01) == 8, "");
+static_assert(__builtin_stdc_first_leading_one((unsigned char)0x0F) == 5, "");
+static_assert(__builtin_stdc_first_leading_one((unsigned short)0) == 0, "");
+static_assert(__builtin_stdc_first_leading_one((unsigned short)0x8000) == 1, "");
+static_assert(__builtin_stdc_first_leading_one((unsigned short)1) == 16, "");
+static_assert(__builtin_stdc_first_leading_one(0U) == 0, "");
+static_assert(__builtin_stdc_first_leading_one(0x80000000U) == 1, "");
+static_assert(__builtin_stdc_first_leading_one(1U) == 32, "");
+static_assert(__builtin_stdc_first_leading_one(0ULL) == 0, "");
+static_assert(__builtin_stdc_first_leading_one(0x8000000000000000ULL) == 1, "");
+static_assert(__builtin_stdc_first_leading_one(1ULL) == 64, "");
+
+} // namespace test_stdc_first_leading_one
+
+namespace test_stdc_first_trailing_zero {
+
+static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0) == 1, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0xFF) == 0, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0x0F) == 5, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned char)0x01) == 2, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned short)0) == 1, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned short)0xFFFF) == 0, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned short)0x000F) == 5, "");
+static_assert(__builtin_stdc_first_trailing_zero(0xFFFFFFFFU) == 0, "");
+static_assert(__builtin_stdc_first_trailing_zero(0x0000000FU) == 5, "");
+static_assert(__builtin_stdc_first_trailing_zero(0ULL) == 1, "");
+static_assert(__builtin_stdc_first_trailing_zero(0xFFFFFFFFFFFFFFFFULL) == 0, "");
+static_assert(__builtin_stdc_first_trailing_zero(0x000000000000000FULL) == 5, "");
+
+} // namespace test_stdc_first_trailing_zero
+
+namespace test_stdc_first_trailing_one {
+
+static_assert(__builtin_stdc_first_trailing_one((unsigned char)0) == 0, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned char)0x01) == 1, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned char)0x80) == 8, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned char)0xF0) == 5, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned short)0) == 0, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned short)1) == 1, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned short)0x8000) == 16, "");
+static_assert(__builtin_stdc_first_trailing_one(0U) == 0, "");
+static_assert(__builtin_stdc_first_trailing_one(0x80000000U) == 32, "");
+static_assert(__builtin_stdc_first_trailing_one(1U) == 1, "");
+static_assert(__builtin_stdc_first_trailing_one(0ULL) == 0, "");
+static_assert(__builtin_stdc_first_trailing_one(1ULL) == 1, "");
+static_assert(__builtin_stdc_first_trailing_one(0x8000000000000000ULL) == 64, "");
+
+} // namespace test_stdc_first_trailing_one
+
+namespace test_stdc_count_zeros {
+
+static_assert(__builtin_stdc_count_zeros((unsigned char)0) == 8, "");
+static_assert(__builtin_stdc_count_zeros((unsigned char)0xFF) == 0, "");
+static_assert(__builtin_stdc_count_zeros((unsigned char)0xAA) == 4, "");
+static_assert(__builtin_stdc_count_zeros((unsigned short)0) == 16, "");
+static_assert(__builtin_stdc_count_zeros((unsigned short)0xFFFF) == 0, "");
+static_assert(__builtin_stdc_count_zeros((unsigned short)0xAAAA) == 8, "");
+static_assert(__builtin_stdc_count_zeros(0U) == 32, "");
+static_assert(__builtin_stdc_count_zeros(0xFFFFFFFFU) == 0, "");
+static_assert(__builtin_stdc_count_zeros(0xAAAAAAAAU) == 16, "");
+static_assert(__builtin_stdc_count_zeros(0ULL) == 64, "");
+static_assert(__builtin_stdc_count_zeros(0xFFFFFFFFFFFFFFFFULL) == 0, "");
+static_assert(__builtin_stdc_count_zeros(0xAAAAAAAAAAAAAAAAULL) == 32, "");
+
+} // namespace test_stdc_count_zeros
+
+namespace test_stdc_count_ones {
+
+static_assert(__builtin_stdc_count_ones((unsigned char)0) == 0, "");
+static_assert(__builtin_stdc_count_ones((unsigned char)0xFF) == 8, "");
+static_assert(__builtin_stdc_count_ones((unsigned char)0xAA) == 4, "");
+static_assert(__builtin_stdc_count_ones((unsigned short)0) == 0, "");
+static_assert(__builtin_stdc_count_ones((unsigned short)0xFFFF) == 16, "");
+static_assert(__builtin_stdc_count_ones((unsigned short)0xAAAA) == 8, "");
+static_assert(__builtin_stdc_count_ones(0U) == 0, "");
+static_assert(__builtin_stdc_count_ones(0xFFFFFFFFU) == 32, "");
+static_assert(__builtin_stdc_count_ones(0xAAAAAAAAU) == 16, "");
+static_assert(__builtin_stdc_count_ones(0ULL) == 0, "");
+static_assert(__builtin_stdc_count_ones(0xFFFFFFFFFFFFFFFFULL) == 64, "");
+static_assert(__builtin_stdc_count_ones(0xAAAAAAAAAAAAAAAAULL) == 32, "");
+
+} // namespace test_stdc_count_ones
+
+namespace test_stdc_has_single_bit {
+
+static_assert(__builtin_stdc_has_single_bit((unsigned char)0) == 0, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned char)1) == 1, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned char)2) == 1, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned char)3) == 0, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned char)0x80) == 1, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned short)0) == 0, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned short)1) == 1, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned short)0x8000) == 1, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned short)0xFFFF) == 0, "");
+static_assert(__builtin_stdc_has_single_bit(0U) == 0, "");
+static_assert(__builtin_stdc_has_single_bit(1U) == 1, "");
+static_assert(__builtin_stdc_has_single_bit(0x80000000U) == 1, "");
+static_assert(__builtin_stdc_has_single_bit(0xFFFFFFFFU) == 0, "");
+static_assert(__builtin_stdc_has_single_bit(0ULL) == 0, "");
+static_assert(__builtin_stdc_has_single_bit(1ULL) == 1, "");
+static_assert(__builtin_stdc_has_single_bit(0x8000000000000000ULL) == 1, "");
+static_assert(__builtin_stdc_has_single_bit(0xFFFFFFFFFFFFFFFFULL) == 0, "");
+
+} // namespace test_stdc_has_single_bit
+
+namespace test_stdc_bit_width {
+
+static_assert(__builtin_stdc_bit_width((unsigned char)0) == 0, "");
+static_assert(__builtin_stdc_bit_width((unsigned char)1) == 1, "");
+static_assert(__builtin_stdc_bit_width((unsigned char)2) == 2, "");
+static_assert(__builtin_stdc_bit_width((unsigned char)3) == 2, "");
+static_assert(__builtin_stdc_bit_width((unsigned char)0x80) == 8, "");
+static_assert(__builtin_stdc_bit_width((unsigned char)0xFF) == 8, "");
+static_assert(__builtin_stdc_bit_width((unsigned short)0) == 0, "");
+static_assert(__builtin_stdc_bit_width((unsigned short)1) == 1, "");
+static_assert(__builtin_stdc_bit_width((unsigned short)0x8000) == 16, "");
+static_assert(__builtin_stdc_bit_width(0U) == 0, "");
+static_assert(__builtin_stdc_bit_width(1U) == 1, "");
+static_assert(__builtin_stdc_bit_width(0x80000000U) == 32, "");
+static_assert(__builtin_stdc_bit_width(0ULL) == 0, "");
+static_assert(__builtin_stdc_bit_width(1ULL) == 1, "");
+static_assert(__builtin_stdc_bit_width(0x8000000000000000ULL) == 64, "");
+
+} // namespace test_stdc_bit_width
+
+namespace test_stdc_bit_floor {
+
+static_assert(__builtin_stdc_bit_floor((unsigned char)0) == 0, "");
+static_assert(__builtin_stdc_bit_floor((unsigned char)1) == 1, "");
+static_assert(__builtin_stdc_bit_floor((unsigned char)2) == 2, "");
+static_assert(__builtin_stdc_bit_floor((unsigned char)3) == 2, "");
+static_assert(__builtin_stdc_bit_floor((unsigned char)4) == 4, "");
+static_assert(__builtin_stdc_bit_floor((unsigned char)5) == 4, "");
+static_assert(__builtin_stdc_bit_floor((unsigned char)0x80) == 0x80, "");
+static_assert(__builtin_stdc_bit_floor((unsigned char)0xFF) == 0x80, "");
+static_assert(__builtin_stdc_bit_floor((unsigned short)0) == 0, "");
+static_assert(__builtin_stdc_bit_floor((unsigned short)1) == 1, "");
+static_assert(__builtin_stdc_bit_floor((unsigned short)0xFFFF) == 0x8000, "");
+static_assert(__builtin_stdc_bit_floor(0U) == 0U, "");
+static_assert(__builtin_stdc_bit_floor(1U) == 1U, "");
+static_assert(__builtin_stdc_bit_floor(7U) == 4U, "");
+static_assert(__builtin_stdc_bit_floor(0x80000000U) == 0x80000000U, "");
+static_assert(__builtin_stdc_bit_floor(0xFFFFFFFFU) == 0x80000000U, "");
+static_assert(__builtin_stdc_bit_floor(0ULL) == 0ULL, "");
+static_assert(__builtin_stdc_bit_floor(1ULL) == 1ULL, "");
+static_assert(__builtin_stdc_bit_floor(0xFFFFFFFFFFFFFFFFULL) == 0x8000000000000000ULL, "");
+
+} // namespace test_stdc_bit_floor
+
+namespace test_stdc_bit_ceil {
+
+static_assert(__builtin_stdc_bit_ceil((unsigned char)0) == 1, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned char)1) == 1, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned char)2) == 2, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned char)3) == 4, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned char)4) == 4, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned char)5) == 8, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned char)0x80) == 0x80, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned short)0) == 1, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned short)1) == 1, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned short)7) == 8, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned short)0x8000) == 0x8000, "");
+static_assert(__builtin_stdc_bit_ceil(0U) == 1U, "");
+static_assert(__builtin_stdc_bit_ceil(1U) == 1U, "");
+static_assert(__builtin_stdc_bit_ceil(7U) == 8U, "");
+static_assert(__builtin_stdc_bit_ceil(0x80000000U) == 0x80000000U, "");
+// Overflow: next power of 2 exceeds type width; wraps to zero.
+static_assert(__builtin_stdc_bit_ceil(0xFFFFFFFFU) == 0U, "");
+static_assert(__builtin_stdc_bit_ceil(0ULL) == 1ULL, "");
+static_assert(__builtin_stdc_bit_ceil(1ULL) == 1ULL, "");
+static_assert(__builtin_stdc_bit_ceil(7ULL) == 8ULL, "");
+static_assert(__builtin_stdc_bit_ceil(0x8000000000000000ULL) == 0x8000000000000000ULL, "");
+
+} // namespace test_stdc_bit_ceil
+
+#ifdef __SIZEOF_INT128__
+namespace test_int128 {
+
+static_assert(__builtin_stdc_leading_zeros((unsigned __int128)0) == 128, "");
+static_assert(__builtin_stdc_leading_zeros((unsigned __int128)1) == 127, "");
+static_assert(__builtin_stdc_leading_ones((unsigned __int128)0) == 0, "");
+static_assert(__builtin_stdc_leading_ones((unsigned __int128)-1) == 128, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned __int128)0) == 128, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned __int128)1) == 0, "");
+static_assert(__builtin_stdc_trailing_ones((unsigned __int128)0) == 0, "");
+static_assert(__builtin_stdc_trailing_ones((unsigned __int128)-1) == 128, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned __int128)0) == 1, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned __int128)-1) == 0, "");
+static_assert(__builtin_stdc_first_leading_one((unsigned __int128)0) == 0, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned __int128)0) == 1, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned __int128)-1) == 0, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned __int128)0) == 0, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned __int128)1) == 1, "");
+static_assert(__builtin_stdc_count_ones((unsigned __int128)0xFFFFFFFF) == 32, "");
+static_assert(__builtin_stdc_count_zeros((unsigned __int128)0) == 128, "");
+static_assert(__builtin_stdc_count_zeros((unsigned __int128)-1) == 0, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned __int128)1) == 1, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned __int128)0) == 0, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned __int128)3) == 0, "");
+static_assert(__builtin_stdc_bit_width((unsigned __int128)0) == 0, "");
+static_assert(__builtin_stdc_bit_width((unsigned __int128)1) == 1, "");
+static_assert(__builtin_stdc_bit_floor((unsigned __int128)0) == 0, "");
+static_assert(__builtin_stdc_bit_floor((unsigned __int128)1) == 1, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned __int128)0) == 1, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned __int128)1) == 1, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned __int128)3) == 4, "");
+
+// MSB tests using constexpr to form the value.
+constexpr unsigned __int128 int128_one = 1;
+constexpr unsigned __int128 int128_msb = int128_one << 127;
+static_assert(__builtin_stdc_leading_zeros(int128_msb) == 0, "");
+static_assert(__builtin_stdc_leading_ones(int128_msb) == 1, "");
+static_assert(__builtin_stdc_trailing_zeros(int128_msb) == 127, "");
+static_assert(__builtin_stdc_trailing_ones(int128_msb) == 0, "");
+static_assert(__builtin_stdc_first_leading_zero(int128_msb) == 2, "");
+static_assert(__builtin_stdc_first_leading_one(int128_msb) == 1, "");
+static_assert(__builtin_stdc_first_trailing_zero(int128_msb) == 1, "");
+static_assert(__builtin_stdc_first_trailing_one(int128_msb) == 128, "");
+static_assert(__builtin_stdc_count_ones(int128_msb) == 1, "");
+static_assert(__builtin_stdc_count_zeros(int128_msb) == 127, "");
+static_assert(__builtin_stdc_has_single_bit(int128_msb) == 1, "");
+static_assert(__builtin_stdc_bit_width(int128_msb) == 128, "");
+static_assert(__builtin_stdc_bit_floor(int128_msb) == int128_msb, "");
+static_assert(__builtin_stdc_bit_ceil(int128_msb) == int128_msb, "");
+
+} // namespace test_int128
+#endif // __SIZEOF_INT128__
+
+namespace test_bitint {
+
+// _BitInt(37): all 14 builtins
+static_assert(__builtin_stdc_leading_zeros((unsigned _BitInt(37))0) == 37, "");
+static_assert(__builtin_stdc_leading_zeros((unsigned _BitInt(37))1) == 36, "");
+static_assert(__builtin_stdc_leading_ones((unsigned _BitInt(37))0) == 0, "");
+static_assert(__builtin_stdc_leading_ones((unsigned _BitInt(37))-1) == 37, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned _BitInt(37))0) == 37, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned _BitInt(37))1) == 0, "");
+static_assert(__builtin_stdc_trailing_ones((unsigned _BitInt(37))0) == 0, "");
+static_assert(__builtin_stdc_trailing_ones((unsigned _BitInt(37))-1) == 37, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned _BitInt(37))0) == 1, "");
+static_assert(__builtin_stdc_first_leading_zero((unsigned _BitInt(37))-1) == 0, "");
+static_assert(__builtin_stdc_first_leading_one((unsigned _BitInt(37))0) == 0, "");
+static_assert(__builtin_stdc_first_leading_one((unsigned _BitInt(37))1) == 37, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned _BitInt(37))0) == 1, "");
+static_assert(__builtin_stdc_first_trailing_zero((unsigned _BitInt(37))-1) == 0, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned _BitInt(37))0) == 0, "");
+static_assert(__builtin_stdc_first_trailing_one((unsigned _BitInt(37))1) == 1, "");
+static_assert(__builtin_stdc_count_ones((unsigned _BitInt(37))0x1F) == 5, "");
+static_assert(__builtin_stdc_count_zeros((unsigned _BitInt(37))0) == 37, "");
+static_assert(__builtin_stdc_count_zeros((unsigned _BitInt(37))-1) == 0, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned _BitInt(37))0x10) == 1, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned _BitInt(37))0) == 0, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned _BitInt(37))3) == 0, "");
+static_assert(__builtin_stdc_bit_width((unsigned _BitInt(37))0x10) == 5, "");
+static_assert(__builtin_stdc_bit_width((unsigned _BitInt(37))0) == 0, "");
+static_assert(__builtin_stdc_bit_width((unsigned _BitInt(37))-1) == 37, "");
+static_assert(__builtin_stdc_bit_floor((unsigned _BitInt(37))0x1F) == 0x10, "");
+static_assert(__builtin_stdc_bit_ceil((unsigned _BitInt(37))0x11) == 0x20, "");
+// Overflow: next power of 2 exceeds _BitInt(17) width; wraps to zero.
+static_assert(__builtin_stdc_bit_ceil((unsigned _BitInt(17))(-1)) ==
+              (unsigned _BitInt(17))(0), "");
+
+// _BitInt(128): sparse pattern, leading zero count, popcount.
+constexpr unsigned _BitInt(128) bi128_pattern = 0x123456789ABCDEF0ULL;
+static_assert(__builtin_stdc_count_ones(bi128_pattern) == 32, "");
+static_assert(__builtin_stdc_leading_zeros(bi128_pattern) == 67, "");
+static_assert(__builtin_stdc_count_zeros(bi128_pattern) == 96, "");
+
+// _BitInt(9): boundary width near a byte.
+static_assert(__builtin_stdc_leading_zeros((unsigned _BitInt(9))0) == 9, "");
+static_assert(__builtin_stdc_trailing_zeros((unsigned _BitInt(9))0x100) == 8, "");
+static_assert(__builtin_stdc_count_ones((unsigned _BitInt(9))0x1FF) == 9, "");
+static_assert(__builtin_stdc_count_zeros((unsigned _BitInt(9))0x1FF) == 0, "");
+static_assert(__builtin_stdc_has_single_bit((unsigned _BitInt(9))0x100) == 1, "");
+static_assert(__builtin_stdc_bit_width((unsigned _BitInt(9))0x100) == 9, "");
+static_assert(__builtin_stdc_bit_floor((unsigned _BitInt(9))0x1FF) == 0x100, "");
+
+} // namespace test_bitint
+
+namespace test_stdc_ulong {
+
+constexpr unsigned long ULongWidth = __SIZEOF_LONG__ * 8;
+constexpr unsigned long ULongMSB = 1UL << (ULongWidth - 1);
+constexpr unsigned long ULongAllOnes = ~0UL;
+constexpr unsigned long ULongTopNibbleOnes = ULongAllOnes << (ULongWidth - 4);
+
+static_assert(__builtin_stdc_leading_zeros(0UL) == ULongWidth, "");
+static_assert(__builtin_stdc_leading_zeros(1UL) == ULongWidth - 1, "");
+static_assert(__builtin_stdc_leading_zeros(ULongMSB) == 0, "");
+static_assert(__builtin_stdc_leading_ones(0UL) == 0, "");
+static_assert(__builtin_stdc_leading_ones(ULongAllOnes) == ULongWidth, "");
+static_assert(__builtin_stdc_leading_ones(ULongTopNibbleOnes) == 4, "");
+static_assert(__builtin_stdc_trailing_zeros(0UL) == ULongWidth, "");
+static_assert(__builtin_stdc_trailing_zeros(1UL) == 0, "");
+static_assert(__builtin_stdc_trailing_zeros(ULongMSB) == ULongWidth - 1, "");
+static_assert(__builtin_stdc_trailing_ones(0UL) == 0, "");
+static_assert(__builtin_stdc_trailing_ones(ULongAllOnes) == ULongWidth, "");
+static_assert(__builtin_stdc_trailing_ones(0xFUL) == 4, "");
+static_assert(__builtin_stdc_first_leading_zero(0UL) == 1, "");
+static_assert(__builtin_stdc_first_leading_zero(ULongAllOnes) == 0, "");
+static_assert(__builtin_stdc_first_leading_zero(ULongTopNibbleOnes) == 5, "");
+static_assert(__builtin_stdc_first_leading_one(0UL) == 0, "");
+static_assert(__builtin_stdc_first_leading_one(ULongMSB) == 1, "");
+static_assert(__builtin_stdc_first_leading_one(1UL) == ULongWidth, "");
+static_assert(__builtin_stdc_first_trailing_zero(0UL) == 1, "");
+static_assert(__builtin_stdc_first_trailing_zero(ULongAllOnes) == 0, "");
+static_assert(__builtin_stdc_first_trailing_zero(0xFUL) == 5, "");
+static_assert(__builtin_stdc_first_trailing_one(0UL) == 0, "");
+static_assert(__builtin_stdc_first_trailing_one(1UL) == 1, "");
+static_assert(__builtin_stdc_first_trailing_one(ULongMSB) == ULongWidth, "");
+static_assert(__builtin_stdc_count_zeros(0UL) == ULongWidth, "");
+static_assert(__builtin_stdc_count_zeros(ULongAllOnes) == 0, "");
+static_assert(__builtin_stdc_count_zeros(ULongMSB) == ULongWidth - 1, "");
+static_assert(__builtin_stdc_count_ones(0UL) == 0, "");
+static_assert(__builtin_stdc_count_ones(ULongAllOnes) == ULongWidth, "");
+static_assert(__builtin_stdc_count_ones(ULongMSB) == 1, "");
+static_assert(__builtin_stdc_has_single_bit(0UL) == 0, "");
+static_assert(__builtin_stdc_has_single_bit(1UL) == 1, "");
+static_assert(__builtin_stdc_has_single_bit(ULongMSB) == 1, "");
+static_assert(__builtin_stdc_has_single_bit(ULongAllOnes) == 0, "");
+static_assert(__builtin_stdc_bit_width(0UL) == 0, "");
+static_assert(__builtin_stdc_bit_width(1UL) == 1, "");
+static_assert(__builtin_stdc_bit_width(ULongMSB) == ULongWidth, "");
+static_assert(__builtin_stdc_bit_floor(0UL) == 0UL, "");
+static_assert(__builtin_stdc_bit_floor(1UL) == 1UL, "");
+static_assert(__builtin_stdc_bit_floor(ULongAllOnes) == ULongMSB, "");
+static_assert(__builtin_stdc_bit_ceil(0UL) == 1UL, "");
+static_assert(__builtin_stdc_bit_ceil(1UL) == 1UL, "");
+static_assert(__builtin_stdc_bit_ceil(7UL) == 8UL, "");
+static_assert(__builtin_stdc_bit_ceil(ULongMSB) == ULongMSB, "");
+
+} // namespace test_stdc_ulong
+
+namespace test_errors {
+
+void test_invalid_types(int si, float f) {
+  __builtin_stdc_leading_zeros(si);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_leading_zeros(f);   // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+  __builtin_stdc_leading_zeros(-1);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+
+  __builtin_stdc_leading_ones(si);   // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_leading_ones(f);    // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_trailing_zeros(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_trailing_zeros(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_trailing_ones(si);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_trailing_ones(f);   // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_first_leading_zero(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_first_leading_zero(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_first_leading_one(si);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_first_leading_one(f);   // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_first_trailing_zero(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_first_trailing_zero(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_first_trailing_one(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_first_trailing_one(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_count_ones(si);     // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_count_ones(f);      // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_count_zeros(si);    // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_count_zeros(f);     // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_has_single_bit(si); // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_has_single_bit(f);  // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_bit_width(si);      // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_bit_width(f);       // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_bit_floor(si);      // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_bit_floor(f);       // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+
+  __builtin_stdc_bit_ceil(si);       // expected-error {{1st argument must be a scalar unsigned integer type (was 'int')}}
+  __builtin_stdc_bit_ceil(f);        // expected-error {{1st argument must be a scalar unsigned integer type (was 'float')}}
+}
+
+} // namespace test_errors


        


More information about the cfe-commits mailing list