[llvm] [AArch64] Prevent reuse of retired architecture names (PR #221782)
Jonathan Thackray via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 03:29:07 PDT 2026
https://github.com/jthackray updated https://github.com/llvm/llvm-project/pull/221782
>From dd48d3848fe163e5545de1207364feccdc8e215a Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Mon, 7 Sep 2026 17:18:21 +0100
Subject: [PATCH 1/4] [AArch64] Prevent reuse of retired architecture names
Add explicit lists of retired AArch64 feature and system register names,
with TableGen validation preventing future definitions from reusing them.
This preserves names previously exposed by LLVM after their architectural
features or registers have been withdrawn or removed. Add coverage for
target features, architecture extension names and aliases, architectural
FEAT_* names, and system registers.
---
llvm/lib/Target/AArch64/AArch64.td | 12 ++++++
.../AArch64/AArch64ValidateRetiredNames.td | 37 ++++++++++++++++
llvm/test/TableGen/aarch64-retired-names.td | 43 +++++++++++++++++++
3 files changed, 92 insertions(+)
create mode 100644 llvm/lib/Target/AArch64/AArch64ValidateRetiredNames.td
create mode 100644 llvm/test/TableGen/aarch64-retired-names.td
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 9750fa837c180..bc061a742b7f1 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -15,6 +15,15 @@
include "llvm/Target/Target.td"
+//===----------------------------------------------------------------------===//
+// Retired feature names or system registers, which cannot be reused
+//===----------------------------------------------------------------------===//
+defvar AArch64RetiredSubtargetFeatureNames = ["mpamv2", "tme"];
+defvar AArch64RetiredArchFeatureNames =
+ ["FEAT_MPAMv2", "FEAT_MPAMv2_VID", "FEAT_TME"];
+defvar AArch64RetiredSystemRegisterNames =
+ ["MPAMVIDCR_EL2", "MPAMVIDSR_EL2", "MPAMVIDSR_EL3"];
+
//===----------------------------------------------------------------------===//
// Subtarget features.
//===----------------------------------------------------------------------===//
@@ -209,3 +218,6 @@ def AArch64 : Target {
//===----------------------------------------------------------------------===//
include "AArch64PfmCounters.td"
+
+// This must remain after all AArch64 records have been instantiated.
+include "AArch64ValidateRetiredNames.td"
diff --git a/llvm/lib/Target/AArch64/AArch64ValidateRetiredNames.td b/llvm/lib/Target/AArch64/AArch64ValidateRetiredNames.td
new file mode 100644
index 0000000000000..cd688796799e9
--- /dev/null
+++ b/llvm/lib/Target/AArch64/AArch64ValidateRetiredNames.td
@@ -0,0 +1,37 @@
+//=- AArch64ValidateRetiredNames.td - Check retired names -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Check that names belonging to withdrawn architectural features and system
+// registers are not reused. This file must be included after all the records
+// to be checked have been instantiated.
+//
+//===----------------------------------------------------------------------===//
+
+foreach Feature = !instances<SubtargetFeature>() in
+ foreach RetiredName = AArch64RetiredSubtargetFeatureNames in
+ assert !ne(Feature.Name, RetiredName),
+ "subtarget feature name '" # RetiredName # "' has been retired";
+
+foreach ExtensionRecord = !instances<Extension>() in {
+ foreach RetiredName = AArch64RetiredSubtargetFeatureNames in {
+ assert !ne(ExtensionRecord.UserVisibleName, RetiredName),
+ "architecture extension name '" # RetiredName # "' has been retired";
+ assert !ne(ExtensionRecord.UserVisibleAlias, RetiredName),
+ "architecture extension alias '" # RetiredName # "' has been retired";
+ }
+
+ foreach RetiredName = AArch64RetiredArchFeatureNames in
+ assert !eq(!find(", " # ExtensionRecord.ArchFeatureName # ", ",
+ ", " # RetiredName # ", "), -1),
+ "architecture feature name '" # RetiredName # "' has been retired";
+}
+
+foreach Register = !instances<SysReg>() in
+ foreach RetiredName = AArch64RetiredSystemRegisterNames in
+ assert !ne(!toupper(Register.Name), !toupper(RetiredName)),
+ "system register name '" # RetiredName # "' has been retired";
diff --git a/llvm/test/TableGen/aarch64-retired-names.td b/llvm/test/TableGen/aarch64-retired-names.td
new file mode 100644
index 0000000000000..c31663e36b90d
--- /dev/null
+++ b/llvm/test/TableGen/aarch64-retired-names.td
@@ -0,0 +1,43 @@
+// RUN: not llvm-tblgen -print-records -DREUSE_RETIRED_NAMES %s \
+// RUN: -I %p/../../lib/Target/AArch64 -I %p/../../include 2>&1 | \
+// RUN: FileCheck %s
+include "AArch64.td"
+
+#ifdef REUSE_RETIRED_NAMES
+foreach RetiredName = AArch64RetiredSubtargetFeatureNames in
+ def : SubtargetFeature<RetiredName, "ReusedFeature", "true",
+ "Invalid test feature">;
+
+foreach RetiredName = AArch64RetiredSubtargetFeatureNames in {
+ let UserVisibleName = RetiredName in
+ def : Extension<"test-name-" # RetiredName, "TestExtensionName",
+ "FEAT_TEST", "Invalid test extension">;
+
+ let UserVisibleAlias = RetiredName in
+ def : Extension<"test-alias-" # RetiredName, "TestExtensionAlias",
+ "FEAT_TEST", "Invalid test extension">;
+}
+
+foreach RetiredName = AArch64RetiredArchFeatureNames in
+ def : Extension<"test-" # RetiredName, "TestArchFeature",
+ "FEAT_TEST, " # RetiredName, "Invalid test extension">;
+
+foreach RetiredName = AArch64RetiredSystemRegisterNames in
+ def : ROSysReg<!tolower(RetiredName), 0b11, 0b000, 0b0000, 0b0000, 0b000>;
+#endif
+
+// Re-run the checks after instantiating the deliberately invalid record.
+include "AArch64ValidateRetiredNames.td"
+
+// CHECK-DAG: assertion failed: subtarget feature name 'mpamv2' has been retired
+// CHECK-DAG: assertion failed: subtarget feature name 'tme' has been retired
+// CHECK-DAG: assertion failed: architecture extension name 'mpamv2' has been retired
+// CHECK-DAG: assertion failed: architecture extension name 'tme' has been retired
+// CHECK-DAG: assertion failed: architecture extension alias 'mpamv2' has been retired
+// CHECK-DAG: assertion failed: architecture extension alias 'tme' has been retired
+// CHECK-DAG: assertion failed: architecture feature name 'FEAT_MPAMv2' has been retired
+// CHECK-DAG: assertion failed: architecture feature name 'FEAT_MPAMv2_VID' has been retired
+// CHECK-DAG: assertion failed: architecture feature name 'FEAT_TME' has been retired
+// CHECK-DAG: assertion failed: system register name 'MPAMVIDCR_EL2' has been retired
+// CHECK-DAG: assertion failed: system register name 'MPAMVIDSR_EL2' has been retired
+// CHECK-DAG: assertion failed: system register name 'MPAMVIDSR_EL3' has been retired
>From c5dbb770c16d97212561ad26b0d0db9117d4bdb5 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Thu, 17 Sep 2026 17:23:41 +0100
Subject: [PATCH 2/4] fixup! Address CR comments; make this simpler
---
llvm/lib/Target/AArch64/AArch64.td | 12 ------
.../AArch64/AArch64ValidateRetiredNames.td | 37 ----------------
llvm/test/MC/AArch64/retired-names.s | 18 ++++++++
llvm/test/TableGen/aarch64-retired-names.td | 43 -------------------
4 files changed, 18 insertions(+), 92 deletions(-)
delete mode 100644 llvm/lib/Target/AArch64/AArch64ValidateRetiredNames.td
create mode 100644 llvm/test/MC/AArch64/retired-names.s
delete mode 100644 llvm/test/TableGen/aarch64-retired-names.td
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index bc061a742b7f1..9750fa837c180 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -15,15 +15,6 @@
include "llvm/Target/Target.td"
-//===----------------------------------------------------------------------===//
-// Retired feature names or system registers, which cannot be reused
-//===----------------------------------------------------------------------===//
-defvar AArch64RetiredSubtargetFeatureNames = ["mpamv2", "tme"];
-defvar AArch64RetiredArchFeatureNames =
- ["FEAT_MPAMv2", "FEAT_MPAMv2_VID", "FEAT_TME"];
-defvar AArch64RetiredSystemRegisterNames =
- ["MPAMVIDCR_EL2", "MPAMVIDSR_EL2", "MPAMVIDSR_EL3"];
-
//===----------------------------------------------------------------------===//
// Subtarget features.
//===----------------------------------------------------------------------===//
@@ -218,6 +209,3 @@ def AArch64 : Target {
//===----------------------------------------------------------------------===//
include "AArch64PfmCounters.td"
-
-// This must remain after all AArch64 records have been instantiated.
-include "AArch64ValidateRetiredNames.td"
diff --git a/llvm/lib/Target/AArch64/AArch64ValidateRetiredNames.td b/llvm/lib/Target/AArch64/AArch64ValidateRetiredNames.td
deleted file mode 100644
index cd688796799e9..0000000000000
--- a/llvm/lib/Target/AArch64/AArch64ValidateRetiredNames.td
+++ /dev/null
@@ -1,37 +0,0 @@
-//=- AArch64ValidateRetiredNames.td - Check retired names -*- tablegen -*-=//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Check that names belonging to withdrawn architectural features and system
-// registers are not reused. This file must be included after all the records
-// to be checked have been instantiated.
-//
-//===----------------------------------------------------------------------===//
-
-foreach Feature = !instances<SubtargetFeature>() in
- foreach RetiredName = AArch64RetiredSubtargetFeatureNames in
- assert !ne(Feature.Name, RetiredName),
- "subtarget feature name '" # RetiredName # "' has been retired";
-
-foreach ExtensionRecord = !instances<Extension>() in {
- foreach RetiredName = AArch64RetiredSubtargetFeatureNames in {
- assert !ne(ExtensionRecord.UserVisibleName, RetiredName),
- "architecture extension name '" # RetiredName # "' has been retired";
- assert !ne(ExtensionRecord.UserVisibleAlias, RetiredName),
- "architecture extension alias '" # RetiredName # "' has been retired";
- }
-
- foreach RetiredName = AArch64RetiredArchFeatureNames in
- assert !eq(!find(", " # ExtensionRecord.ArchFeatureName # ", ",
- ", " # RetiredName # ", "), -1),
- "architecture feature name '" # RetiredName # "' has been retired";
-}
-
-foreach Register = !instances<SysReg>() in
- foreach RetiredName = AArch64RetiredSystemRegisterNames in
- assert !ne(!toupper(Register.Name), !toupper(RetiredName)),
- "system register name '" # RetiredName # "' has been retired";
diff --git a/llvm/test/MC/AArch64/retired-names.s b/llvm/test/MC/AArch64/retired-names.s
new file mode 100644
index 0000000000000..324c12b566f1c
--- /dev/null
+++ b/llvm/test/MC/AArch64/retired-names.s
@@ -0,0 +1,18 @@
+// RUN: not llvm-mc -triple=aarch64 -mattr=+mpamv2,+tme < %s 2>&1 | FileCheck %s
+
+// Retired feature and system register names must not be reused.
+
+// CHECK: '+mpamv2' is not a recognized feature for this target (ignoring feature)
+// CHECK-NEXT: '+tme' is not a recognized feature for this target (ignoring feature)
+
+mrs x0, mpamvidcr_el2
+// CHECK: :[[@LINE-1]]:9: error: expected readable system register
+// CHECK-NEXT: mrs x0, mpamvidcr_el2
+
+mrs x0, mpamvidsr_el2
+// CHECK: :[[@LINE-1]]:9: error: expected readable system register
+// CHECK-NEXT: mrs x0, mpamvidsr_el2
+
+mrs x0, mpamvidsr_el3
+// CHECK: :[[@LINE-1]]:9: error: expected readable system register
+// CHECK-NEXT: mrs x0, mpamvidsr_el3
diff --git a/llvm/test/TableGen/aarch64-retired-names.td b/llvm/test/TableGen/aarch64-retired-names.td
deleted file mode 100644
index c31663e36b90d..0000000000000
--- a/llvm/test/TableGen/aarch64-retired-names.td
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: not llvm-tblgen -print-records -DREUSE_RETIRED_NAMES %s \
-// RUN: -I %p/../../lib/Target/AArch64 -I %p/../../include 2>&1 | \
-// RUN: FileCheck %s
-include "AArch64.td"
-
-#ifdef REUSE_RETIRED_NAMES
-foreach RetiredName = AArch64RetiredSubtargetFeatureNames in
- def : SubtargetFeature<RetiredName, "ReusedFeature", "true",
- "Invalid test feature">;
-
-foreach RetiredName = AArch64RetiredSubtargetFeatureNames in {
- let UserVisibleName = RetiredName in
- def : Extension<"test-name-" # RetiredName, "TestExtensionName",
- "FEAT_TEST", "Invalid test extension">;
-
- let UserVisibleAlias = RetiredName in
- def : Extension<"test-alias-" # RetiredName, "TestExtensionAlias",
- "FEAT_TEST", "Invalid test extension">;
-}
-
-foreach RetiredName = AArch64RetiredArchFeatureNames in
- def : Extension<"test-" # RetiredName, "TestArchFeature",
- "FEAT_TEST, " # RetiredName, "Invalid test extension">;
-
-foreach RetiredName = AArch64RetiredSystemRegisterNames in
- def : ROSysReg<!tolower(RetiredName), 0b11, 0b000, 0b0000, 0b0000, 0b000>;
-#endif
-
-// Re-run the checks after instantiating the deliberately invalid record.
-include "AArch64ValidateRetiredNames.td"
-
-// CHECK-DAG: assertion failed: subtarget feature name 'mpamv2' has been retired
-// CHECK-DAG: assertion failed: subtarget feature name 'tme' has been retired
-// CHECK-DAG: assertion failed: architecture extension name 'mpamv2' has been retired
-// CHECK-DAG: assertion failed: architecture extension name 'tme' has been retired
-// CHECK-DAG: assertion failed: architecture extension alias 'mpamv2' has been retired
-// CHECK-DAG: assertion failed: architecture extension alias 'tme' has been retired
-// CHECK-DAG: assertion failed: architecture feature name 'FEAT_MPAMv2' has been retired
-// CHECK-DAG: assertion failed: architecture feature name 'FEAT_MPAMv2_VID' has been retired
-// CHECK-DAG: assertion failed: architecture feature name 'FEAT_TME' has been retired
-// CHECK-DAG: assertion failed: system register name 'MPAMVIDCR_EL2' has been retired
-// CHECK-DAG: assertion failed: system register name 'MPAMVIDSR_EL2' has been retired
-// CHECK-DAG: assertion failed: system register name 'MPAMVIDSR_EL3' has been retired
>From 85974515c3c46c8fbc6ce171997363de159a717a Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Fri, 18 Sep 2026 11:24:10 +0100
Subject: [PATCH 3/4] fixup! Slightly adjust message in testfile
---
llvm/test/MC/AArch64/retired-names.s | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/llvm/test/MC/AArch64/retired-names.s b/llvm/test/MC/AArch64/retired-names.s
index 324c12b566f1c..bec58732985f1 100644
--- a/llvm/test/MC/AArch64/retired-names.s
+++ b/llvm/test/MC/AArch64/retired-names.s
@@ -1,6 +1,9 @@
// RUN: not llvm-mc -triple=aarch64 -mattr=+mpamv2,+tme < %s 2>&1 | FileCheck %s
-// Retired feature and system register names must not be reused.
+// Add negative tests preventing reuse of retired feature and system register names.
+//
+// When system registers or feature names are retired, they should be appended to
+// this file, to ensure they're never re-used in future.
// CHECK: '+mpamv2' is not a recognized feature for this target (ignoring feature)
// CHECK-NEXT: '+tme' is not a recognized feature for this target (ignoring feature)
>From 017d946b5328ccdd7e5f58e093880f11e57ebf54 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Mon, 21 Sep 2026 11:26:34 +0100
Subject: [PATCH 4/4] fixup! Amend after PR comments
---
llvm/test/MC/AArch64/retired-feature-names.s | 9 +++++++++
.../{retired-names.s => retired-register-names.s} | 9 +++------
2 files changed, 12 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/MC/AArch64/retired-feature-names.s
rename llvm/test/MC/AArch64/{retired-names.s => retired-register-names.s} (52%)
diff --git a/llvm/test/MC/AArch64/retired-feature-names.s b/llvm/test/MC/AArch64/retired-feature-names.s
new file mode 100644
index 0000000000000..0b5cc06a2ef98
--- /dev/null
+++ b/llvm/test/MC/AArch64/retired-feature-names.s
@@ -0,0 +1,9 @@
+// RUN: llvm-mc -triple=aarch64 -mattr=+mpamv2,+tme < %s 2>&1 | FileCheck %s
+
+// Add negative tests preventing reuse of retired feature names.
+//
+// When feature names are retired, they should be appended to
+// this file, to ensure they're never re-used in future.
+
+// CHECK: '+mpamv2' is not a recognized feature for this target (ignoring feature)
+// CHECK-NEXT: '+tme' is not a recognized feature for this target (ignoring feature)
diff --git a/llvm/test/MC/AArch64/retired-names.s b/llvm/test/MC/AArch64/retired-register-names.s
similarity index 52%
rename from llvm/test/MC/AArch64/retired-names.s
rename to llvm/test/MC/AArch64/retired-register-names.s
index bec58732985f1..56a483698e90e 100644
--- a/llvm/test/MC/AArch64/retired-names.s
+++ b/llvm/test/MC/AArch64/retired-register-names.s
@@ -1,13 +1,10 @@
-// RUN: not llvm-mc -triple=aarch64 -mattr=+mpamv2,+tme < %s 2>&1 | FileCheck %s
+// RUN: not llvm-mc -triple=aarch64 -mattr=+all < %s 2>&1 | FileCheck %s
-// Add negative tests preventing reuse of retired feature and system register names.
+// Add negative tests preventing reuse of retired system register names.
//
-// When system registers or feature names are retired, they should be appended to
+// When system registers are retired, they should be appended to
// this file, to ensure they're never re-used in future.
-// CHECK: '+mpamv2' is not a recognized feature for this target (ignoring feature)
-// CHECK-NEXT: '+tme' is not a recognized feature for this target (ignoring feature)
-
mrs x0, mpamvidcr_el2
// CHECK: :[[@LINE-1]]:9: error: expected readable system register
// CHECK-NEXT: mrs x0, mpamvidcr_el2
More information about the llvm-commits
mailing list