[llvm] [AArch64][SVE] Allow basic use of `target("aarch64.svcount")` with +sve (PR #167875)

Benjamin Maxwell via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 13 08:01:28 PST 2025


https://github.com/MacDue updated https://github.com/llvm/llvm-project/pull/167875

>From 16de1550031b88fe50ca9ce1a294591fff978d55 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 13 Nov 2025 13:54:43 +0000
Subject: [PATCH 1/4] [AArch64][SVE] Allow basic use of
 `target("aarch64.svcount")` with +sve

This prevents the backend from crashing for basic uses of the
__SVCount_t type (e.g., as function arguments), without +sve2p1 or +sme2.

Fixes #167462
---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 13 +++--
 .../CodeGen/AArch64/aarch64-svcount-basic.ll  | 51 +++++++++++++++++++
 2 files changed, 57 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/aarch64-svcount-basic.ll

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index eaa10ef031989..301853495a6f3 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -462,6 +462,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
     addRegisterClass(MVT::nxv4bf16, &AArch64::ZPRRegClass);
     addRegisterClass(MVT::nxv8bf16, &AArch64::ZPRRegClass);
 
+    addRegisterClass(MVT::aarch64svcount, &AArch64::PPRRegClass);
+
     if (Subtarget->useSVEForFixedLengthVectors()) {
       for (MVT VT : MVT::integer_fixedlen_vector_valuetypes())
         if (useSVEForFixedLengthVectorVT(VT))
@@ -473,14 +475,11 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
     }
   }
 
-  if (Subtarget->hasSVE2p1() || Subtarget->hasSME2()) {
-    addRegisterClass(MVT::aarch64svcount, &AArch64::PPRRegClass);
-    setOperationPromotedToType(ISD::LOAD, MVT::aarch64svcount, MVT::nxv16i1);
-    setOperationPromotedToType(ISD::STORE, MVT::aarch64svcount, MVT::nxv16i1);
+  setOperationPromotedToType(ISD::LOAD, MVT::aarch64svcount, MVT::nxv16i1);
+  setOperationPromotedToType(ISD::STORE, MVT::aarch64svcount, MVT::nxv16i1);
 
-    setOperationAction(ISD::SELECT, MVT::aarch64svcount, Custom);
-    setOperationAction(ISD::SELECT_CC, MVT::aarch64svcount, Expand);
-  }
+  setOperationAction(ISD::SELECT, MVT::aarch64svcount, Custom);
+  setOperationAction(ISD::SELECT_CC, MVT::aarch64svcount, Expand);
 
   // Compute derived properties from the register classes
   computeRegisterProperties(Subtarget->getRegisterInfo());
diff --git a/llvm/test/CodeGen/AArch64/aarch64-svcount-basic.ll b/llvm/test/CodeGen/AArch64/aarch64-svcount-basic.ll
new file mode 100644
index 0000000000000..90869e9d6532a
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/aarch64-svcount-basic.ll
@@ -0,0 +1,51 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+sve | FileCheck %s
+
+;; This file tests basic use of `target("aarch64.svcount")` works with only +sve.
+
+declare void @svcount_fn_arg(target("aarch64.svcount"))
+
+define void @svcount_fn_call() {
+; CHECK-LABEL: svcount_fn_call:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    .cfi_offset w30, -16
+; CHECK-NEXT:    pfalse p0.b
+; CHECK-NEXT:    bl svcount_fn_arg
+; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT:    ret
+entry:
+  call void @svcount_fn_arg(target("aarch64.svcount") zeroinitializer)
+  ret void
+}
+
+define target("aarch64.svcount") @select_svcount(i1 %cond, target("aarch64.svcount") %pn0, target("aarch64.svcount") %pn1) {
+; CHECK-LABEL: select_svcount:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
+; CHECK-NEXT:    sbfx x8, x0, #0, #1
+; CHECK-NEXT:    whilelo p2.b, xzr, x8
+; CHECK-NEXT:    sel p0.b, p2, p0.b, p1.b
+; CHECK-NEXT:    ret
+  %sel = select i1 %cond, target("aarch64.svcount") %pn0, target("aarch64.svcount") %pn1
+  ret target("aarch64.svcount") %sel
+}
+
+define void @store_svcount(ptr %ptr, target("aarch64.svcount") %pn) {
+; CHECK-LABEL: store_svcount:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    str p0, [x0]
+; CHECK-NEXT:    ret
+  store target("aarch64.svcount") %pn, ptr %ptr, align 2
+  ret void
+}
+
+define target("aarch64.svcount")  @load_svcount(ptr %ptr) {
+; CHECK-LABEL: load_svcount:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ldr p0, [x0]
+; CHECK-NEXT:    ret
+  %pn = load target("aarch64.svcount"), ptr %ptr, align 2
+  ret target("aarch64.svcount") %pn
+}

>From ba2f4a49f2522c315734082aba30df1a1d8b542c Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 13 Nov 2025 14:16:45 +0000
Subject: [PATCH 2/4] Move actions

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 301853495a6f3..fc0581a36e1b7 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -475,12 +475,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
     }
   }
 
-  setOperationPromotedToType(ISD::LOAD, MVT::aarch64svcount, MVT::nxv16i1);
-  setOperationPromotedToType(ISD::STORE, MVT::aarch64svcount, MVT::nxv16i1);
-
-  setOperationAction(ISD::SELECT, MVT::aarch64svcount, Custom);
-  setOperationAction(ISD::SELECT_CC, MVT::aarch64svcount, Expand);
-
   // Compute derived properties from the register classes
   computeRegisterProperties(Subtarget->getRegisterInfo());
 
@@ -1608,6 +1602,14 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
            MVT::nxv4i16, MVT::nxv4i32, MVT::nxv8i8, MVT::nxv8i16 })
       setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Legal);
 
+    // Promote predicate as counter load/stores to standard predicates.
+    setOperationPromotedToType(ISD::LOAD, MVT::aarch64svcount, MVT::nxv16i1);
+    setOperationPromotedToType(ISD::STORE, MVT::aarch64svcount, MVT::nxv16i1);
+
+    // Predicate as counter legalization actions.
+    setOperationAction(ISD::SELECT, MVT::aarch64svcount, Custom);
+    setOperationAction(ISD::SELECT_CC, MVT::aarch64svcount, Expand);
+
     for (auto VT :
          {MVT::nxv16i1, MVT::nxv8i1, MVT::nxv4i1, MVT::nxv2i1, MVT::nxv1i1}) {
       setOperationAction(ISD::CONCAT_VECTORS, VT, Custom);

>From 3a8a7590f1fc657539d9fd05862247170ce13732 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 13 Nov 2025 14:21:54 +0000
Subject: [PATCH 3/4] Move addRegclass

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index fc0581a36e1b7..f4e8b74f115dc 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -445,6 +445,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
     addRegisterClass(MVT::nxv8i1, &AArch64::PPRRegClass);
     addRegisterClass(MVT::nxv16i1, &AArch64::PPRRegClass);
 
+    // Add sve predicate as counter type
+    addRegisterClass(MVT::aarch64svcount, &AArch64::PPRRegClass);
+
     // Add legal sve data types
     addRegisterClass(MVT::nxv16i8, &AArch64::ZPRRegClass);
     addRegisterClass(MVT::nxv8i16, &AArch64::ZPRRegClass);
@@ -462,8 +465,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
     addRegisterClass(MVT::nxv4bf16, &AArch64::ZPRRegClass);
     addRegisterClass(MVT::nxv8bf16, &AArch64::ZPRRegClass);
 
-    addRegisterClass(MVT::aarch64svcount, &AArch64::PPRRegClass);
-
     if (Subtarget->useSVEForFixedLengthVectors()) {
       for (MVT VT : MVT::integer_fixedlen_vector_valuetypes())
         if (useSVEForFixedLengthVectorVT(VT))

>From eb13f1bec29e02bcbaaeae831d45a058760d90db Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 13 Nov 2025 15:59:54 +0000
Subject: [PATCH 4/4] Remove test

---
 .../CodeGen/AArch64/aarch64-svcount-basic.ll  | 51 -------------------
 .../CodeGen/AArch64/sme-aarch64-svcount.ll    |  4 +-
 2 files changed, 2 insertions(+), 53 deletions(-)
 delete mode 100644 llvm/test/CodeGen/AArch64/aarch64-svcount-basic.ll

diff --git a/llvm/test/CodeGen/AArch64/aarch64-svcount-basic.ll b/llvm/test/CodeGen/AArch64/aarch64-svcount-basic.ll
deleted file mode 100644
index 90869e9d6532a..0000000000000
--- a/llvm/test/CodeGen/AArch64/aarch64-svcount-basic.ll
+++ /dev/null
@@ -1,51 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
-; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+sve | FileCheck %s
-
-;; This file tests basic use of `target("aarch64.svcount")` works with only +sve.
-
-declare void @svcount_fn_arg(target("aarch64.svcount"))
-
-define void @svcount_fn_call() {
-; CHECK-LABEL: svcount_fn_call:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    .cfi_offset w30, -16
-; CHECK-NEXT:    pfalse p0.b
-; CHECK-NEXT:    bl svcount_fn_arg
-; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
-; CHECK-NEXT:    ret
-entry:
-  call void @svcount_fn_arg(target("aarch64.svcount") zeroinitializer)
-  ret void
-}
-
-define target("aarch64.svcount") @select_svcount(i1 %cond, target("aarch64.svcount") %pn0, target("aarch64.svcount") %pn1) {
-; CHECK-LABEL: select_svcount:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
-; CHECK-NEXT:    sbfx x8, x0, #0, #1
-; CHECK-NEXT:    whilelo p2.b, xzr, x8
-; CHECK-NEXT:    sel p0.b, p2, p0.b, p1.b
-; CHECK-NEXT:    ret
-  %sel = select i1 %cond, target("aarch64.svcount") %pn0, target("aarch64.svcount") %pn1
-  ret target("aarch64.svcount") %sel
-}
-
-define void @store_svcount(ptr %ptr, target("aarch64.svcount") %pn) {
-; CHECK-LABEL: store_svcount:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    str p0, [x0]
-; CHECK-NEXT:    ret
-  store target("aarch64.svcount") %pn, ptr %ptr, align 2
-  ret void
-}
-
-define target("aarch64.svcount")  @load_svcount(ptr %ptr) {
-; CHECK-LABEL: load_svcount:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    ldr p0, [x0]
-; CHECK-NEXT:    ret
-  %pn = load target("aarch64.svcount"), ptr %ptr, align 2
-  ret target("aarch64.svcount") %pn
-}
diff --git a/llvm/test/CodeGen/AArch64/sme-aarch64-svcount.ll b/llvm/test/CodeGen/AArch64/sme-aarch64-svcount.ll
index aee705f0be9b9..ecbf0bdb06d15 100644
--- a/llvm/test/CodeGen/AArch64/sme-aarch64-svcount.ll
+++ b/llvm/test/CodeGen/AArch64/sme-aarch64-svcount.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -O0 -mtriple=aarch64 -mattr=+sve2p1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-O0
-; RUN: llc -O3 -mtriple=aarch64 -mattr=+sve2p1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-O3
+; RUN: llc -O0 -mtriple=aarch64 -mattr=+sve < %s | FileCheck %s --check-prefixes=CHECK,CHECK-O0
+; RUN: llc -O3 -mtriple=aarch64 -mattr=+sve < %s | FileCheck %s --check-prefixes=CHECK,CHECK-O3
 
 ;
 ; Test simple loads, stores and return.



More information about the llvm-commits mailing list