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

Yashwant Singh via llvm-commits llvm-commits at lists.llvm.org
Mon May 4 01:06:53 PDT 2026


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

>From a8df554efcb6691e8515656ab6fa5bb10fbc9b49 Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Tue, 14 Apr 2026 23:33:37 -0700
Subject: [PATCH 1/4] [NFC]Pre commit test for ctpop sve

---
 .../CostModel/AArch64/ctpop-neon-sve.ll       | 97 +++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll

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..e309425b10e7a
--- /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 4 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 3 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 2 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 3 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
+}

>From 1bfccf9f4d4250a756269fa94afdd767c3fac1c4 Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Tue, 14 Apr 2026 23:33:51 -0700
Subject: [PATCH 2/4] [AArch64][CostModel] Model sve costs for ctpop

Targets supporting sve prefer sve for ctop intrinsics with fixed length vectors.
However, the cost model reports same costs for both neon and sve targets https://godbolt.org/z/44hYhWPhx
---
 .../AArch64/AArch64TargetTransformInfo.cpp    | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 734339e5c7a05..c19717861b40e 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -812,9 +812,32 @@ AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
         {ISD::CTPOP, MVT::v4i16, 2},
         {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.

>From 4c74fed163524ed22a6da774525941614137359f Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Wed, 15 Apr 2026 03:57:46 -0700
Subject: [PATCH 3/4] [NFC] update test

---
 llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp | 6 +++---
 llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index c19717861b40e..0f940191c15b4 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -807,11 +807,11 @@ 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},
diff --git a/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll b/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll
index e309425b10e7a..bc62baea96d5f 100644
--- a/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll
@@ -11,7 +11,7 @@ define <2 x i64> @test_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 4 for instruction: %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
+; 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)
@@ -24,7 +24,7 @@ define <4 x i32> @test_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 3 for instruction: %ctpop = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
+; 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)
@@ -37,7 +37,7 @@ define <8 x i16> @test_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 2 for instruction: %ctpop = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
+; 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)
@@ -63,7 +63,7 @@ define <2 x i32> @test_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 3 for instruction: %ctpop = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a)
+; 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)

>From 03ba3f40f79d6f29c0cdc13311445df5025d9be6 Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Mon, 4 May 2026 01:05:50 -0700
Subject: [PATCH 4/4] Address review comments

---
 .../AArch64/AArch64TargetTransformInfo.cpp    | 22 ++---
 .../CostModel/AArch64/ctpop-neon-sve.ll       | 97 -------------------
 llvm/test/Analysis/CostModel/AArch64/ctpop.ll | 81 ++++++++++++++++
 .../Analysis/CostModel/AArch64/sve-ctpop.ll   | 51 ++++++++++
 llvm/test/CodeGen/AArch64/sve-ctpop.ll        | 32 ++++++
 5 files changed, 174 insertions(+), 109 deletions(-)
 delete mode 100644 llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll
 create mode 100644 llvm/test/Analysis/CostModel/AArch64/sve-ctpop.ll
 create mode 100644 llvm/test/CodeGen/AArch64/sve-ctpop.ll

diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 0f940191c15b4..ef692f74a09bd 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -813,13 +813,11 @@ AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
         {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::nxv2i64, 1},
+        {ISD::CTPOP, MVT::nxv4i32, 1},
         {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},
+        {ISD::CTPOP, MVT::nxv2i32, 1},
+        {ISD::CTPOP, MVT::nxv4i16, 1},
     };
     auto LT = getTypeLegalizationCost(RetTy);
     MVT MTy = LT.second;
@@ -827,12 +825,12 @@ AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
     // 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());
+    // TODO: Handle type promotion case.
+    if (ST->isSVEorStreamingSVEAvailable() && MTy.isFixedLengthVector() &&
+        MTy.getScalarSizeInBits() > 8 &&
+        MTy.getScalarSizeInBits() == RetTy->getScalarSizeInBits()) {
+      EVT ScalableVT = MVT::getScalableVectorVT(MTy.getVectorElementType(),
+                                                MTy.getVectorNumElements());
       if (const auto *Entry = CostTableLookup(CtpopCostTbl, ISD::CTPOP,
                                               ScalableVT.getSimpleVT()))
         return LT.first * Entry->Cost;
diff --git a/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll b/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll
deleted file mode 100644
index bc62baea96d5f..0000000000000
--- a/llvm/test/Analysis/CostModel/AArch64/ctpop-neon-sve.ll
+++ /dev/null
@@ -1,97 +0,0 @@
-; 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
-}
diff --git a/llvm/test/Analysis/CostModel/AArch64/ctpop.ll b/llvm/test/Analysis/CostModel/AArch64/ctpop.ll
index 013432991f5ae..d8af6e3a4c9e9 100644
--- a/llvm/test/Analysis/CostModel/AArch64/ctpop.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/ctpop.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
 ; RUN: opt < %s -mtriple=aarch64 -passes="print<cost-model>" -cost-kind=all 2>&1 -disable-output | FileCheck %s
+; RUN: opt < %s -mtriple=aarch64 -mattr=+sve -passes="print<cost-model>" -cost-kind=all 2>&1 -disable-output | FileCheck %s --check-prefixes=CHECK-FIXED-WIDTH-VECTOR
 
 ; Verify the cost of scalar ctpop instructions.
 
@@ -9,6 +10,10 @@ define i64 @test_ctpop_i64(i64 %a) {
 ; CHECK-LABEL: 'test_ctpop_i64'
 ; CHECK-NEXT:  Cost Model: Found costs of 4 for: %ctpop = call i64 @llvm.ctpop.i64(i64 %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i64 %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_i64'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 4 for: %ctpop = call i64 @llvm.ctpop.i64(i64 %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i64 %ctpop
 ;
   %ctpop = call i64 @llvm.ctpop.i64(i64 %a)
   ret i64 %ctpop
@@ -18,6 +23,10 @@ define i32 @test_ctpop_i32(i32 %a) {
 ; CHECK-LABEL: 'test_ctpop_i32'
 ; CHECK-NEXT:  Cost Model: Found costs of 5 for: %ctpop = call i32 @llvm.ctpop.i32(i32 %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i32 %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_i32'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 5 for: %ctpop = call i32 @llvm.ctpop.i32(i32 %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i32 %ctpop
 ;
   %ctpop = call i32 @llvm.ctpop.i32(i32 %a)
   ret i32 %ctpop
@@ -27,6 +36,10 @@ define i16 @test_ctpop_i16(i16 %a) {
 ; CHECK-LABEL: 'test_ctpop_i16'
 ; CHECK-NEXT:  Cost Model: Found costs of 5 for: %ctpop = call i16 @llvm.ctpop.i16(i16 %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i16 %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_i16'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 5 for: %ctpop = call i16 @llvm.ctpop.i16(i16 %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i16 %ctpop
 ;
   %ctpop = call i16 @llvm.ctpop.i16(i16 %a)
   ret i16 %ctpop
@@ -36,6 +49,10 @@ define i8 @test_ctpop_i8(i8 %a) {
 ; CHECK-LABEL: 'test_ctpop_i8'
 ; CHECK-NEXT:  Cost Model: Found costs of 5 for: %ctpop = call i8 @llvm.ctpop.i8(i8 %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i8 %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_i8'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 5 for: %ctpop = call i8 @llvm.ctpop.i8(i8 %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i8 %ctpop
 ;
   %ctpop = call i8 @llvm.ctpop.i8(i8 %a)
   ret i8 %ctpop
@@ -52,6 +69,10 @@ define <2 x i64> @test_ctpop_v2i64(<2 x i64> %a) {
 ; CHECK-LABEL: 'test_ctpop_v2i64'
 ; CHECK-NEXT:  Cost Model: Found costs of 4 for: %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i64> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v2i64'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 1 for: %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i64> %ctpop
 ;
   %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
   ret <2 x i64> %ctpop
@@ -61,6 +82,10 @@ define <2 x i32> @test_ctpop_v2i32(<2 x i32> %a) {
 ; CHECK-LABEL: 'test_ctpop_v2i32'
 ; CHECK-NEXT:  Cost Model: Found costs of 3 for: %ctpop = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i32> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v2i32'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 1 for: %ctpop = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i32> %ctpop
 ;
   %ctpop = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a)
   ret <2 x i32> %ctpop
@@ -70,6 +95,10 @@ define <4 x i32> @test_ctpop_v4i32(<4 x i32> %a) {
 ; CHECK-LABEL: 'test_ctpop_v4i32'
 ; CHECK-NEXT:  Cost Model: Found costs of 3 for: %ctpop = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <4 x i32> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v4i32'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 1 for: %ctpop = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <4 x i32> %ctpop
 ;
   %ctpop = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
   ret <4 x i32> %ctpop
@@ -79,6 +108,10 @@ define <2 x i16> @test_ctpop_v2i16(<2 x i16> %a) {
 ; CHECK-LABEL: 'test_ctpop_v2i16'
 ; CHECK-NEXT:  Cost Model: Found costs of 4 for: %ctpop = call <2 x i16> @llvm.ctpop.v2i16(<2 x i16> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i16> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v2i16'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 4 for: %ctpop = call <2 x i16> @llvm.ctpop.v2i16(<2 x i16> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i16> %ctpop
 ;
   %ctpop = call <2 x i16> @llvm.ctpop.v2i16(<2 x i16> %a)
   ret <2 x i16> %ctpop
@@ -88,6 +121,10 @@ define <4 x i16> @test_ctpop_v4i16(<4 x i16> %a) {
 ; CHECK-LABEL: 'test_ctpop_v4i16'
 ; CHECK-NEXT:  Cost Model: Found costs of 2 for: %ctpop = call <4 x i16> @llvm.ctpop.v4i16(<4 x i16> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <4 x i16> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v4i16'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 1 for: %ctpop = call <4 x i16> @llvm.ctpop.v4i16(<4 x i16> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <4 x i16> %ctpop
 ;
   %ctpop = call <4 x i16> @llvm.ctpop.v4i16(<4 x i16> %a)
   ret <4 x i16> %ctpop
@@ -97,6 +134,10 @@ define <8 x i16> @test_ctpop_v8i16(<8 x i16> %a) {
 ; CHECK-LABEL: 'test_ctpop_v8i16'
 ; CHECK-NEXT:  Cost Model: Found costs of 2 for: %ctpop = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <8 x i16> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v8i16'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 1 for: %ctpop = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <8 x i16> %ctpop
 ;
   %ctpop = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
   ret <8 x i16> %ctpop
@@ -106,6 +147,10 @@ define <2 x i8> @test_ctpop_v2i8(<2 x i8> %a) {
 ; CHECK-LABEL: 'test_ctpop_v2i8'
 ; CHECK-NEXT:  Cost Model: Found costs of 4 for: %ctpop = call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i8> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v2i8'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 4 for: %ctpop = call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i8> %ctpop
 ;
   %ctpop = call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %a)
   ret <2 x i8> %ctpop
@@ -115,6 +160,10 @@ define <4 x i8> @test_ctpop_v4i8(<4 x i8> %a) {
 ; CHECK-LABEL: 'test_ctpop_v4i8'
 ; CHECK-NEXT:  Cost Model: Found costs of 3 for: %ctpop = call <4 x i8> @llvm.ctpop.v4i8(<4 x i8> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <4 x i8> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v4i8'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 3 for: %ctpop = call <4 x i8> @llvm.ctpop.v4i8(<4 x i8> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <4 x i8> %ctpop
 ;
   %ctpop = call <4 x i8> @llvm.ctpop.v4i8(<4 x i8> %a)
   ret <4 x i8> %ctpop
@@ -124,6 +173,10 @@ define <8 x i8> @test_ctpop_v8i8(<8 x i8> %a) {
 ; CHECK-LABEL: 'test_ctpop_v8i8'
 ; CHECK-NEXT:  Cost Model: Found costs of 1 for: %ctpop = call <8 x i8> @llvm.ctpop.v8i8(<8 x i8> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <8 x i8> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v8i8'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 1 for: %ctpop = call <8 x i8> @llvm.ctpop.v8i8(<8 x i8> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <8 x i8> %ctpop
 ;
   %ctpop = call <8 x i8> @llvm.ctpop.v8i8(<8 x i8> %a)
   ret <8 x i8> %ctpop
@@ -133,6 +186,10 @@ define <16 x i8> @test_ctpop_v16i8(<16 x i8> %a) {
 ; CHECK-LABEL: 'test_ctpop_v16i8'
 ; CHECK-NEXT:  Cost Model: Found costs of 1 for: %ctpop = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <16 x i8> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v16i8'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 1 for: %ctpop = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <16 x i8> %ctpop
 ;
   %ctpop = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %a)
   ret <16 x i8> %ctpop
@@ -142,6 +199,10 @@ define <4 x i64> @test_ctpop_v4i64(<4 x i64> %a) {
 ; CHECK-LABEL: 'test_ctpop_v4i64'
 ; CHECK-NEXT:  Cost Model: Found costs of 8 for: %ctpop = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <4 x i64> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v4i64'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 2 for: %ctpop = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <4 x i64> %ctpop
 ;
   %ctpop = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> %a)
   ret <4 x i64> %ctpop
@@ -151,6 +212,10 @@ define <8 x i32> @test_ctpop_v8i32(<8 x i32> %a) {
 ; CHECK-LABEL: 'test_ctpop_v8i32'
 ; CHECK-NEXT:  Cost Model: Found costs of 6 for: %ctpop = call <8 x i32> @llvm.ctpop.v8i32(<8 x i32> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <8 x i32> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v8i32'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 2 for: %ctpop = call <8 x i32> @llvm.ctpop.v8i32(<8 x i32> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <8 x i32> %ctpop
 ;
   %ctpop = call <8 x i32> @llvm.ctpop.v8i32(<8 x i32> %a)
   ret <8 x i32> %ctpop
@@ -160,6 +225,10 @@ define <16 x i16> @test_ctpop_v16i16(<16 x i16> %a) {
 ; CHECK-LABEL: 'test_ctpop_v16i16'
 ; CHECK-NEXT:  Cost Model: Found costs of 4 for: %ctpop = call <16 x i16> @llvm.ctpop.v16i16(<16 x i16> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <16 x i16> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v16i16'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 2 for: %ctpop = call <16 x i16> @llvm.ctpop.v16i16(<16 x i16> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <16 x i16> %ctpop
 ;
   %ctpop = call <16 x i16> @llvm.ctpop.v16i16(<16 x i16> %a)
   ret <16 x i16> %ctpop
@@ -169,6 +238,10 @@ define <32 x i8> @test_ctpop_v32i8(<32 x i8> %a) {
 ; CHECK-LABEL: 'test_ctpop_v32i8'
 ; CHECK-NEXT:  Cost Model: Found costs of 2 for: %ctpop = call <32 x i8> @llvm.ctpop.v32i8(<32 x i8> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <32 x i8> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_v32i8'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 2 for: %ctpop = call <32 x i8> @llvm.ctpop.v32i8(<32 x i8> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <32 x i8> %ctpop
 ;
   %ctpop = call <32 x i8> @llvm.ctpop.v32i8(<32 x i8> %a)
   ret <32 x i8> %ctpop
@@ -178,6 +251,10 @@ define i64 @test_ctpop_noneon_i64(i64 %a) "target-features"="-fp-armv8,-neon" {
 ; CHECK-LABEL: 'test_ctpop_noneon_i64'
 ; CHECK-NEXT:  Cost Model: Found costs of 12 for: %ctpop = call i64 @llvm.ctpop.i64(i64 %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i64 %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_noneon_i64'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 12 for: %ctpop = call i64 @llvm.ctpop.i64(i64 %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret i64 %ctpop
 ;
   %ctpop = call i64 @llvm.ctpop.i64(i64 %a)
   ret i64 %ctpop
@@ -187,6 +264,10 @@ define <2 x i64> @test_ctpop_noneon_v2i64(<2 x i64> %a) "target-features"="-fp-a
 ; CHECK-LABEL: 'test_ctpop_noneon_v2i64'
 ; CHECK-NEXT:  Cost Model: Found costs of 24 for: %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
 ; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i64> %ctpop
+;
+; CHECK-FIXED-WIDTH-VECTOR-LABEL: 'test_ctpop_noneon_v2i64'
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of 24 for: %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
+; CHECK-FIXED-WIDTH-VECTOR-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret <2 x i64> %ctpop
 ;
   %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
   ret <2 x i64> %ctpop
diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-ctpop.ll b/llvm/test/Analysis/CostModel/AArch64/sve-ctpop.ll
new file mode 100644
index 0000000000000..6768448b15091
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/AArch64/sve-ctpop.ll
@@ -0,0 +1,51 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -mtriple=aarch64-unknown-linux-gnu -mattr=+sve -passes="print<cost-model>" -cost-kind=all 2>&1 -disable-output | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+
+define void @ctpop_scalable() {
+; CHECK-LABEL: 'ctpop_scalable'
+; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv4i8 = call <vscale x 4 x i8> @llvm.ctpop.nxv4i8(<vscale x 4 x i8> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv8i8 = call <vscale x 8 x i8> @llvm.ctpop.nxv8i8(<vscale x 8 x i8> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv16i8 = call <vscale x 16 x i8> @llvm.ctpop.nxv16i8(<vscale x 16 x i8> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 4 for: %nxv32i8 = call <vscale x 32 x i8> @llvm.ctpop.nxv32i8(<vscale x 32 x i8> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv2i16 = call <vscale x 2 x i16> @llvm.ctpop.nxv2i16(<vscale x 2 x i16> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv4i16 = call <vscale x 4 x i16> @llvm.ctpop.nxv4i16(<vscale x 4 x i16> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv8i16 = call <vscale x 8 x i16> @llvm.ctpop.nxv8i16(<vscale x 8 x i16> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv16i16 = call <vscale x 16 x i16> @llvm.ctpop.nxv16i16(<vscale x 16 x i16> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv2i32 = call <vscale x 2 x i32> @llvm.ctpop.nxv2i32(<vscale x 2 x i32> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv4i32 = call <vscale x 4 x i32> @llvm.ctpop.nxv4i32(<vscale x 4 x i32> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv8i32 = call <vscale x 8 x i32> @llvm.ctpop.nxv8i32(<vscale x 8 x i32> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 1 for: %nxv2i64 = call <vscale x 2 x i64> @llvm.ctpop.nxv2i64(<vscale x 2 x i64> poison)
+; CHECK-NEXT:  Cost Model: Found costs of 2 for: %nxv4i64 = call <vscale x 4 x i64> @llvm.ctpop.nxv4i64(<vscale x 4 x i64> poison)
+; CHECK-NEXT:  Cost Model: Found costs of RThru:0 CodeSize:1 Lat:1 SizeLat:1 for: ret void
+;
+  %nxv4i8   = call <vscale x 4 x i8>   @llvm.ctpop.nxv4i8  (<vscale x 4 x i8>   poison)
+  %nxv8i8   = call <vscale x 8 x i8>   @llvm.ctpop.nxv8i8  (<vscale x 8 x i8>   poison)
+  %nxv16i8  = call <vscale x 16 x i8>  @llvm.ctpop.nxv16i8 (<vscale x 16 x i8>  poison)
+  %nxv32i8  = call <vscale x 32 x i8>  @llvm.ctpop.nxv32i8 (<vscale x 32 x i8>  poison)
+  %nxv2i16  = call <vscale x 2 x i16>  @llvm.ctpop.nxv2i16 (<vscale x 2 x i16>  poison)
+  %nxv4i16  = call <vscale x 4 x i16>  @llvm.ctpop.nxv4i16 (<vscale x 4 x i16>  poison)
+  %nxv8i16  = call <vscale x 8 x i16>  @llvm.ctpop.nxv8i16 (<vscale x 8 x i16>  poison)
+  %nxv16i16 = call <vscale x 16 x i16> @llvm.ctpop.nxv16i16(<vscale x 16 x i16> poison)
+  %nxv2i32  = call <vscale x 2 x i32>  @llvm.ctpop.nxv2i32 (<vscale x 2 x i32>  poison)
+  %nxv4i32  = call <vscale x 4 x i32>  @llvm.ctpop.nxv4i32 (<vscale x 4 x i32>  poison)
+  %nxv8i32  = call <vscale x 8 x i32>  @llvm.ctpop.nxv8i32 (<vscale x 8 x i32>  poison)
+  %nxv2i64  = call <vscale x 2 x i64>  @llvm.ctpop.nxv2i64 (<vscale x 2 x i64>  poison)
+  %nxv4i64  = call <vscale x 4 x i64>  @llvm.ctpop.nxv4i64 (<vscale x 4 x i64>  poison)
+  ret void
+}
+
+declare <vscale x 4 x i8>   @llvm.ctpop.nxv4i8  (<vscale x 4 x i8>)
+declare <vscale x 8 x i8>   @llvm.ctpop.nxv8i8  (<vscale x 8 x i8>)
+declare <vscale x 16 x i8>  @llvm.ctpop.nxv16i8 (<vscale x 16 x i8>)
+declare <vscale x 32 x i8>  @llvm.ctpop.nxv32i8 (<vscale x 32 x i8>)
+declare <vscale x 2 x i16>  @llvm.ctpop.nxv2i16 (<vscale x 2 x i16>)
+declare <vscale x 4 x i16>  @llvm.ctpop.nxv4i16 (<vscale x 4 x i16>)
+declare <vscale x 8 x i16>  @llvm.ctpop.nxv8i16 (<vscale x 8 x i16>)
+declare <vscale x 16 x i16> @llvm.ctpop.nxv16i16(<vscale x 16 x i16>)
+declare <vscale x 2 x i32>  @llvm.ctpop.nxv2i32 (<vscale x 2 x i32>)
+declare <vscale x 4 x i32>  @llvm.ctpop.nxv4i32 (<vscale x 4 x i32>)
+declare <vscale x 8 x i32>  @llvm.ctpop.nxv8i32 (<vscale x 8 x i32>)
+declare <vscale x 2 x i64>  @llvm.ctpop.nxv2i64 (<vscale x 2 x i64>)
+declare <vscale x 4 x i64>  @llvm.ctpop.nxv4i64 (<vscale x 4 x i64>)
diff --git a/llvm/test/CodeGen/AArch64/sve-ctpop.ll b/llvm/test/CodeGen/AArch64/sve-ctpop.ll
new file mode 100644
index 0000000000000..88d2e0fe26cf3
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sve-ctpop.ll
@@ -0,0 +1,32 @@
+; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+sve | FileCheck %s
+
+define void @ctpop_scalable(<vscale x 4 x i8> %nxv4i8_in,
+                             <vscale x 8 x i8> %nxv8i8_in,
+                             <vscale x 16 x i8> %nxv16i8_in,
+                             <vscale x 2 x i16> %nxv2i16_in,
+                             <vscale x 4 x i16> %nxv4i16_in,
+                             <vscale x 8 x i16> %nxv8i16_in,
+                             <vscale x 2 x i32> %nxv2i32_in,
+                             <vscale x 4 x i32> %nxv4i32_in,
+                             <vscale x 2 x i64> %nxv2i64_in) {
+  %nxv4i8  = call <vscale x 4 x i8>  @llvm.ctpop.nxv4i8 (<vscale x 4 x i8>  %nxv4i8_in)
+  %nxv8i8  = call <vscale x 8 x i8>  @llvm.ctpop.nxv8i8 (<vscale x 8 x i8>  %nxv8i8_in)
+  %nxv16i8 = call <vscale x 16 x i8> @llvm.ctpop.nxv16i8(<vscale x 16 x i8> %nxv16i8_in)
+  %nxv2i16 = call <vscale x 2 x i16> @llvm.ctpop.nxv2i16(<vscale x 2 x i16> %nxv2i16_in)
+  %nxv4i16 = call <vscale x 4 x i16> @llvm.ctpop.nxv4i16(<vscale x 4 x i16> %nxv4i16_in)
+  %nxv8i16 = call <vscale x 8 x i16> @llvm.ctpop.nxv8i16(<vscale x 8 x i16> %nxv8i16_in)
+  %nxv2i32 = call <vscale x 2 x i32> @llvm.ctpop.nxv2i32(<vscale x 2 x i32> %nxv2i32_in)
+  %nxv4i32 = call <vscale x 4 x i32> @llvm.ctpop.nxv4i32(<vscale x 4 x i32> %nxv4i32_in)
+  %nxv2i64 = call <vscale x 2 x i64> @llvm.ctpop.nxv2i64(<vscale x 2 x i64> %nxv2i64_in)
+  ret void
+}
+
+declare <vscale x 4 x i8>  @llvm.ctpop.nxv4i8 (<vscale x 4 x i8>)
+declare <vscale x 8 x i8>  @llvm.ctpop.nxv8i8 (<vscale x 8 x i8>)
+declare <vscale x 16 x i8> @llvm.ctpop.nxv16i8(<vscale x 16 x i8>)
+declare <vscale x 2 x i16> @llvm.ctpop.nxv2i16(<vscale x 2 x i16>)
+declare <vscale x 4 x i16> @llvm.ctpop.nxv4i16(<vscale x 4 x i16>)
+declare <vscale x 8 x i16> @llvm.ctpop.nxv8i16(<vscale x 8 x i16>)
+declare <vscale x 2 x i32> @llvm.ctpop.nxv2i32(<vscale x 2 x i32>)
+declare <vscale x 4 x i32> @llvm.ctpop.nxv4i32(<vscale x 4 x i32>)
+declare <vscale x 2 x i64> @llvm.ctpop.nxv2i64(<vscale x 2 x i64>)



More information about the llvm-commits mailing list