[llvm] [RISCV] Add helper functions to detect CLZ/CTZ/CPOP-like support. (PR #158148)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 11 13:21:40 PDT 2025
https://github.com/topperc created https://github.com/llvm/llvm-project/pull/158148
None
>From b4024b5751077705debc87d3abe8b10164d4d5d8 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 11 Sep 2025 13:20:18 -0700
Subject: [PATCH] [RISCV] Add helper functions to detect CLZ/CTZ/CPOP-like
support.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 16 ++++++++--------
llvm/lib/Target/RISCV/RISCVSubtarget.h | 11 +++++++++++
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 037eec05e4301..4f137756d2f48 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -403,12 +403,14 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
Legal);
}
- if (Subtarget.hasStdExtZbb() ||
- (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit())) {
+ if (Subtarget.hasCTZLike()) {
if (Subtarget.is64Bit())
setOperationAction({ISD::CTTZ, ISD::CTTZ_ZERO_UNDEF}, MVT::i32, Custom);
} else {
setOperationAction(ISD::CTTZ, XLenVT, Expand);
+ }
+
+ if (!Subtarget.hasCPOPLike()) {
// TODO: These should be set to LibCall, but this currently breaks
// the Linux kernel build. See #101786. Lacks i128 tests, too.
if (Subtarget.is64Bit())
@@ -418,8 +420,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::CTPOP, MVT::i64, Expand);
}
- if (Subtarget.hasStdExtZbb() || Subtarget.hasVendorXTHeadBb() ||
- (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit())) {
+ if (Subtarget.hasCLZLike()) {
// We need the custom lowering to make sure that the resulting sequence
// for the 32bit case is efficient on 64bit targets.
// Use default promotion for i32 without Zbb.
@@ -2158,13 +2159,11 @@ bool RISCVTargetLowering::signExtendConstant(const ConstantInt *CI) const {
}
bool RISCVTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
- return Subtarget.hasStdExtZbb() ||
- (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit());
+ return Subtarget.hasCTZLike();
}
bool RISCVTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {
- return Subtarget.hasStdExtZbb() || Subtarget.hasVendorXTHeadBb() ||
- (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit());
+ return Subtarget.hasCLZLike();
}
bool RISCVTargetLowering::isMaskAndCmp0FoldingBeneficial(
@@ -24843,6 +24842,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() &&
(VT == MVT::i32 || VT == MVT::i64 || VT.isFixedLengthVector());
}
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index 50e76df56e575..0d9cd16a77937 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -186,6 +186,17 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
return HasStdExtZfhmin || HasStdExtZfbfmin;
}
+ bool hasCLZLike() const {
+ return HasStdExtZbb || HasVendorXTHeadBb ||
+ (HasVendorXCVbitmanip && !IsRV64);
+ }
+ bool hasCTZLike() const {
+ return HasStdExtZbb || (HasVendorXCVbitmanip && !IsRV64);
+ }
+ bool hasCPOPLike() const {
+ return HasStdExtZbb || (HasVendorXCVbitmanip && !IsRV64);
+ }
+
bool hasBEXTILike() const { return HasStdExtZbs || HasVendorXTHeadBs; }
bool hasCZEROLike() const {
More information about the llvm-commits
mailing list