diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index f26d298f5b600..0536fe44b9dcb 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -439,6 +439,15 @@ static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, + const Function *Func, const CallExpr *Call) { + PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); + APSInt Val = peekToAPSInt(S.Stk, ArgT); + pushInt(S, Val.popcount() % 2); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -576,6 +585,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return retInt(S, OpPC, Dummy); break; + case Builtin::BI__builtin_parity: + case Builtin::BI__builtin_parityl: + case Builtin::BI__builtin_parityll: + if (interp__builtin_parity(S, OpPC, Frame, F, Call)) + return retInt(S, OpPC, Dummy); + break; + default: return false; } diff --git a/clang/test/AST/Interp/builtin-functions.cpp b/clang/test/AST/Interp/builtin-functions.cpp index a78a0fbdf11b1..14604a2b553f1 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -274,6 +274,7 @@ namespace SourceLocation { } } +#define BITSIZE(x) (sizeof(x) * 8) namespace popcount { static_assert(__builtin_popcount(~0u) == __CHAR_BIT__ * sizeof(unsigned int), ""); static_assert(__builtin_popcount(0) == 0, ""); @@ -283,7 +284,6 @@ namespace popcount { static_assert(__builtin_popcountll(0) == 0, ""); /// From test/Sema/constant-builtins-2.c -#define BITSIZE(x) (sizeof(x) * 8) char popcount1[__builtin_popcount(0) == 0 ? 1 : -1]; char popcount2[__builtin_popcount(0xF0F0) == 8 ? 1 : -1]; char popcount3[__builtin_popcount(~0) == BITSIZE(int) ? 1 : -1]; @@ -295,3 +295,18 @@ namespace popcount { char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1]; char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1]; } + +namespace parity { + /// From test/Sema/constant-builtins-2.c + char parity1[__builtin_parity(0) == 0 ? 1 : -1]; + char parity2[__builtin_parity(0xb821) == 0 ? 1 : -1]; + char parity3[__builtin_parity(0xb822) == 0 ? 1 : -1]; + char parity4[__builtin_parity(0xb823) == 1 ? 1 : -1]; + char parity5[__builtin_parity(0xb824) == 0 ? 1 : -1]; + char parity6[__builtin_parity(0xb825) == 1 ? 1 : -1]; + char parity7[__builtin_parity(0xb826) == 1 ? 1 : -1]; + char parity8[__builtin_parity(~0) == 0 ? 1 : -1]; + char parity9[__builtin_parityl(1L << (BITSIZE(long) - 1)) == 1 ? 1 : -1]; + char parity10[__builtin_parityll(1LL << (BITSIZE(long long) - 1)) == 1 ? 1 : -1]; +} +