Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ elementwise to the input.
Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = ±infinity

The integer elementwise intrinsics, including ``__builtin_elementwise_popcount``,
can be called in a ``constexpr`` context.
``__builtin_elementwise_bitreverse``, can be called in a ``constexpr`` context.

============================================== ====================================================================== =========================================
Name Operation Supported element types
Expand Down
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ Non-comprehensive list of changes in this release
- ``__builtin_reduce_and`` function can now be used in constant expressions.
- ``__builtin_reduce_or`` and ``__builtin_reduce_xor`` functions can now be used in constant expressions.
- ``__builtin_elementwise_popcount`` function can now be used in constant expressions.
- ``__builtin_elementwise_bitreverse`` function can now be used in constant expressions.

New Compiler Flags
------------------
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,7 @@ def ElementwiseATan2 : Builtin {

def ElementwiseBitreverse : Builtin {
let Spellings = ["__builtin_elementwise_bitreverse"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}

Expand Down
22 changes: 17 additions & 5 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11310,7 +11310,8 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
switch (E->getBuiltinCallee()) {
default:
return false;
case Builtin::BI__builtin_elementwise_popcount: {
case Builtin::BI__builtin_elementwise_popcount:
case Builtin::BI__builtin_elementwise_bitreverse: {
APValue Source;
if (!EvaluateAsRValue(Info, E->getArg(0), Source))
return false;
Expand All @@ -11322,9 +11323,19 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {

for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
APSInt Elt = Source.getVectorElt(EltNum).getInt();
ResultElements.push_back(
APValue(APSInt(APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
DestEltTy->isUnsignedIntegerOrEnumerationType())));
switch (E->getBuiltinCallee()) {
case Builtin::BI__builtin_elementwise_popcount:
ResultElements.push_back(APValue(
APSInt(APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
DestEltTy->isUnsignedIntegerOrEnumerationType())));
break;
case Builtin::BI__builtin_elementwise_bitreverse:
ResultElements.push_back(
APValue(APSInt(Elt.reverseBits(),
DestEltTy->isUnsignedIntegerOrEnumerationType())
.extOrTrunc(Info.Ctx.getIntWidth(DestEltTy))));
break;
}
}

return Success(APValue(ResultElements.data(), ResultElements.size()), E);
Expand Down Expand Up @@ -12833,7 +12844,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
case Builtin::BI__builtin_bitreverse8:
case Builtin::BI__builtin_bitreverse16:
case Builtin::BI__builtin_bitreverse32:
case Builtin::BI__builtin_bitreverse64: {
case Builtin::BI__builtin_bitreverse64:
case Builtin::BI__builtin_elementwise_bitreverse: {
APSInt Val;
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGen/builtins-elementwise-math.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ void test_builtin_elementwise_bitreverse(si8 vi1, si8 vi2,
// CHECK-NEXT: call i32 @llvm.bitreverse.i32(i32 [[IA1]])
b = __builtin_elementwise_bitreverse(int_as_one);

// CHECK: call i32 @llvm.bitreverse.i32(i32 -10)
// CHECK: store i32 1879048191, ptr @b, align 4
b = __builtin_elementwise_bitreverse(-10);

// CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2
Expand Down
5 changes: 5 additions & 0 deletions clang/test/Sema/constant_builtins_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -817,3 +817,8 @@ static_assert(__builtin_elementwise_popcount(~0U) == 8 * sizeof(int));
static_assert(__builtin_elementwise_popcount(0L) == 0);
static_assert(__builtin_elementwise_popcount(0xF0F0L) == 8);
static_assert(__builtin_elementwise_popcount(~0LL) == 8 * sizeof(long long));

static_assert(__builtin_elementwise_bitreverse(0x12345678) == 0x1E6A2C48);
static_assert(__builtin_elementwise_bitreverse(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480);
static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_bitreverse((vector4char){1, 2, 4, 8})) == (LITTLE_END ? 0x10204080 : 0x80402010));
static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_bitreverse((vector4short){1, 2, 4, 8})) == (LITTLE_END ? 0x1000200040008000 : 0x8000400020001000));