[clang] a6aaa96 - [AArch64] Assembly support for FEAT_LRCPC3
Tomas Matheson via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 25 10:59:29 PST 2022
Author: Tomas Matheson
Date: 2022-11-25T18:59:07Z
New Revision: a6aaa969f7caec58a994142f8d855861cf3a1463
URL: https://github.com/llvm/llvm-project/commit/a6aaa969f7caec58a994142f8d855861cf3a1463
DIFF: https://github.com/llvm/llvm-project/commit/a6aaa969f7caec58a994142f8d855861cf3a1463.diff
LOG: [AArch64] Assembly support for FEAT_LRCPC3
This patch implements assembly support for the 2022 A-Profile Architecture
extension FEAT_LRCPC3. FEAT_LRCPC3 is AArch64 only and introduces new
variants of load/store instructions with release consistency ordering.
Specs for individual instructions can be found here:
https://developer.arm.com/documentation/ddi0602/2022-09/Base-Instructions/
This feature is optionally available from v8.2a and therefore not enabled by
default.
Contributors:
Lucas Prates
Sam Elliot
Son Tuan Vu
Tomas Matheson
Differential Revision: https://reviews.llvm.org/D138579
Added:
clang/test/Driver/aarch64-lrcpc3.c
llvm/test/MC/AArch64/armv8.9a-lrcpc3.s
llvm/test/MC/Disassembler/AArch64/armv8.9a-lrcpc3.txt
Modified:
llvm/include/llvm/Support/AArch64TargetParser.def
llvm/include/llvm/Support/AArch64TargetParser.h
llvm/lib/Target/AArch64/AArch64.td
llvm/lib/Target/AArch64/AArch64InstrFormats.td
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
llvm/test/MC/AArch64/arm64-memory.s
llvm/unittests/Support/TargetParserTest.cpp
Removed:
################################################################################
diff --git a/clang/test/Driver/aarch64-lrcpc3.c b/clang/test/Driver/aarch64-lrcpc3.c
new file mode 100644
index 0000000000000..27b522d74c5f8
--- /dev/null
+++ b/clang/test/Driver/aarch64-lrcpc3.c
@@ -0,0 +1,26 @@
+// Test that target feature FEAT_RCPC3 is implemented and available correctly
+
+// FEAT_RCPC3 is optional for v8.2a onwards, and can be enabled with +rcpc3
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.9-a %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.9-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=ENABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.9-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.4-a %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.4-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=ENABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.4-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+
+// FEAT_RCPC3 is optional (off by default) for v8.8a/9.3a and older, and can be enabled using +rcpc3
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.2-a %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.2-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=ENABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.2-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9-a %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=ENABLED
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+
+// FEAT_RCPC3 is invalid before v8
+// RUN: %clang -### -target arm-none-none-eabi -march=armv7-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=INVALID
+
+// INVALID: error: unsupported argument 'armv7-a+rcpc3' to option '-march='
+// ENABLED: "-target-feature" "+rcpc3"
+// NOT_ENABLED-NOT: "-target-feature" "+rcpc3"
+// DISABLED: "-target-feature" "-rcpc3"
+
diff --git a/llvm/include/llvm/Support/AArch64TargetParser.def b/llvm/include/llvm/Support/AArch64TargetParser.def
index f016c9147a7bb..6fd68872e96c1 100644
--- a/llvm/include/llvm/Support/AArch64TargetParser.def
+++ b/llvm/include/llvm/Support/AArch64TargetParser.def
@@ -152,6 +152,7 @@ AARCH64_ARCH_EXT_NAME("hbc", AArch64::AEK_HBC, "+hbc",
AARCH64_ARCH_EXT_NAME("mops", AArch64::AEK_MOPS, "+mops", "-mops")
AARCH64_ARCH_EXT_NAME("pmuv3", AArch64::AEK_PERFMON, "+perfmon", "-perfmon")
AARCH64_ARCH_EXT_NAME("cssc", AArch64::AEK_CSSC, "+cssc", "-cssc")
+AARCH64_ARCH_EXT_NAME("rcpc3", AArch64::AEK_RCPC3, "+rcpc3", "-rcpc3")
#undef AARCH64_ARCH_EXT_NAME
#ifndef AARCH64_CPU_NAME
diff --git a/llvm/include/llvm/Support/AArch64TargetParser.h b/llvm/include/llvm/Support/AArch64TargetParser.h
index 4d069a6b67831..3261e3f5b5eae 100644
--- a/llvm/include/llvm/Support/AArch64TargetParser.h
+++ b/llvm/include/llvm/Support/AArch64TargetParser.h
@@ -77,6 +77,7 @@ enum ArchExtKind : uint64_t {
AEK_B16B16 = 1ULL << 46, // FEAT_B16B16
AEK_SMEF16F16 = 1ULL << 47, // FEAT_SMEF16F16
AEK_CSSC = 1ULL << 48, // FEAT_CSSC
+ AEK_RCPC3 = 1ULL << 49, // FEAT_LRCPC3
};
enum class ArchKind {
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 35583cd959bd9..1fedf5b770b62 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -511,6 +511,10 @@ def FeatureITE : SubtargetFeature<"ite", "HasITE",
"true", "Enable Armv9.4-A Instrumentation Extension FEAT_ITE", [FeatureETE,
FeatureTRBE]>;
+def FeatureRCPC3 : SubtargetFeature<"rcpc3", "HasRCPC3",
+ "true", "Enable Armv8.9-A RCPC instructions for A64 and Advanced SIMD and floating-point instruction set (FEAT_LRCPC3)",
+ [FeatureRCPC_IMMO]>;
+
//===----------------------------------------------------------------------===//
// Architectures.
//
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 5cb42e7161e43..319cedc228c5a 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -4552,7 +4552,7 @@ let mayLoad = 0, mayStore = 1 in
class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
RegisterClass regtype, string asm>
: LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
- (ins regtype:$Rt, GPR64sp0:$Rn),
+ (ins regtype:$Rt, GPR64sp:$Rn),
asm, "\t$Rt, [$Rn]">,
Sched<[WriteST]>;
@@ -11762,6 +11762,73 @@ multiclass ComparisonOp<bit isUnsigned, bit isMin, string asm,
// 2022 Armv8.9/Armv9.4 Extensions
//----------------------------------------------------------------------------
+//---
+// RCPC instructions (FEAT_LRCPC3)
+//---
+
+class BaseLRCPC3<bits<2> size, bit V, bits<2> opc, dag oops, dag iops,
+ string asm, string operands, string cstr = "">
+ : I<oops, iops, asm, operands, cstr, []>,
+ Sched<[WriteAtomic]> {
+ bits<5> Rt;
+ bits<5> Rn;
+ let Inst{31-30} = size;
+ let Inst{29-24} = {0,1,1,V,0,1};
+ let Inst{23-22} = opc;
+ let Inst{21} = 0b0;
+ // Inst{20-12}
+ let Inst{11-10} = 0b10;
+ let Inst{9-5} = Rn;
+ let Inst{4-0} = Rt;
+
+ let mayLoad = Inst{22};
+ let mayStore = !not(Inst{22});
+ let hasSideEffects = 0;
+}
+
+class BaseLRCPC3IntegerLoadStorePair<bits<2> size, bits<2> opc, bits<4> opc2,
+ dag oops, dag iops, string asm,
+ string operands, string cstr>
+ : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> {
+ bits<5> Rt2;
+ let Inst{20-16} = Rt2;
+ let Inst{15-12} = opc2;
+}
+
+class BaseLRCPC3IntegerLoadStore<bits<2> size, bits<2> opc, dag oops, dag iops,
+ string asm, string operands, string cstr>
+ : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> {
+ let Inst{20-12} = 0b000000000; // imm9
+}
+
+multiclass LRCPC3NEONLoadStoreUnscaledOffset<bits<2> size, bits<2> opc, RegisterClass regtype,
+ dag oops, dag iops, string asm> {
+ def i : BaseLRCPC3<size, /*V*/1, opc, oops, iops, asm, "\t$Rt, [$Rn{, $simm}]", /*cstr*/""> {
+ bits<9> simm; // signed immediate encoded in imm9=Rt2:imm4
+ let Inst{20-12} = simm;
+ }
+
+ def a : InstAlias<asm # "\t$Rt, [$Rn]",
+ (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
+}
+
+class LRCPC3NEONLdStSingle<bit L, dag oops, dag iops, string asm, string cst>
+ : BaseSIMDLdStSingle<L, /*R*/0b0, /*opcode*/0b100, asm,
+ "\t$Vt$Q, [$Rn]", cst, oops, iops, []>,
+ Sched<[]> {
+ bit Q;
+ let Inst{31} = 0;
+ let Inst{30} = Q;
+ let Inst{23} = 0;
+ let Inst{20-16} = 0b00001;
+ let Inst{12} = 0; // S
+ let Inst{11-10} = 0b01; // size
+
+ let mayLoad = L;
+ let mayStore = !not(L);
+ let hasSideEffects = 1;
+}
+
//---
// Instrumentation Extension (FEAT_ITE)
//---
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 463d7539cdba0..27bf285f9740d 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -234,6 +234,8 @@ def HasMOPS : Predicate<"Subtarget->hasMOPS()">,
AssemblerPredicateWithAll<(all_of FeatureMOPS), "mops">;
def HasITE : Predicate<"Subtarget->hasITE()">,
AssemblerPredicateWithAll<(all_of FeatureITE), "ite">;
+def HasRCPC3 : Predicate<"Subtarget->hasRCPC3()">,
+ AssemblerPredicate<(all_of FeatureRCPC3), "rcpc3">;
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
def IsWindows : Predicate<"Subtarget->isTargetWindows()">;
@@ -3903,6 +3905,21 @@ def STLRX : StoreRelease <0b11, 1, 0, 0, 1, GPR64, "stlr">;
def STLRB : StoreRelease <0b00, 1, 0, 0, 1, GPR32, "stlrb">;
def STLRH : StoreRelease <0b01, 1, 0, 0, 1, GPR32, "stlrh">;
+/*
+Aliases for when offset=0. Note that in contrast to LoadAcquire which has a $Rn
+of type GPR64sp0, we deliberately choose to make $Rn of type GPR64sp and add an
+alias for the case of immediate #0. This is because new STLR versions (from
+LRCPC3 extension) do have a non-zero immediate value, so GPR64sp0 is not
+appropriate anymore (it parses and discards the optional zero). This is not the
+case for LoadAcquire because the new LRCPC3 LDAR instructions are post-indexed,
+and the immediate values are not inside the [] brackets and thus not accepted
+by GPR64sp0 parser.
+*/
+def STLRW0 : InstAlias<"stlr\t$Rt, [$Rn, #0]" , (STLRW GPR32: $Rt, GPR64sp:$Rn)>;
+def STLRX0 : InstAlias<"stlr\t$Rt, [$Rn, #0]" , (STLRX GPR64: $Rt, GPR64sp:$Rn)>;
+def STLRB0 : InstAlias<"stlrb\t$Rt, [$Rn, #0]", (STLRB GPR32: $Rt, GPR64sp:$Rn)>;
+def STLRH0 : InstAlias<"stlrh\t$Rt, [$Rn, #0]", (STLRH GPR32: $Rt, GPR64sp:$Rn)>;
+
def STLXRW : StoreExclusive<0b10, 0, 0, 0, 1, GPR32, "stlxr">;
def STLXRX : StoreExclusive<0b11, 0, 0, 0, 1, GPR64, "stlxr">;
def STLXRB : StoreExclusive<0b00, 0, 0, 0, 1, GPR32, "stlxrb">;
@@ -3937,6 +3954,12 @@ let Predicates = [HasLOR] in {
def STLLRX : StoreRelease <0b11, 1, 0, 0, 0, GPR64, "stllr">;
def STLLRB : StoreRelease <0b00, 1, 0, 0, 0, GPR32, "stllrb">;
def STLLRH : StoreRelease <0b01, 1, 0, 0, 0, GPR32, "stllrh">;
+
+ // Aliases for when offset=0
+ def STLLRW0 : InstAlias<"stllr\t$Rt, [$Rn, #0]", (STLLRW GPR32: $Rt, GPR64sp:$Rn)>;
+ def STLLRX0 : InstAlias<"stllr\t$Rt, [$Rn, #0]", (STLLRX GPR64: $Rt, GPR64sp:$Rn)>;
+ def STLLRB0 : InstAlias<"stllrb\t$Rt, [$Rn, #0]", (STLLRB GPR32: $Rt, GPR64sp:$Rn)>;
+ def STLLRH0 : InstAlias<"stllrh\t$Rt, [$Rn, #0]", (STLLRH GPR32: $Rt, GPR64sp:$Rn)>;
}
//===----------------------------------------------------------------------===//
@@ -8528,6 +8551,53 @@ def RPRFM:
let DecoderNamespace = "Fallback";
}
+//===----------------------------------------------------------------------===//
+// RCPC Instructions (FEAT_LRCPC3)
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasRCPC3] in {
+ // size opc opc2
+ def STILPWpre: BaseLRCPC3IntegerLoadStorePair<0b10, 0b00, 0b0000, (outs GPR64sp:$wback), (ins GPR32:$Rt, GPR32:$Rt2, GPR64sp:$Rn), "stilp", "\t$Rt, $Rt2, [$Rn, #-8]!", "$Rn = $wback">;
+ def STILPXpre: BaseLRCPC3IntegerLoadStorePair<0b11, 0b00, 0b0000, (outs GPR64sp:$wback), (ins GPR64:$Rt, GPR64:$Rt2, GPR64sp:$Rn), "stilp", "\t$Rt, $Rt2, [$Rn, #-16]!", "$Rn = $wback">;
+ def STILPW: BaseLRCPC3IntegerLoadStorePair<0b10, 0b00, 0b0001, (outs), (ins GPR32:$Rt, GPR32:$Rt2, GPR64sp:$Rn), "stilp", "\t$Rt, $Rt2, [$Rn]", "">;
+ def STILPX: BaseLRCPC3IntegerLoadStorePair<0b11, 0b00, 0b0001, (outs), (ins GPR64:$Rt, GPR64:$Rt2, GPR64sp:$Rn), "stilp", "\t$Rt, $Rt2, [$Rn]", "">;
+ def LDIAPPWpre: BaseLRCPC3IntegerLoadStorePair<0b10, 0b01, 0b0000, (outs GPR64sp:$wback, GPR32:$Rt, GPR32:$Rt2), (ins GPR64sp:$Rn), "ldiapp", "\t$Rt, $Rt2, [$Rn], #8", "$Rn = $wback">;
+ def LDIAPPXpre: BaseLRCPC3IntegerLoadStorePair<0b11, 0b01, 0b0000, (outs GPR64sp:$wback, GPR64:$Rt, GPR64:$Rt2), (ins GPR64sp:$Rn), "ldiapp", "\t$Rt, $Rt2, [$Rn], #16", "$Rn = $wback">;
+ def LDIAPPW: BaseLRCPC3IntegerLoadStorePair<0b10, 0b01, 0b0001, (outs GPR32:$Rt, GPR32:$Rt2), (ins GPR64sp0:$Rn), "ldiapp", "\t$Rt, $Rt2, [$Rn]", "">;
+ def LDIAPPX: BaseLRCPC3IntegerLoadStorePair<0b11, 0b01, 0b0001, (outs GPR64:$Rt, GPR64:$Rt2), (ins GPR64sp0:$Rn), "ldiapp", "\t$Rt, $Rt2, [$Rn]", "">;
+
+ // Aliases for when offset=0
+ def : InstAlias<"stilp\t$Rt, $Rt2, [$Rn, #0]", (STILPW GPR32: $Rt, GPR32: $Rt2, GPR64sp:$Rn)>;
+ def : InstAlias<"stilp\t$Rt, $Rt2, [$Rn, #0]", (STILPX GPR64: $Rt, GPR64: $Rt2, GPR64sp:$Rn)>;
+
+ // size opc
+ def STLRWpre: BaseLRCPC3IntegerLoadStore<0b10, 0b10, (outs GPR64sp:$wback), (ins GPR32:$Rt, GPR64sp:$Rn), "stlr", "\t$Rt, [$Rn, #-4]!", "$Rn = $wback">;
+ def STLRXpre: BaseLRCPC3IntegerLoadStore<0b11, 0b10, (outs GPR64sp:$wback), (ins GPR64:$Rt, GPR64sp:$Rn), "stlr", "\t$Rt, [$Rn, #-8]!", "$Rn = $wback">;
+ def LDAPRWpre: BaseLRCPC3IntegerLoadStore<0b10, 0b11, (outs GPR64sp:$wback, GPR32:$Rt), (ins GPR64sp:$Rn), "ldapr", "\t$Rt, [$Rn], #4", "$Rn = $wback">;
+ def LDAPRXpre: BaseLRCPC3IntegerLoadStore<0b11, 0b11, (outs GPR64sp:$wback, GPR64:$Rt), (ins GPR64sp:$Rn), "ldapr", "\t$Rt, [$Rn], #8", "$Rn = $wback">;
+}
+
+let Predicates = [HasRCPC3, HasNEON] in {
+ // size opc regtype
+ defm STLURb: LRCPC3NEONLoadStoreUnscaledOffset<0b00, 0b00, FPR8 , (outs), (ins FPR8 :$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">;
+ defm STLURh: LRCPC3NEONLoadStoreUnscaledOffset<0b01, 0b00, FPR16 , (outs), (ins FPR16 :$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">;
+ defm STLURs: LRCPC3NEONLoadStoreUnscaledOffset<0b10, 0b00, FPR32 , (outs), (ins FPR32 :$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">;
+ defm STLURd: LRCPC3NEONLoadStoreUnscaledOffset<0b11, 0b00, FPR64 , (outs), (ins FPR64 :$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">;
+ defm STLURq: LRCPC3NEONLoadStoreUnscaledOffset<0b00, 0b10, FPR128, (outs), (ins FPR128:$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">;
+ defm LDAPURb: LRCPC3NEONLoadStoreUnscaledOffset<0b00, 0b01, FPR8 , (outs FPR8 :$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">;
+ defm LDAPURh: LRCPC3NEONLoadStoreUnscaledOffset<0b01, 0b01, FPR16 , (outs FPR16 :$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">;
+ defm LDAPURs: LRCPC3NEONLoadStoreUnscaledOffset<0b10, 0b01, FPR32 , (outs FPR32 :$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">;
+ defm LDAPURd: LRCPC3NEONLoadStoreUnscaledOffset<0b11, 0b01, FPR64 , (outs FPR64 :$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">;
+ defm LDAPURq: LRCPC3NEONLoadStoreUnscaledOffset<0b00, 0b11, FPR128, (outs FPR128:$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">;
+
+ // L
+ def STL1: LRCPC3NEONLdStSingle<0b0, (outs), (ins VecListOned:$Vt, VectorIndexD:$Q, GPR64sp:$Rn) , "stl1", "">;
+ def LDAP1: LRCPC3NEONLdStSingle<0b1, (outs VecListOned:$dst), (ins VecListOned:$Vt, VectorIndexD:$Q, GPR64sp0:$Rn), "ldap1", "$Vt = $dst">;
+
+ // Aliases for when offset=0
+ def : InstAlias<"stl1\t$Vt$Q, [$Rn, #0]", (STL1 VecListOned:$Vt, VectorIndexD:$Q, GPR64sp:$Rn)>;
+}
+
include "AArch64InstrAtomics.td"
include "AArch64SVEInstrInfo.td"
include "AArch64SMEInstrInfo.td"
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 55f0f6f9b2b8e..9cf92e7171204 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -7547,6 +7547,15 @@ unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
case MCK__HASH_8:
ExpectedVal = 8;
break;
+ case MCK__HASH__MINUS_4:
+ ExpectedVal = -4;
+ break;
+ case MCK__HASH__MINUS_8:
+ ExpectedVal = -8;
+ break;
+ case MCK__HASH__MINUS_16:
+ ExpectedVal = -16;
+ break;
case MCK_MPR:
// If the Kind is a token for the MPR register class which has the "za"
// register (SME accumulator array), check if the asm is a literal "za"
diff --git a/llvm/test/MC/AArch64/arm64-memory.s b/llvm/test/MC/AArch64/arm64-memory.s
index fd4630d4f9cca..93c96c37f8cb5 100644
--- a/llvm/test/MC/AArch64/arm64-memory.s
+++ b/llvm/test/MC/AArch64/arm64-memory.s
@@ -498,11 +498,23 @@ foo:
stlrb w3, [x6]
stlrh w3, [x6]
+ stlr w3, [x6, #0]
+ stlr x3, [x6, 0]
+ stlrb w3, [sp]
+ stlrb w3, [sp, #0]
+ stlrb w3, [sp, 0]
+
; CHECK: stlr w3, [x6] ; encoding: [0xc3,0xfc,0x9f,0x88]
; CHECK: stlr x3, [x6] ; encoding: [0xc3,0xfc,0x9f,0xc8]
; CHECK: stlrb w3, [x6] ; encoding: [0xc3,0xfc,0x9f,0x08]
; CHECK: stlrh w3, [x6] ; encoding: [0xc3,0xfc,0x9f,0x48]
+; CHECK: stlr w3, [x6] ; encoding: [0xc3,0xfc,0x9f,0x88]
+; CHECK: stlr x3, [x6] ; encoding: [0xc3,0xfc,0x9f,0xc8]
+; CHECK: stlrb w3, [sp] ; encoding: [0xe3,0xff,0x9f,0x08]
+; CHECK: stlrb w3, [sp] ; encoding: [0xe3,0xff,0x9f,0x08]
+; CHECK: stlrb w3, [sp] ; encoding: [0xe3,0xff,0x9f,0x08]
+
;-----------------------------------------------------------------------------
; Load-acquire/Store-release exclusive
;-----------------------------------------------------------------------------
diff --git a/llvm/test/MC/AArch64/armv8.9a-lrcpc3.s b/llvm/test/MC/AArch64/armv8.9a-lrcpc3.s
new file mode 100644
index 0000000000000..263f200428b68
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv8.9a-lrcpc3.s
@@ -0,0 +1,143 @@
+// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+rcpc3 < %s | FileCheck %s
+// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.9a -mattr=+rcpc3 < %s | FileCheck %s
+// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v9.4a -mattr=+rcpc3 < %s | FileCheck %s
+
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.9a < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v9.4a < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s
+
+ stilp w24, w0, [x16, #-8]!
+// CHECK: stilp w24, w0, [x16, #-8]! // encoding: [0x18,0x0a,0x00,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stilp w24, w0, [x16, -8]!
+// CHECK: stilp w24, w0, [x16, #-8]! // encoding: [0x18,0x0a,0x00,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stilp x25, x1, [x17, -16]!
+// CHECK: stilp x25, x1, [x17, #-16]! // encoding: [0x39,0x0a,0x01,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stilp x25, x1, [x17, #-16]!
+// CHECK: stilp x25, x1, [x17, #-16]! // encoding: [0x39,0x0a,0x01,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stilp w26, w2, [x18]
+// CHECK: stilp w26, w2, [x18] // encoding: [0x5a,0x1a,0x02,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stilp w26, w2, [x18, #0]
+// CHECK: stilp w26, w2, [x18] // encoding: [0x5a,0x1a,0x02,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stilp x27, x3, [sp]
+// CHECK: stilp x27, x3, [sp] // encoding: [0xfb,0x1b,0x03,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stilp x27, x3, [sp, 0]
+// CHECK: stilp x27, x3, [sp] // encoding: [0xfb,0x1b,0x03,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp w28, w4, [x20], #8
+// CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp w28, w4, [x20, #0], #8
+// CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp w28, w4, [x20], 8
+// CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp w28, w4, [x20, 0], 8
+// CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp x29, x5, [x21], #16
+// CHECK: ldiapp x29, x5, [x21], #16 // encoding: [0xbd,0x0a,0x45,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp x29, x5, [x21], 16
+// CHECK: ldiapp x29, x5, [x21], #16 // encoding: [0xbd,0x0a,0x45,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp w30, w6, [sp]
+// CHECK: ldiapp w30, w6, [sp] // encoding: [0xfe,0x1b,0x46,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp w30, w6, [sp, #0]
+// CHECK: ldiapp w30, w6, [sp] // encoding: [0xfe,0x1b,0x46,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp xzr, x7, [x23]
+// CHECK: ldiapp xzr, x7, [x23] // encoding: [0xff,0x1a,0x47,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldiapp xzr, x7, [x23, 0]
+// CHECK: ldiapp xzr, x7, [x23] // encoding: [0xff,0x1a,0x47,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+
+ stlr w3, [x15, #-4]!
+// CHECK: stlr w3, [x15, #-4]! // encoding: [0xe3,0x09,0x80,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stlr w3, [x15, -4]!
+// CHECK: stlr w3, [x15, #-4]! // encoding: [0xe3,0x09,0x80,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stlr x3, [x15, #-8]!
+// CHECK: stlr x3, [x15, #-8]! // encoding: [0xe3,0x09,0x80,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stlr x3, [sp, -8]!
+// CHECK: stlr x3, [sp, #-8]! // encoding: [0xe3,0x0b,0x80,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldapr w3, [sp], #4
+// CHECK: ldapr w3, [sp], #4 // encoding: [0xe3,0x0b,0xc0,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldapr w3, [x15], 4
+// CHECK: ldapr w3, [x15], #4 // encoding: [0xe3,0x09,0xc0,0x99]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldapr x3, [x15], #8
+// CHECK: ldapr x3, [x15], #8 // encoding: [0xe3,0x09,0xc0,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldapr x3, [x15], 8
+// CHECK: ldapr x3, [x15], #8 // encoding: [0xe3,0x09,0xc0,0xd9]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+
+ stlur b3, [x15, #-1]
+// CHECK: stlur b3, [x15, #-1] // encoding: [0xe3,0xf9,0x1f,0x1d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stlur h3, [x15, #2]
+// CHECK: stlur h3, [x15, #2] // encoding: [0xe3,0x29,0x00,0x5d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stlur s3, [x15, #-3]
+// CHECK: stlur s3, [x15, #-3] // encoding: [0xe3,0xd9,0x1f,0x9d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stlur d3, [sp, #4]
+// CHECK: stlur d3, [sp, #4] // encoding: [0xe3,0x4b,0x00,0xdd]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stlur q3, [x15, #-5]
+// CHECK: stlur q3, [x15, #-5] // encoding: [0xe3,0xb9,0x9f,0x1d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldapur b3, [x15, #6]
+// CHECK: ldapur b3, [x15, #6] // encoding: [0xe3,0x69,0x40,0x1d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldapur h3, [x15, #-7]
+// CHECK: ldapur h3, [x15, #-7] // encoding: [0xe3,0x99,0x5f,0x5d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldapur s3, [x15, #8]
+// CHECK: ldapur s3, [x15, #8] // encoding: [0xe3,0x89,0x40,0x9d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldapur d3, [x15, #-9]
+// CHECK: ldapur d3, [x15, #-9] // encoding: [0xe3,0x79,0x5f,0xdd]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldapur q3, [sp, #10]
+// CHECK: ldapur q3, [sp, #10] // encoding: [0xe3,0xab,0xc0,0x1d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+
+ stl1 { v3.d }[0], [x15]
+// CHECK: stl1 { v3.d }[0], [x15] // encoding: [0xe3,0x85,0x01,0x0d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stl1 { v3.d }[0], [x15, #0]
+// CHECK: stl1 { v3.d }[0], [x15] // encoding: [0xe3,0x85,0x01,0x0d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stl1 { v3.d }[1], [sp]
+// CHECK: stl1 { v3.d }[1], [sp] // encoding: [0xe3,0x87,0x01,0x4d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ stl1 { v3.d }[1], [sp, 0]
+// CHECK: stl1 { v3.d }[1], [sp] // encoding: [0xe3,0x87,0x01,0x4d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldap1 { v3.d }[0], [sp]
+// CHECK: ldap1 { v3.d }[0], [sp] // encoding: [0xe3,0x87,0x41,0x0d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldap1 { v3.d }[0], [sp, #0]
+// CHECK: ldap1 { v3.d }[0], [sp] // encoding: [0xe3,0x87,0x41,0x0d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldap1 { v3.d }[1], [x15]
+// CHECK: ldap1 { v3.d }[1], [x15] // encoding: [0xe3,0x85,0x41,0x4d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
+ ldap1 { v3.d }[1], [x15, 0]
+// CHECK: ldap1 { v3.d }[1], [x15] // encoding: [0xe3,0x85,0x41,0x4d]
+// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3
diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.9a-lrcpc3.txt b/llvm/test/MC/Disassembler/AArch64/armv8.9a-lrcpc3.txt
new file mode 100644
index 0000000000000..644e032cd79cd
--- /dev/null
+++ b/llvm/test/MC/Disassembler/AArch64/armv8.9a-lrcpc3.txt
@@ -0,0 +1,113 @@
+# RUN: llvm-mc -triple aarch64-none-linux-gnu -disassemble -show-encoding -mattr=+rcpc3 < %s | FileCheck %s
+# RUN: llvm-mc -triple aarch64-none-linux-gnu -disassemble -show-encoding -mattr=+v8.9a -mattr=+rcpc3 < %s | FileCheck %s
+# RUN: llvm-mc -triple aarch64-none-linux-gnu -disassemble -show-encoding -mattr=+v9.4a -mattr=+rcpc3 < %s | FileCheck %s
+
+# RUN: not llvm-mc -triple aarch64-none-linux-gnu -disassemble < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s
+# RUN: not llvm-mc -triple aarch64-none-linux-gnu -disassemble -mattr=+v8.9a < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s
+# RUN: not llvm-mc -triple aarch64-none-linux-gnu -disassemble -mattr=+v9.4a < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s
+
+[0x18,0x0a,0x00,0x99]
+# CHECK: stilp w24, w0, [x16, #-8]! // encoding: [0x18,0x0a,0x00,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x18,0x0a,0x00,0x99]
+# CHECK: stilp w24, w0, [x16, #-8]! // encoding: [0x18,0x0a,0x00,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x39,0x0a,0x01,0xd9]
+# CHECK: stilp x25, x1, [x17, #-16]! // encoding: [0x39,0x0a,0x01,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x39,0x0a,0x01,0xd9]
+# CHECK: stilp x25, x1, [x17, #-16]! // encoding: [0x39,0x0a,0x01,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x5a,0x1a,0x02,0x99]
+# CHECK: stilp w26, w2, [x18] // encoding: [0x5a,0x1a,0x02,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xfb,0x1b,0x03,0xd9]
+# CHECK: stilp x27, x3, [sp] // encoding: [0xfb,0x1b,0x03,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x9c,0x0a,0x44,0x99]
+# CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0x9c,0x0a,0x44,0x99]
+# CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xbd,0x0a,0x45,0xd9]
+# CHECK: ldiapp x29, x5, [x21], #16 // encoding: [0xbd,0x0a,0x45,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xbd,0x0a,0x45,0xd9]
+# CHECK: ldiapp x29, x5, [x21], #16 // encoding: [0xbd,0x0a,0x45,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xfe,0x1b,0x46,0x99]
+# CHECK: ldiapp w30, w6, [sp] // encoding: [0xfe,0x1b,0x46,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xff,0x1a,0x47,0xd9]
+# CHECK: ldiapp xzr, x7, [x23] // encoding: [0xff,0x1a,0x47,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0xe3,0x09,0x80,0x99]
+# CHECK: stlr w3, [x15, #-4]! // encoding: [0xe3,0x09,0x80,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x09,0x80,0x99]
+# CHECK: stlr w3, [x15, #-4]! // encoding: [0xe3,0x09,0x80,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x09,0x80,0xd9]
+# CHECK: stlr x3, [x15, #-8]! // encoding: [0xe3,0x09,0x80,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x0b,0x80,0xd9]
+# CHECK: stlr x3, [sp, #-8]! // encoding: [0xe3,0x0b,0x80,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x0b,0xc0,0x99]
+# CHECK: ldapr w3, [sp], #4 // encoding: [0xe3,0x0b,0xc0,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x09,0xc0,0x99]
+# CHECK: ldapr w3, [x15], #4 // encoding: [0xe3,0x09,0xc0,0x99]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x09,0xc0,0xd9]
+# CHECK: ldapr x3, [x15], #8 // encoding: [0xe3,0x09,0xc0,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x09,0xc0,0xd9]
+# CHECK: ldapr x3, [x15], #8 // encoding: [0xe3,0x09,0xc0,0xd9]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0xe3,0xf9,0x1f,0x1d]
+# CHECK: stlur b3, [x15, #-1] // encoding: [0xe3,0xf9,0x1f,0x1d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x29,0x00,0x5d]
+# CHECK: stlur h3, [x15, #2] // encoding: [0xe3,0x29,0x00,0x5d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0xd9,0x1f,0x9d]
+# CHECK: stlur s3, [x15, #-3] // encoding: [0xe3,0xd9,0x1f,0x9d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x4b,0x00,0xdd]
+# CHECK: stlur d3, [sp, #4] // encoding: [0xe3,0x4b,0x00,0xdd]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0xb9,0x9f,0x1d]
+# CHECK: stlur q3, [x15, #-5] // encoding: [0xe3,0xb9,0x9f,0x1d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x69,0x40,0x1d]
+# CHECK: ldapur b3, [x15, #6] // encoding: [0xe3,0x69,0x40,0x1d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x99,0x5f,0x5d]
+# CHECK: ldapur h3, [x15, #-7] // encoding: [0xe3,0x99,0x5f,0x5d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x89,0x40,0x9d]
+# CHECK: ldapur s3, [x15, #8] // encoding: [0xe3,0x89,0x40,0x9d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x79,0x5f,0xdd]
+# CHECK: ldapur d3, [x15, #-9] // encoding: [0xe3,0x79,0x5f,0xdd]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0xab,0xc0,0x1d]
+# CHECK: ldapur q3, [sp, #10] // encoding: [0xe3,0xab,0xc0,0x1d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0xe3,0x85,0x01,0x0d]
+# CHECK: stl1 { v3.d }[0], [x15] // encoding: [0xe3,0x85,0x01,0x0d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x87,0x01,0x4d]
+# CHECK: stl1 { v3.d }[1], [sp] // encoding: [0xe3,0x87,0x01,0x4d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x87,0x41,0x0d]
+# CHECK: ldap1 { v3.d }[0], [sp] // encoding: [0xe3,0x87,0x41,0x0d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
+[0xe3,0x85,0x41,0x4d]
+# CHECK: ldap1 { v3.d }[1], [x15] // encoding: [0xe3,0x85,0x41,0x4d]
+# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding
diff --git a/llvm/unittests/Support/TargetParserTest.cpp b/llvm/unittests/Support/TargetParserTest.cpp
index 747aac17d69f9..a51a07b7b1294 100644
--- a/llvm/unittests/Support/TargetParserTest.cpp
+++ b/llvm/unittests/Support/TargetParserTest.cpp
@@ -1606,7 +1606,8 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
AArch64::AEK_SME, AArch64::AEK_SMEF64F64, AArch64::AEK_SMEI16I64,
AArch64::AEK_SME2, AArch64::AEK_HBC, AArch64::AEK_MOPS,
AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1, AArch64::AEK_SME2p1,
- AArch64::AEK_B16B16, AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC};
+ AArch64::AEK_B16B16, AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC,
+ AArch64::AEK_RCPC3};
std::vector<StringRef> Features;
@@ -1672,6 +1673,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
EXPECT_TRUE(llvm::is_contained(Features, "+mops"));
EXPECT_TRUE(llvm::is_contained(Features, "+perfmon"));
EXPECT_TRUE(llvm::is_contained(Features, "+cssc"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+rcpc3"));
// Assuming we listed every extension above, this should produce the same
// result. (note that AEK_NONE doesn't have a name so it won't be in the
More information about the cfe-commits
mailing list