Skip to content

Commit 95f2b6b

Browse files
committed
constexpr elementwise popcount
1 parent c85c77c commit 95f2b6b

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ Non-comprehensive list of changes in this release
370370
- ``__builtin_reduce_mul`` function can now be used in constant expressions.
371371
- ``__builtin_reduce_and`` function can now be used in constant expressions.
372372
- ``__builtin_reduce_or`` and ``__builtin_reduce_xor`` functions can now be used in constant expressions.
373+
- ``__builtin_elementwise_popcount`` function can now be used in constant expressions.
373374

374375
New Compiler Flags
375376
------------------

clang/include/clang/Basic/Builtins.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ def ElementwiseLog10 : Builtin {
13541354

13551355
def ElementwisePopcount : Builtin {
13561356
let Spellings = ["__builtin_elementwise_popcount"];
1357-
let Attributes = [NoThrow, Const, CustomTypeChecking];
1357+
let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
13581358
let Prototype = "void(...)";
13591359
}
13601360

clang/lib/AST/ExprConstant.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11005,6 +11005,7 @@ namespace {
1100511005
bool VisitUnaryImag(const UnaryOperator *E);
1100611006
bool VisitBinaryOperator(const BinaryOperator *E);
1100711007
bool VisitUnaryOperator(const UnaryOperator *E);
11008+
bool VisitCallExpr(const CallExpr *E);
1100811009
bool VisitConvertVectorExpr(const ConvertVectorExpr *E);
1100911010
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E);
1101011011

@@ -11302,6 +11303,32 @@ static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO,
1130211303
return false;
1130311304
}
1130411305

11306+
bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
11307+
switch (E->getBuiltinCallee()) {
11308+
default:
11309+
return false;
11310+
case Builtin::BI__builtin_elementwise_popcount: {
11311+
APValue Source;
11312+
if (!EvaluateAsRValue(Info, E->getArg(0), Source))
11313+
return false;
11314+
11315+
QualType DestTy = E->getType()->castAs<VectorType>()->getElementType();
11316+
unsigned SourceLen = Source.getVectorLength();
11317+
SmallVector<APValue, 4> ResultElements;
11318+
ResultElements.reserve(SourceLen);
11319+
11320+
for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11321+
APSInt Elt = Source.getVectorElt(EltNum).getInt();
11322+
ResultElements.push_back(
11323+
APValue(APSInt(APInt(Info.Ctx.getIntWidth(DestTy), Elt.popcount()),
11324+
DestTy->isUnsignedIntegerOrEnumerationType())));
11325+
}
11326+
11327+
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11328+
}
11329+
}
11330+
}
11331+
1130511332
bool VectorExprEvaluator::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
1130611333
APValue Source;
1130711334
QualType SourceVecType = E->getSrcExpr()->getType();

clang/test/Sema/constant_builtins_vector.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,3 +797,8 @@ static_assert(__builtin_reduce_xor((vector4int){(int)0x11111111, (int)0x22222222
797797
static_assert(__builtin_reduce_xor((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0xFFFFFFFFFFFFFFFFL);
798798
static_assert(__builtin_reduce_xor((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0xFFFFFFFFU);
799799
static_assert(__builtin_reduce_xor((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0xFFFFFFFFFFFFFFFFUL);
800+
801+
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){1, 2, 3, 4})) == 5);
802+
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){0, 0xF0F0, ~0, ~0xF0F0})) == 16 * sizeof(int));
803+
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){1L, 2L, 3L, 4L})) == 5L);
804+
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){0L, 0xF0F0L, ~0L, ~0xF0F0L})) == 16 * sizeof(long long));

0 commit comments

Comments
 (0)