[llvm] [clang][AArch64] Restrict `__SVCount_t` to targets with sme2 or sve2p1 (PR #167875)

Benjamin Maxwell via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 13 05:58:03 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] [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
+}



More information about the llvm-commits mailing list