Author: NagaChaitanya Vellanki Date: 2026-08-10T11:50:53-07:00 New Revision: 317aa53cbc0866a82d41e162144118797e4f3615
URL: https://github.com/llvm/llvm-project/commit/317aa53cbc0866a82d41e162144118797e4f3615 DIFF: https://github.com/llvm/llvm-project/commit/317aa53cbc0866a82d41e162144118797e4f3615.diff LOG: [clang] Fix crash in __builtin_stdc_bit_ceil for a 1-bit _BitInt (#214822) The literal 2 as an ArgType constant requires at least 2 bits. For a 1-bit unsigned _BitInt, this triggers an assertion failure in APInt's constructor (and silently computes a corrupted result in NDEBUG builds). Compute the value via a shift of the always-valid constant 1 instead, so it never depends on ArgType's width. Fixes: #214478 Added: Modified: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/builtin-stdc-bit-functions.c clang/test/SemaCXX/constexpr-builtin-stdc-bit-functions.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 4c1318f6543c1..3521fc10f1387 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -4164,10 +4164,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, 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(); @@ -4183,8 +4180,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // 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 + unsigned BitWidth = ArgType->getIntegerBitWidth(); Value *ShiftAmt = Builder.CreateSub(ConstantInt::get(ArgType, BitWidth - 1), LZ); + Value *Two = Builder.CreateShl(One, One); Value *Tmp = Builder.CreateShl(Two, ShiftAmt); Builder.CreateBr(MergeBB); diff --git a/clang/test/CodeGen/builtin-stdc-bit-functions.c b/clang/test/CodeGen/builtin-stdc-bit-functions.c index 1d7b99122135f..e4fd8f77b0e35 100644 --- a/clang/test/CodeGen/builtin-stdc-bit-functions.c +++ b/clang/test/CodeGen/builtin-stdc-bit-functions.c @@ -319,6 +319,13 @@ void test_bitint_first_and_count(unsigned _BitInt(9) bi9) { r = __builtin_stdc_count_zeros(bi9); } +// CHECK-LABEL: test_bit_ceil_bitint1 +// CHECK: shl i1 poison, %{{.*}} +// CHECK: phi i1 [ true, %{{.*}} ], [ %{{.*}}, %bitceil.calc ] +void test_bit_ceil_bitint1(unsigned _BitInt(1) bi1) { + volatile unsigned _BitInt(1) r = __builtin_stdc_bit_ceil(bi1); +} + // CHECK-LABEL: test_bit_floor_all_ones_bitint // CHECK: store volatile i32 65536, ptr %r void test_bit_floor_all_ones_bitint(void) { diff --git a/clang/test/SemaCXX/constexpr-builtin-stdc-bit-functions.cpp b/clang/test/SemaCXX/constexpr-builtin-stdc-bit-functions.cpp index 8bcaa16e991ad..9354c65432fc1 100644 --- a/clang/test/SemaCXX/constexpr-builtin-stdc-bit-functions.cpp +++ b/clang/test/SemaCXX/constexpr-builtin-stdc-bit-functions.cpp @@ -355,6 +355,10 @@ static_assert(__builtin_stdc_bit_ceil((unsigned _BitInt(37))0x11) == 0x20, ""); static_assert(__builtin_stdc_bit_ceil((unsigned _BitInt(17))(-1)) == (unsigned _BitInt(17))(0), ""); +// _BitInt(1): +static_assert(__builtin_stdc_bit_ceil((unsigned _BitInt(1))0) == 1, ""); +static_assert(__builtin_stdc_bit_ceil((unsigned _BitInt(1))1) == 1, ""); + // _BitInt(128): sparse pattern, leading zero count, popcount. constexpr unsigned _BitInt(128) bi128_pattern = 0x123456789ABCDEF0ULL; static_assert(__builtin_stdc_count_ones(bi128_pattern) == 32, ""); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
