[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