[llvm] [RISCV] Use hasCPOPLike in isCtpopFast and getPopcntSupport (PR #158371)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 12 14:42:24 PDT 2025


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/158371

None

>From 07cdaa6939c476edbc0d451677819395c0b9f82a Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 12 Sep 2025 14:24:12 -0700
Subject: [PATCH 1/3] [RISCV] Use hasCPOPLike in getPopcntSupport.

---
 llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
index 1ca513214f67c..a06faa414a2ef 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
@@ -289,9 +289,7 @@ bool RISCVTTIImpl::hasActiveVectorLength() const {
 TargetTransformInfo::PopcntSupportKind
 RISCVTTIImpl::getPopcntSupport(unsigned TyWidth) const {
   assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
-  return ST->hasStdExtZbb() || (ST->hasVendorXCVbitmanip() && !ST->is64Bit())
-             ? TTI::PSK_FastHardware
-             : TTI::PSK_Software;
+  return ST->hasCPOPLike() ? TTI::PSK_FastHardware : TTI::PSK_Software;
 }
 
 InstructionCost RISCVTTIImpl::getPartialReductionCost(

>From 9342cc5943a44a0890f617d9608ed87d9d673ff2 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 12 Sep 2025 14:34:41 -0700
Subject: [PATCH 2/3] Pre-commit test

---
 llvm/test/CodeGen/RISCV/xcvbitmanip.ll | 66 ++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/xcvbitmanip.ll b/llvm/test/CodeGen/RISCV/xcvbitmanip.ll
index d25ff28475c4b..4dd6c4285bded 100644
--- a/llvm/test/CodeGen/RISCV/xcvbitmanip.ll
+++ b/llvm/test/CodeGen/RISCV/xcvbitmanip.ll
@@ -229,3 +229,69 @@ define i32 @test.llvm.bitrev(i32 %a) {
   %1 = call i32 @llvm.bitreverse(i32 %a)
   ret i32 %1
 }
+
+define i1 @ctpop_i32_ult_two(i32 signext %a) nounwind {
+; CHECK-LABEL: ctpop_i32_ult_two:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    addi a1, a0, -1
+; CHECK-NEXT:    and a0, a0, a1
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.ctpop.i32(i32 %a)
+  %2 = icmp ult i32 %1, 2
+  ret i1 %2
+}
+
+define i1 @ctpop_i32_ugt_one(i32 signext %a) nounwind {
+; CHECK-LABEL: ctpop_i32_ugt_one:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    addi a1, a0, -1
+; CHECK-NEXT:    and a0, a0, a1
+; CHECK-NEXT:    snez a0, a0
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.ctpop.i32(i32 %a)
+  %2 = icmp ugt i32 %1, 1
+  ret i1 %2
+}
+
+define i1 @ctpop_i32_eq_one(i32 signext %a) nounwind {
+; CHECK-O0-LABEL: ctpop_i32_eq_one:
+; CHECK-O0:       # %bb.0:
+; CHECK-O0-NEXT:    mv a1, a0
+; CHECK-O0-NEXT:    addi a0, a1, -1
+; CHECK-O0-NEXT:    xor a1, a1, a0
+; CHECK-O0-NEXT:    sltu a0, a0, a1
+; CHECK-O0-NEXT:    ret
+;
+; CHECK-O3-LABEL: ctpop_i32_eq_one:
+; CHECK-O3:       # %bb.0:
+; CHECK-O3-NEXT:    addi a1, a0, -1
+; CHECK-O3-NEXT:    xor a0, a0, a1
+; CHECK-O3-NEXT:    sltu a0, a1, a0
+; CHECK-O3-NEXT:    ret
+  %1 = call i32 @llvm.ctpop.i32(i32 %a)
+  %2 = icmp eq i32 %1, 1
+  ret i1 %2
+}
+
+define i1 @ctpop_i32_ne_one(i32 signext %a) nounwind {
+; CHECK-O0-LABEL: ctpop_i32_ne_one:
+; CHECK-O0:       # %bb.0:
+; CHECK-O0-NEXT:    mv a1, a0
+; CHECK-O0-NEXT:    addi a0, a1, -1
+; CHECK-O0-NEXT:    xor a1, a1, a0
+; CHECK-O0-NEXT:    sltu a0, a0, a1
+; CHECK-O0-NEXT:    xori a0, a0, 1
+; CHECK-O0-NEXT:    ret
+;
+; CHECK-O3-LABEL: ctpop_i32_ne_one:
+; CHECK-O3:       # %bb.0:
+; CHECK-O3-NEXT:    addi a1, a0, -1
+; CHECK-O3-NEXT:    xor a0, a0, a1
+; CHECK-O3-NEXT:    sltu a0, a1, a0
+; CHECK-O3-NEXT:    xori a0, a0, 1
+; CHECK-O3-NEXT:    ret
+  %1 = call i32 @llvm.ctpop.i32(i32 %a)
+  %2 = icmp ne i32 %1, 1
+  ret i1 %2
+}

>From d827b00ab47dca173a7fc001add75f3a5497e230 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 12 Sep 2025 14:36:55 -0700
Subject: [PATCH 3/3] [RISCV] Use hasCPOPLike in isCtpopFast

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  3 +-
 llvm/test/CodeGen/RISCV/xcvbitmanip.ll      | 53 +++++++--------------
 2 files changed, 18 insertions(+), 38 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 523b857f9e6cd..e131c4098c2ba 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -24844,8 +24844,7 @@ bool RISCVTargetLowering::isCtpopFast(EVT VT) const {
     return isTypeLegal(VT) && Subtarget.hasStdExtZvbb();
   if (VT.isFixedLengthVector() && Subtarget.hasStdExtZvbb())
     return true;
-  // FIXME: Should use hasCPOPLike here.
-  return Subtarget.hasStdExtZbb() &&
+  return Subtarget.hasCPOPLike() &&
          (VT == MVT::i32 || VT == MVT::i64 || VT.isFixedLengthVector());
 }
 
diff --git a/llvm/test/CodeGen/RISCV/xcvbitmanip.ll b/llvm/test/CodeGen/RISCV/xcvbitmanip.ll
index 4dd6c4285bded..b2cebabb7df8b 100644
--- a/llvm/test/CodeGen/RISCV/xcvbitmanip.ll
+++ b/llvm/test/CodeGen/RISCV/xcvbitmanip.ll
@@ -233,9 +233,8 @@ define i32 @test.llvm.bitrev(i32 %a) {
 define i1 @ctpop_i32_ult_two(i32 signext %a) nounwind {
 ; CHECK-LABEL: ctpop_i32_ult_two:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addi a1, a0, -1
-; CHECK-NEXT:    and a0, a0, a1
-; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    cv.cnt a0, a0
+; CHECK-NEXT:    sltiu a0, a0, 2
 ; CHECK-NEXT:    ret
   %1 = call i32 @llvm.ctpop.i32(i32 %a)
   %2 = icmp ult i32 %1, 2
@@ -245,9 +244,9 @@ define i1 @ctpop_i32_ult_two(i32 signext %a) nounwind {
 define i1 @ctpop_i32_ugt_one(i32 signext %a) nounwind {
 ; CHECK-LABEL: ctpop_i32_ugt_one:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addi a1, a0, -1
-; CHECK-NEXT:    and a0, a0, a1
-; CHECK-NEXT:    snez a0, a0
+; CHECK-NEXT:    cv.cnt a0, a0
+; CHECK-NEXT:    sltiu a0, a0, 2
+; CHECK-NEXT:    xori a0, a0, 1
 ; CHECK-NEXT:    ret
   %1 = call i32 @llvm.ctpop.i32(i32 %a)
   %2 = icmp ugt i32 %1, 1
@@ -255,42 +254,24 @@ define i1 @ctpop_i32_ugt_one(i32 signext %a) nounwind {
 }
 
 define i1 @ctpop_i32_eq_one(i32 signext %a) nounwind {
-; CHECK-O0-LABEL: ctpop_i32_eq_one:
-; CHECK-O0:       # %bb.0:
-; CHECK-O0-NEXT:    mv a1, a0
-; CHECK-O0-NEXT:    addi a0, a1, -1
-; CHECK-O0-NEXT:    xor a1, a1, a0
-; CHECK-O0-NEXT:    sltu a0, a0, a1
-; CHECK-O0-NEXT:    ret
-;
-; CHECK-O3-LABEL: ctpop_i32_eq_one:
-; CHECK-O3:       # %bb.0:
-; CHECK-O3-NEXT:    addi a1, a0, -1
-; CHECK-O3-NEXT:    xor a0, a0, a1
-; CHECK-O3-NEXT:    sltu a0, a1, a0
-; CHECK-O3-NEXT:    ret
+; CHECK-LABEL: ctpop_i32_eq_one:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.cnt a0, a0
+; CHECK-NEXT:    addi a0, a0, -1
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    ret
   %1 = call i32 @llvm.ctpop.i32(i32 %a)
   %2 = icmp eq i32 %1, 1
   ret i1 %2
 }
 
 define i1 @ctpop_i32_ne_one(i32 signext %a) nounwind {
-; CHECK-O0-LABEL: ctpop_i32_ne_one:
-; CHECK-O0:       # %bb.0:
-; CHECK-O0-NEXT:    mv a1, a0
-; CHECK-O0-NEXT:    addi a0, a1, -1
-; CHECK-O0-NEXT:    xor a1, a1, a0
-; CHECK-O0-NEXT:    sltu a0, a0, a1
-; CHECK-O0-NEXT:    xori a0, a0, 1
-; CHECK-O0-NEXT:    ret
-;
-; CHECK-O3-LABEL: ctpop_i32_ne_one:
-; CHECK-O3:       # %bb.0:
-; CHECK-O3-NEXT:    addi a1, a0, -1
-; CHECK-O3-NEXT:    xor a0, a0, a1
-; CHECK-O3-NEXT:    sltu a0, a1, a0
-; CHECK-O3-NEXT:    xori a0, a0, 1
-; CHECK-O3-NEXT:    ret
+; CHECK-LABEL: ctpop_i32_ne_one:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.cnt a0, a0
+; CHECK-NEXT:    addi a0, a0, -1
+; CHECK-NEXT:    snez a0, a0
+; CHECK-NEXT:    ret
   %1 = call i32 @llvm.ctpop.i32(i32 %a)
   %2 = icmp ne i32 %1, 1
   ret i1 %2



More information about the llvm-commits mailing list