[clang] 9aedb60 - [clang][Interp] Implement __builtin_popcount() (#67929)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 2 08:14:35 PDT 2023


Author: Timm Baeder
Date: 2023-10-02T17:14:31+02:00
New Revision: 9aedb60c70386c6be28e3c9b7fa5326cade25702

URL: https://github.com/llvm/llvm-project/commit/9aedb60c70386c6be28e3c9b7fa5326cade25702
DIFF: https://github.com/llvm/llvm-project/commit/9aedb60c70386c6be28e3c9b7fa5326cade25702.diff

LOG: [clang][Interp] Implement __builtin_popcount() (#67929)

Added: 
    

Modified: 
    clang/lib/AST/Interp/InterpBuiltin.cpp
    clang/test/AST/Interp/builtin-functions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp
index d816145598049b0..bba0255219bc0d7 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -398,6 +398,16 @@ static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC,
   return true;
 }
 
+static bool interp__builtin_popcount(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());
+  return true;
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
                       const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -513,6 +523,16 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
       return Ret<PT_Float>(S, OpPC, Dummy);
     break;
 
+  case Builtin::BI__builtin_popcount:
+  case Builtin::BI__builtin_popcountl:
+  case Builtin::BI__builtin_popcountll:
+  case Builtin::BI__popcnt16: // Microsoft variants of popcount
+  case Builtin::BI__popcnt:
+  case Builtin::BI__popcnt64:
+    if (interp__builtin_popcount(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 cd4ad010af12220..65361d67d68d578 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -260,3 +260,25 @@ namespace SourceLocation {
     static_assert(c.a.n == __LINE__ - 1, "");
   }
 }
+
+namespace popcount {
+  static_assert(__builtin_popcount(~0u) == __CHAR_BIT__ * sizeof(unsigned int), "");
+  static_assert(__builtin_popcount(0) == 0, "");
+  static_assert(__builtin_popcountl(~0ul) == __CHAR_BIT__ * sizeof(unsigned long), "");
+  static_assert(__builtin_popcountl(0) == 0, "");
+  static_assert(__builtin_popcountll(~0ull) == __CHAR_BIT__ * sizeof(unsigned long long), "");
+  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];
+  char popcount4[__builtin_popcount(~0L) == BITSIZE(int) ? 1 : -1];
+  char popcount5[__builtin_popcountl(0L) == 0 ? 1 : -1];
+  char popcount6[__builtin_popcountl(0xF0F0L) == 8 ? 1 : -1];
+  char popcount7[__builtin_popcountl(~0L) == BITSIZE(long) ? 1 : -1];
+  char popcount8[__builtin_popcountll(0LL) == 0 ? 1 : -1];
+  char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
+  char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
+}


        


More information about the cfe-commits mailing list