Skip to content

Commit d26791b

Browse files
authored
[Clang][RISCV] Use __builtin_popcount in __riscv_cpop_32/64 (#76286)
This patch replaces `__builtin_riscv_cpop_32/64` with `__builtin_popcount(ll)` because `__builtin_riscv_cpop_32/64` is not implemented in clang.
1 parent e060392 commit d26791b

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

clang/lib/Headers/riscv_bitmanip.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ __riscv_ctz_32(uint32_t __x) {
3434

3535
static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
3636
__riscv_cpop_32(uint32_t __x) {
37-
return __builtin_riscv_cpop_32(__x);
37+
return __builtin_popcount(__x);
3838
}
3939

4040
#if __riscv_xlen == 64
@@ -55,7 +55,7 @@ __riscv_ctz_64(uint64_t __x) {
5555

5656
static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
5757
__riscv_cpop_64(uint64_t __x) {
58-
return __builtin_riscv_cpop_64(__x);
58+
return __builtin_popcountll(__x);
5959
}
6060
#endif
6161
#endif // defined(__riscv_zbb)

clang/test/CodeGen/RISCV/rvb-intrinsics/zbb.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ unsigned int clz_32(uint32_t a) {
5151
// RV64ZBB-LABEL: @clz_64(
5252
// RV64ZBB-NEXT: entry:
5353
// RV64ZBB-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[A:%.*]], i1 false)
54-
// RV64ZBB-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
55-
// RV64ZBB-NEXT: ret i32 [[CAST]]
54+
// RV64ZBB-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32
55+
// RV64ZBB-NEXT: ret i32 [[CAST_I]]
5656
//
5757
unsigned int clz_64(uint64_t a) {
5858
return __riscv_clz_64(a);
@@ -77,10 +77,36 @@ unsigned int ctz_32(uint32_t a) {
7777
// RV64ZBB-LABEL: @ctz_64(
7878
// RV64ZBB-NEXT: entry:
7979
// RV64ZBB-NEXT: [[TMP0:%.*]] = call i64 @llvm.cttz.i64(i64 [[A:%.*]], i1 false)
80-
// RV64ZBB-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
81-
// RV64ZBB-NEXT: ret i32 [[CAST]]
80+
// RV64ZBB-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32
81+
// RV64ZBB-NEXT: ret i32 [[CAST_I]]
8282
//
8383
unsigned int ctz_64(uint64_t a) {
8484
return __riscv_ctz_64(a);
8585
}
8686
#endif
87+
88+
// RV32ZBB-LABEL: @cpop_32(
89+
// RV32ZBB-NEXT: entry:
90+
// RV32ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]])
91+
// RV32ZBB-NEXT: ret i32 [[TMP0]]
92+
//
93+
// RV64ZBB-LABEL: @cpop_32(
94+
// RV64ZBB-NEXT: entry:
95+
// RV64ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]])
96+
// RV64ZBB-NEXT: ret i32 [[TMP0]]
97+
//
98+
unsigned int cpop_32(uint32_t a) {
99+
return __riscv_cpop_32(a);
100+
}
101+
102+
#if __riscv_xlen == 64
103+
// RV64ZBB-LABEL: @cpop_64(
104+
// RV64ZBB-NEXT: entry:
105+
// RV64ZBB-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
106+
// RV64ZBB-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32
107+
// RV64ZBB-NEXT: ret i32 [[CAST_I]]
108+
//
109+
unsigned int cpop_64(uint64_t a) {
110+
return __riscv_cpop_64(a);
111+
}
112+
#endif

0 commit comments

Comments
 (0)