Skip to content

Commit e41f7be

Browse files
committed
[clang] Implement __builtin_popcountg
Fixes #82058.
1 parent ae3e142 commit e41f7be

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,12 @@ def Popcount : Builtin, BitInt_Long_LongLongTemplate {
688688
let Prototype = "int(unsigned T)";
689689
}
690690

691+
def Popcountg : Builtin {
692+
let Spellings = ["__builtin_popcountg"];
693+
let Attributes = [NoThrow, Const, Constexpr];
694+
let Prototype = "int(...)";
695+
}
696+
691697
def Clrsb : Builtin, BitInt_Long_LongLongTemplate {
692698
let Spellings = ["__builtin_clrsb"];
693699
let Attributes = [NoThrow, Const, Constexpr];

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3216,7 +3216,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
32163216
case Builtin::BI__popcnt64:
32173217
case Builtin::BI__builtin_popcount:
32183218
case Builtin::BI__builtin_popcountl:
3219-
case Builtin::BI__builtin_popcountll: {
3219+
case Builtin::BI__builtin_popcountll:
3220+
case Builtin::BI__builtin_popcountg: {
3221+
if (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_popcountg) {
3222+
assert(E->getNumArgs() == 1 && "__builtin_popcountg takes 1 argument");
3223+
}
3224+
32203225
Value *ArgValue = EmitScalarExpr(E->getArg(0));
32213226

32223227
llvm::Type *ArgType = ArgValue->getType();

clang/test/CodeGen/builtins.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,4 +940,47 @@ void test_builtin_os_log_long_double(void *buf, long double ld) {
940940
// CHECK: %[[V3:.*]] = load i128, ptr %[[ARG0_ADDR]], align 16
941941
// CHECK: store i128 %[[V3]], ptr %[[ARGDATA]], align 1
942942

943+
// CHECK-LABEL: define{{.*}} void @test_builtin_popcountg
944+
void test_builtin_popcountg(unsigned char uc, unsigned short us,
945+
unsigned int ui, unsigned long ul,
946+
unsigned long long ull, unsigned __int128 ui128,
947+
unsigned _BitInt(128) ubi128) {
948+
volatile int pop;
949+
pop = __builtin_popcountg(uc);
950+
// CHECK: %1 = load i8, ptr %uc.addr, align 1
951+
// CHECK-NEXT: %conv = zext i8 %1 to i32
952+
// CHECK-NEXT: %2 = call i32 @llvm.ctpop.i32(i32 %conv)
953+
// CHECK-NEXT: store volatile i32 %2, ptr %pop, align 4
954+
pop = __builtin_popcountg(us);
955+
// CHECK-NEXT: %3 = load i16, ptr %us.addr, align 2
956+
// CHECK-NEXT: %conv1 = zext i16 %3 to i32
957+
// CHECK-NEXT: %4 = call i32 @llvm.ctpop.i32(i32 %conv1)
958+
// CHECK-NEXT: store volatile i32 %4, ptr %pop, align 4
959+
pop = __builtin_popcountg(ui);
960+
// CHECK-NEXT: %5 = load i32, ptr %ui.addr, align 4
961+
// CHECK-NEXT: %6 = call i32 @llvm.ctpop.i32(i32 %5)
962+
// CHECK-NEXT: store volatile i32 %6, ptr %pop, align 4
963+
pop = __builtin_popcountg(ul);
964+
// CHECK-NEXT: %7 = load i64, ptr %ul.addr, align 8
965+
// CHECK-NEXT: %8 = call i64 @llvm.ctpop.i64(i64 %7)
966+
// CHECK-NEXT: %cast = trunc i64 %8 to i32
967+
// CHECK-NEXT: store volatile i32 %cast, ptr %pop, align 4
968+
pop = __builtin_popcountg(ull);
969+
// CHECK-NEXT: %9 = load i64, ptr %ull.addr, align 8
970+
// CHECK-NEXT: %10 = call i64 @llvm.ctpop.i64(i64 %9)
971+
// CHECK-NEXT: %cast2 = trunc i64 %10 to i32
972+
// CHECK-NEXT: store volatile i32 %cast2, ptr %pop, align 4
973+
pop = __builtin_popcountg(ui128);
974+
// CHECK-NEXT: %11 = load i128, ptr %ui128.addr, align 16
975+
// CHECK-NEXT: %12 = call i128 @llvm.ctpop.i128(i128 %11)
976+
// CHECK-NEXT: %cast3 = trunc i128 %12 to i32
977+
// CHECK-NEXT: store volatile i32 %cast3, ptr %pop, align 4
978+
pop = __builtin_popcountg(ubi128);
979+
// CHECK-NEXT: %13 = load i128, ptr %ubi128.addr, align 8
980+
// CHECK-NEXT: %14 = call i128 @llvm.ctpop.i128(i128 %13)
981+
// CHECK-NEXT: %cast4 = trunc i128 %14 to i32
982+
// CHECK-NEXT: store volatile i32 %cast4, ptr %pop, align 4
983+
// CHECK-NEXT: ret void
984+
}
985+
943986
#endif

0 commit comments

Comments
 (0)