[llvm] [AArch64][CostModel] Model sve costs for ctpop (PR #192428)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 16 03:52:30 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-llvm-analysis

Author: Yashwant Singh (yashssh)

<details>
<summary>Changes</summary>

Targets supporting sve prefer sve for ctpop with fixed length vectors.
However, the cost model reports same costs for both neon and sve targets 
https://godbolt.org/z/44hYhWPhx

---
Full diff: https://github.com/llvm/llvm-project/pull/192428.diff


2 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp (+26-3) 
- (added) llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll (+97) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 734339e5c7a05..0f940191c15b4 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -807,14 +807,37 @@ AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
         {ISD::CTPOP, MVT::v4i32, 3},
         {ISD::CTPOP, MVT::v8i16, 2},
         {ISD::CTPOP, MVT::v16i8, 1},
-        {ISD::CTPOP, MVT::i64,   4},
+        {ISD::CTPOP, MVT::i64, 4},
         {ISD::CTPOP, MVT::v2i32, 3},
         {ISD::CTPOP, MVT::v4i16, 2},
-        {ISD::CTPOP, MVT::v8i8,  1},
-        {ISD::CTPOP, MVT::i32,   5},
+        {ISD::CTPOP, MVT::v8i8, 1},
+        {ISD::CTPOP, MVT::i32, 5},
+        // SVE types (For targets that override NEON for fixed length vectors)
+        {ISD::CTPOP, MVT::nxv2i64, 2},
+        {ISD::CTPOP, MVT::nxv4i32, 2},
+        {ISD::CTPOP, MVT::nxv8i16, 1},
+        {ISD::CTPOP, MVT::nxv16i8, 1},
+        {ISD::CTPOP, MVT::nxv2i32, 2},
+        {ISD::CTPOP, MVT::nxv4i16, 2},
+        {ISD::CTPOP, MVT::nxv8i8, 1},
     };
     auto LT = getTypeLegalizationCost(RetTy);
     MVT MTy = LT.second;
+
+    // When SVE is available, fixed-length vector ctpop is lowered using SVE
+    // (useSVEForFixedLengthVectorVT with OverrideNEON=true), so look up the
+    // scalable equivalent type for accurate costing.
+    if (ST->isSVEorStreamingSVEAvailable() && MTy.isFixedLengthVector()) {
+      EVT ScalableVT = MVT::getScalableVectorVT(
+          MTy.getVectorElementType(),
+          MTy.is128BitVector()
+              ? 128 / MTy.getVectorElementType().getSizeInBits()
+              : 64 / MTy.getVectorElementType().getSizeInBits());
+      if (const auto *Entry = CostTableLookup(CtpopCostTbl, ISD::CTPOP,
+                                              ScalableVT.getSimpleVT()))
+        return LT.first * Entry->Cost;
+    }
+
     if (const auto *Entry = CostTableLookup(CtpopCostTbl, ISD::CTPOP, MTy)) {
       // Extra cost of +1 when illegal vector types are legalized by promoting
       // the integer type.
diff --git a/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll b/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll
new file mode 100644
index 0000000000000..bc62baea96d5f
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll
@@ -0,0 +1,97 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; RUN: opt < %s -passes='print<cost-model>' -disable-output 2>&1 | FileCheck %s --check-prefix=NEON
+; RUN: opt < %s -passes='print<cost-model>' -disable-output -mattr=+sve 2>&1 | FileCheck %s --check-prefix=SVE
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "aarch64-unknown-linux-gnu"
+
+define <2 x i64> @test_ctpop_v2i64(<2 x i64> %a) {
+; NEON-LABEL: 'test_ctpop_v2i64'
+; NEON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
+; NEON-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <2 x i64> %ctpop
+;
+; SVE-LABEL: 'test_ctpop_v2i64'
+; SVE-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
+; SVE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <2 x i64> %ctpop
+;
+  %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
+  ret <2 x i64> %ctpop
+}
+
+define <4 x i32> @test_ctpop_v4i32(<4 x i32> %a) {
+; NEON-LABEL: 'test_ctpop_v4i32'
+; NEON-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %ctpop = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
+; NEON-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <4 x i32> %ctpop
+;
+; SVE-LABEL: 'test_ctpop_v4i32'
+; SVE-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %ctpop = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
+; SVE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <4 x i32> %ctpop
+;
+  %ctpop = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
+  ret <4 x i32> %ctpop
+}
+
+define <8 x i16> @test_ctpop_v8i16(<8 x i16> %a) {
+; NEON-LABEL: 'test_ctpop_v8i16'
+; NEON-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %ctpop = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
+; NEON-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <8 x i16> %ctpop
+;
+; SVE-LABEL: 'test_ctpop_v8i16'
+; SVE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %ctpop = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
+; SVE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <8 x i16> %ctpop
+;
+  %ctpop = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
+  ret <8 x i16> %ctpop
+}
+
+define <16 x i8> @test_ctpop_v16i8(<16 x i8> %a) {
+; NEON-LABEL: 'test_ctpop_v16i8'
+; NEON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %ctpop = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %a)
+; NEON-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <16 x i8> %ctpop
+;
+; SVE-LABEL: 'test_ctpop_v16i8'
+; SVE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %ctpop = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %a)
+; SVE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <16 x i8> %ctpop
+;
+  %ctpop = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %a)
+  ret <16 x i8> %ctpop
+}
+
+define <2 x i32> @test_ctpop_v2i32(<2 x i32> %a) {
+; NEON-LABEL: 'test_ctpop_v2i32'
+; NEON-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %ctpop = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a)
+; NEON-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <2 x i32> %ctpop
+;
+; SVE-LABEL: 'test_ctpop_v2i32'
+; SVE-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %ctpop = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a)
+; SVE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <2 x i32> %ctpop
+;
+  %ctpop = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a)
+  ret <2 x i32> %ctpop
+}
+
+define <4 x i16> @test_ctpop_v4i16(<4 x i16> %a) {
+; NEON-LABEL: 'test_ctpop_v4i16'
+; NEON-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %ctpop = call <4 x i16> @llvm.ctpop.v4i16(<4 x i16> %a)
+; NEON-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <4 x i16> %ctpop
+;
+; SVE-LABEL: 'test_ctpop_v4i16'
+; SVE-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %ctpop = call <4 x i16> @llvm.ctpop.v4i16(<4 x i16> %a)
+; SVE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <4 x i16> %ctpop
+;
+  %ctpop = call <4 x i16> @llvm.ctpop.v4i16(<4 x i16> %a)
+  ret <4 x i16> %ctpop
+}
+
+define <8 x i8> @test_ctpop_v8i8(<8 x i8> %a) {
+; NEON-LABEL: 'test_ctpop_v8i8'
+; NEON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %ctpop = call <8 x i8> @llvm.ctpop.v8i8(<8 x i8> %a)
+; NEON-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <8 x i8> %ctpop
+;
+; SVE-LABEL: 'test_ctpop_v8i8'
+; SVE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: %ctpop = call <8 x i8> @llvm.ctpop.v8i8(<8 x i8> %a)
+; SVE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret <8 x i8> %ctpop
+;
+  %ctpop = call <8 x i8> @llvm.ctpop.v8i8(<8 x i8> %a)
+  ret <8 x i8> %ctpop
+}

``````````

</details>


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


More information about the llvm-commits mailing list