[llvm] [AArch64][SVE] Implement demanded bits for @llvm.aarch64.sve.cntp (PR #168714)

Paul Walker via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 19 08:49:26 PST 2025


================
@@ -19443,22 +19443,53 @@ AArch64TargetLowering::BuildSREMPow2(SDNode *N, const APInt &Divisor,
   return CSNeg;
 }
 
-static std::optional<unsigned> IsSVECntIntrinsic(SDValue S) {
+static bool IsSVECntIntrinsic(SDValue S) {
   switch(getIntrinsicID(S.getNode())) {
   default:
     break;
   case Intrinsic::aarch64_sve_cntb:
-    return 8;
   case Intrinsic::aarch64_sve_cnth:
-    return 16;
   case Intrinsic::aarch64_sve_cntw:
-    return 32;
   case Intrinsic::aarch64_sve_cntd:
-    return 64;
+  case Intrinsic::aarch64_sve_cntp:
+    return true;
   }
   return {};
 }
 
+// Creates a constexpr (IID, VT) pair that can be used in switch cases.
+static constexpr uint64_t intrinsicWithType(Intrinsic::ID IID, MVT VT) {
+  static_assert(sizeof(VT.SimpleTy) <= sizeof(uint32_t) &&
+                    sizeof(IID) <= sizeof(uint32_t),
+                "IID and MVT should fit in 64 bits");
+  return (uint64_t(IID) << 32) | uint64_t(VT.SimpleTy);
+}
+
+// Returns the maximum (scalable) value that can be returned by an SVE count
+// intrinsic. The supported intrinsics are covered by IsSVECntIntrinsic.
+static ElementCount getMaxValueForSVECntIntrinsic(SDValue Op) {
+  Intrinsic::ID IID = getIntrinsicID(Op.getNode());
+  MVT VT = IID == Intrinsic::aarch64_sve_cntp
+               ? Op.getOperand(1).getValueType().getSimpleVT()
+               : MVT::Untyped;
+  switch (intrinsicWithType(IID, VT)) {
+  case intrinsicWithType(Intrinsic::aarch64_sve_cntd, MVT::Untyped):
+  case intrinsicWithType(Intrinsic::aarch64_sve_cntp, MVT::nxv2i1):
+    return ElementCount::getScalable(2);
+  case intrinsicWithType(Intrinsic::aarch64_sve_cntw, MVT::Untyped):
+  case intrinsicWithType(Intrinsic::aarch64_sve_cntp, MVT::nxv4i1):
+    return ElementCount::getScalable(4);
+  case intrinsicWithType(Intrinsic::aarch64_sve_cnth, MVT::Untyped):
+  case intrinsicWithType(Intrinsic::aarch64_sve_cntp, MVT::nxv8i1):
+    return ElementCount::getScalable(8);
+  case intrinsicWithType(Intrinsic::aarch64_sve_cntb, MVT::Untyped):
+  case intrinsicWithType(Intrinsic::aarch64_sve_cntp, MVT::nxv16i1):
+    return ElementCount::getScalable(16);
+  default:
+    llvm_unreachable("unexpected intrininc type pair");
+  }
+}
----------------
paulwalker-arm wrote:

+1 for ingenuity but perhaps?
```
if (IID == Intrinsic::aarch64_sve_cntp)
  return Op.getOperand(1).getValueType().getVectorElementCount();

switch (IID) {
case intrinsicWithType(Intrinsic::aarch64_sve_cntd:
  return ElementCount::getScalable(2);
....
}
```

https://github.com/llvm/llvm-project/pull/168714


More information about the llvm-commits mailing list