Skip to content

Commit 9aedb60

Browse files
authored
[clang][Interp] Implement __builtin_popcount() (#67929)
1 parent b4f5913 commit 9aedb60

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

clang/lib/AST/Interp/InterpBuiltin.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,16 @@ static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC,
398398
return true;
399399
}
400400

401+
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC,
402+
const InterpFrame *Frame,
403+
const Function *Func,
404+
const CallExpr *Call) {
405+
PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
406+
APSInt Val = peekToAPSInt(S.Stk, ArgT);
407+
pushInt(S, Val.popcount());
408+
return true;
409+
}
410+
401411
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
402412
const CallExpr *Call) {
403413
InterpFrame *Frame = S.Current;
@@ -513,6 +523,16 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
513523
return Ret<PT_Float>(S, OpPC, Dummy);
514524
break;
515525

526+
case Builtin::BI__builtin_popcount:
527+
case Builtin::BI__builtin_popcountl:
528+
case Builtin::BI__builtin_popcountll:
529+
case Builtin::BI__popcnt16: // Microsoft variants of popcount
530+
case Builtin::BI__popcnt:
531+
case Builtin::BI__popcnt64:
532+
if (interp__builtin_popcount(S, OpPC, Frame, F, Call))
533+
return retInt(S, OpPC, Dummy);
534+
break;
535+
516536
default:
517537
return false;
518538
}

clang/test/AST/Interp/builtin-functions.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,25 @@ namespace SourceLocation {
260260
static_assert(c.a.n == __LINE__ - 1, "");
261261
}
262262
}
263+
264+
namespace popcount {
265+
static_assert(__builtin_popcount(~0u) == __CHAR_BIT__ * sizeof(unsigned int), "");
266+
static_assert(__builtin_popcount(0) == 0, "");
267+
static_assert(__builtin_popcountl(~0ul) == __CHAR_BIT__ * sizeof(unsigned long), "");
268+
static_assert(__builtin_popcountl(0) == 0, "");
269+
static_assert(__builtin_popcountll(~0ull) == __CHAR_BIT__ * sizeof(unsigned long long), "");
270+
static_assert(__builtin_popcountll(0) == 0, "");
271+
272+
/// From test/Sema/constant-builtins-2.c
273+
#define BITSIZE(x) (sizeof(x) * 8)
274+
char popcount1[__builtin_popcount(0) == 0 ? 1 : -1];
275+
char popcount2[__builtin_popcount(0xF0F0) == 8 ? 1 : -1];
276+
char popcount3[__builtin_popcount(~0) == BITSIZE(int) ? 1 : -1];
277+
char popcount4[__builtin_popcount(~0L) == BITSIZE(int) ? 1 : -1];
278+
char popcount5[__builtin_popcountl(0L) == 0 ? 1 : -1];
279+
char popcount6[__builtin_popcountl(0xF0F0L) == 8 ? 1 : -1];
280+
char popcount7[__builtin_popcountl(~0L) == BITSIZE(long) ? 1 : -1];
281+
char popcount8[__builtin_popcountll(0LL) == 0 ? 1 : -1];
282+
char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
283+
char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
284+
}

0 commit comments

Comments
 (0)