[llvm] 85f3d5c - [AArch64] Add assembly/disassembly for SVE COMPACT (b/h) and EXPAND (#114053)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 30 05:11:37 PDT 2024
Author: SpencerAbson
Date: 2024-10-30T12:11:34Z
New Revision: 85f3d5ca4994ff70a72f6ad81948bf4721e15ef1
URL: https://github.com/llvm/llvm-project/commit/85f3d5ca4994ff70a72f6ad81948bf4721e15ef1
DIFF: https://github.com/llvm/llvm-project/commit/85f3d5ca4994ff70a72f6ad81948bf4721e15ef1.diff
LOG: [AArch64] Add assembly/disassembly for SVE COMPACT (b/h) and EXPAND (#114053)
This patch adds assembly/disassembly support for the following SVE2.2
instructions
- COMPACT (byte, halfword)
- EXPAND
- Allow selection of `COMPACT` (word/halfword) in streaming mode if the
target has FEAT_SME2p2 (see [COMPACT ](
https://developer.arm.com/documentation/ddi0602/2024-09/SVE-Instructions/COMPACT--Copy-active-vector-elements-to-lower-numbered-elements-))
- Rename predicates guarding instructions that are illegal in streaming
SVE mode without FEAT_SME2p2
- In accordance with
https://developer.arm.com/documentation/ddi0602/2024-09/SVE-Instructions
Co-authored-by: Marian Lukac marian.lukac at arm.com
Added:
llvm/test/MC/AArch64/SVE2p2/compact-diagnostics.s
llvm/test/MC/AArch64/SVE2p2/compact.s
llvm/test/MC/AArch64/SVE2p2/expand-diagnostics.s
llvm/test/MC/AArch64/SVE2p2/expand.s
Modified:
llvm/lib/Target/AArch64/AArch64.td
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
llvm/lib/Target/AArch64/SVEInstrFormats.td
llvm/test/MC/AArch64/SVE/compact-diagnostics.s
llvm/test/MC/AArch64/SVE/compact.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 9bb508b783c36a..6854cccaafa1d7 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -73,7 +73,8 @@ def SVEUnsupported : AArch64Unsupported {
SVE2Unsupported.F);
}
-let F = [HasSME2p2, HasSVE2p2orSME2p2] in
+let F = [HasSME2p2, HasSVE2p2orSME2p2, HasNonStreamingSVEorSME2p2,
+ HasNonStreamingSVE2p2orSME2p2] in
def SME2p2Unsupported : AArch64Unsupported;
def SME2p1Unsupported : AArch64Unsupported {
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 6194de2d56b630..457e918728ae27 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -244,7 +244,7 @@ def HasSVEorSME
: Predicate<"Subtarget->hasSVE() || (Subtarget->isStreaming() && Subtarget->hasSME())">,
AssemblerPredicateWithAll<(any_of FeatureSVE, FeatureSME),
"sve or sme">;
-def HasSVEorSME2p2
+def HasNonStreamingSVEorSME2p2
: Predicate<"(Subtarget->isSVEAvailable() && Subtarget->hasSVE()) ||"
"(Subtarget->isSVEorStreamingSVEAvailable() && Subtarget->hasSME2p2())">,
AssemblerPredicateWithAll<(any_of FeatureSVE, FeatureSME2p2),
@@ -281,6 +281,11 @@ def HasSMEF16F16orSMEF8F16
: Predicate<"Subtarget->isStreaming() && (Subtarget->hasSMEF16F16() || Subtarget->hasSMEF8F16())">,
AssemblerPredicateWithAll<(any_of FeatureSMEF16F16, FeatureSMEF8F16),
"sme-f16f16 or sme-f8f16">;
+def HasNonStreamingSVE2p2orSME2p2
+ : Predicate<"(Subtarget->isSVEAvailable() && Subtarget->hasSVE2p2()) ||"
+ "(Subtarget->isSVEorStreamingSVEAvailable() && Subtarget->hasSME2p2())">,
+ AssemblerPredicateWithAll<(any_of FeatureSVE2p2, FeatureSME2p2),
+ "sme2p2 or sve2p2">;
// A subset of NEON instructions are legal in Streaming SVE execution mode,
// so don't need the additional check for 'isNeonAvailable'.
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 5c5ae898a8ac02..c9ee2d0059a9fe 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -928,9 +928,10 @@ let Predicates = [HasSVEorSME] in {
defm SPLICE_ZPZ : sve_int_perm_splice<"splice", AArch64splice>;
} // End HasSVEorSME
-let Predicates = [HasSVE] in {
- defm COMPACT_ZPZ : sve_int_perm_compact<"compact", int_aarch64_sve_compact>;
-} // End HasSVE
+// COMPACT - word and doubleword
+let Predicates = [HasNonStreamingSVEorSME2p2] in {
+ defm COMPACT_ZPZ : sve_int_perm_compact_sd<"compact", int_aarch64_sve_compact>;
+}
let Predicates = [HasSVEorSME] in {
defm INSR_ZR : sve_int_perm_insrs<"insr", AArch64insr>;
@@ -4305,6 +4306,16 @@ let Predicates = [HasSVE2p2orSME2p2] in {
} // End HasSME2p2orSVE2p2
+//===----------------------------------------------------------------------===//
+// SME2.2 or SVE2.2 instructions - Legal in streaming mode iff target has SME2p2
+//===----------------------------------------------------------------------===//
+let Predicates = [HasNonStreamingSVE2p2orSME2p2] in {
+ // SVE2 EXPAND
+ defm EXPAND_ZPZ : sve2_int_perm_expand<"expand">;
+ // SVE COMPACT - byte and halfword
+ defm COMPACT_ZPZ : sve_int_perm_compact_bh<"compact">;
+}
+
//===----------------------------------------------------------------------===//
// SVE2 FP8 instructions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 88a0983aa1480d..3637a63684a0de 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -7315,6 +7315,32 @@ multiclass sve2_int_perm_splice_cons<string asm> {
def _D : sve2_int_perm_splice_cons<0b11, asm, ZPR64, ZZ_d>;
}
+class sve2_int_perm_expand<bits<2> sz, string asm,
+ ZPRRegOp zprty>
+: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
+ asm, "\t$Zd, $Pg, $Zn",
+ "",
+ []>, Sched<[]> {
+ bits<3> Pg;
+ bits<5> Zn;
+ bits<5> Zd;
+ let Inst{31-24} = 0b00000101;
+ let Inst{23-22} = sz;
+ let Inst{21-13} = 0b110001100;
+ let Inst{12-10} = Pg;
+ let Inst{9-5} = Zn;
+ let Inst{4-0} = Zd;
+
+ let hasSideEffects = 0;
+}
+
+multiclass sve2_int_perm_expand<string asm> {
+ def _B : sve2_int_perm_expand<0b00, asm, ZPR8>;
+ def _H : sve2_int_perm_expand<0b01, asm, ZPR16>;
+ def _S : sve2_int_perm_expand<0b10, asm, ZPR32>;
+ def _D : sve2_int_perm_expand<0b11, asm, ZPR64>;
+}
+
class sve_int_perm_rev<bits<2> sz8_64, bits<2> opc, string asm,
ZPRRegOp zprty>
: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
@@ -7476,7 +7502,7 @@ multiclass sve_int_perm_cpy_v<string asm, SDPatternOperator op> {
(!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
}
-class sve_int_perm_compact<bit sz, string asm, ZPRRegOp zprty>
+class sve_int_perm_compact<bits<2> sz, string asm, ZPRRegOp zprty>
: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
asm, "\t$Zd, $Pg, $Zn",
"",
@@ -7484,8 +7510,8 @@ class sve_int_perm_compact<bit sz, string asm, ZPRRegOp zprty>
bits<3> Pg;
bits<5> Zd;
bits<5> Zn;
- let Inst{31-23} = 0b000001011;
- let Inst{22} = sz;
+ let Inst{31-24} = 0b00000101;
+ let Inst{23-22} = sz;
let Inst{21-13} = 0b100001100;
let Inst{12-10} = Pg;
let Inst{9-5} = Zn;
@@ -7494,9 +7520,9 @@ class sve_int_perm_compact<bit sz, string asm, ZPRRegOp zprty>
let hasSideEffects = 0;
}
-multiclass sve_int_perm_compact<string asm, SDPatternOperator op> {
- def _S : sve_int_perm_compact<0b0, asm, ZPR32>;
- def _D : sve_int_perm_compact<0b1, asm, ZPR64>;
+multiclass sve_int_perm_compact_sd<string asm, SDPatternOperator op> {
+ def _S : sve_int_perm_compact<0b10, asm, ZPR32>;
+ def _D : sve_int_perm_compact<0b11, asm, ZPR64>;
def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
@@ -7504,6 +7530,11 @@ multiclass sve_int_perm_compact<string asm, SDPatternOperator op> {
def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
}
+multiclass sve_int_perm_compact_bh<string asm> {
+ def _B : sve_int_perm_compact<0b00, asm, ZPR8>;
+ def _H : sve_int_perm_compact<0b01, asm, ZPR16>;
+}
+
//===----------------------------------------------------------------------===//
// SVE Memory - Contiguous Load Group
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/SVE/compact-diagnostics.s b/llvm/test/MC/AArch64/SVE/compact-diagnostics.s
index a3d86267d917b5..b8ff8cc46201f2 100644
--- a/llvm/test/MC/AArch64/SVE/compact-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/compact-diagnostics.s
@@ -28,12 +28,12 @@ compact z31.s, p7, z31.d
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
compact z31.b, p7, z31.b
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
// CHECK-NEXT: compact z31.b, p7, z31.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
compact z31.h, p7, z31.h
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
// CHECK-NEXT: compact z31.h, p7, z31.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE/compact.s b/llvm/test/MC/AArch64/SVE/compact.s
index ff815980781d79..a9b47dea246bee 100644
--- a/llvm/test/MC/AArch64/SVE/compact.s
+++ b/llvm/test/MC/AArch64/SVE/compact.s
@@ -12,11 +12,11 @@
compact z31.s, p7, z31.s
// CHECK-INST: compact z31.s, p7, z31.s
// CHECK-ENCODING: [0xff,0x9f,0xa1,0x05]
-// CHECK-ERROR: instruction requires: sve
+// CHECK-ERROR: instruction requires: sve or sme2p2
// CHECK-UNKNOWN: 05a19fff <unknown>
compact z31.d, p7, z31.d
// CHECK-INST: compact z31.d, p7, z31.d
// CHECK-ENCODING: [0xff,0x9f,0xe1,0x05]
-// CHECK-ERROR: instruction requires: sve
+// CHECK-ERROR: instruction requires: sve or sme2p2
// CHECK-UNKNOWN: 05e19fff <unknown>
diff --git a/llvm/test/MC/AArch64/SVE2p2/compact-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/compact-diagnostics.s
new file mode 100644
index 00000000000000..acf00e7f7a600f
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/compact-diagnostics.s
@@ -0,0 +1,65 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+compact z31.h, p7, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: compact z31.h, p7, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+compact z31.b, p7, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: compact z31.b, p7, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid predicate operation
+
+compact z23.b, p7/m, z13.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: compact z23.b, p7/m, z13.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+compact z23.b, p7.b, z13.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: compact z23.b, p7.b, z13.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+compact z23.h, p7/z, z13.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: compact z23.h, p7/z, z13.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+compact z23.h, p7.h, z13.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: compact z23.h, p7.h, z13.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Predicate not in restricted predicate range
+
+compact z23.b, p8, z13.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: compact z23.b, p8, z13.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+compact z23.h, p8, z13.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: compact z23.h, p8, z13.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z31.b, p7/z, z6.b
+compact z31.b, p7, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: compact z31.b, p7, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z31, z6
+compact z31.h, p7, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: compact z31.h, p7, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE2p2/compact.s b/llvm/test/MC/AArch64/SVE2p2/compact.s
new file mode 100644
index 00000000000000..0170b3832bea67
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/compact.s
@@ -0,0 +1,33 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p2 < %s \
+// RUN: | llvm-objdump -d --mattr=+sve2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p2 < %s \
+// RUN: | llvm-objdump -d --mattr=-sve2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p2 -disassemble -show-encoding \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+compact z0.b, p0, z0.b // 00000101-00100001-10000000-00000000
+// CHECK-INST: compact z0.b, p0, z0.b
+// CHECK-ENCODING: [0x00,0x80,0x21,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05218000 <unknown>
+
+compact z21.b, p5, z10.b // 00000101-00100001-10010101-01010101
+// CHECK-INST: compact z21.b, p5, z10.b
+// CHECK-ENCODING: [0x55,0x95,0x21,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05219555 <unknown>
+
+compact z31.h, p7, z31.h // 00000101-01100001-10011111-11111111
+// CHECK-INST: compact z31.h, p7, z31.h
+// CHECK-ENCODING: [0xff,0x9f,0x61,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05619fff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/expand-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/expand-diagnostics.s
new file mode 100644
index 00000000000000..b9a95f399a168a
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/expand-diagnostics.s
@@ -0,0 +1,120 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid element widths.
+
+expand z23.b, p3, z13.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: expand z23.b, p3, z13.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.h, p3, z13.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: expand z23.h, p3, z13.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.s, p3, z13.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: expand z23.s, p3, z13.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.d, p3, z13.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: expand z23.d, p3, z13.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.q, p3, z13.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: expand z23.q, p3, z13.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid predicate operation
+
+expand z23.b, p3/z, z13.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: expand z23.b, p3/z, z13.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.b, p3.b, z13.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.b, p3.b, z13.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.h, p3/m, z13.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: expand z23.h, p3/m, z13.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.h, p3.h, z13.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.h, p3.h, z13.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.s, p3/z, z13.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: expand z23.s, p3/z, z13.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.s, p3.s, z13.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.s, p3.s, z13.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.d, p3/m, z13.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: expand z23.d, p3/m, z13.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.d, p3.d, z13.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.d, p3.d, z13.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Predicate not in restricted predicate range
+
+expand z23.b, p8, z13.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.b, p8, z13.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.b, p3.b, z13.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.b, p3.b, z13.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.h, p8, z13.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.h, p8, z13.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.h, p3.h, z13.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.h, p3.h, z13.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}
+
+expand z23.s, p8, z13.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.s, p8, z13.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+expand z23.d, p8, z13.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: expand z23.d, p8, z13.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z31, z6
+expand z31.b, p7, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: expand z31.b, p7, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z31.b, p0/z, z6.b
+expand z31.b, p0, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: expand z31.b, p0, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE2p2/expand.s b/llvm/test/MC/AArch64/SVE2p2/expand.s
new file mode 100644
index 00000000000000..7523978380fbd7
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/expand.s
@@ -0,0 +1,39 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p2 < %s \
+// RUN: | llvm-objdump -d --mattr=+sve2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p2 < %s \
+// RUN: | llvm-objdump -d --mattr=-sve2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p2 -disassemble -show-encoding \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+expand z0.b, p0, z0.b // 00000101-00110001-10000000-00000000
+// CHECK-INST: expand z0.b, p0, z0.b
+// CHECK-ENCODING: [0x00,0x80,0x31,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05318000 <unknown>
+
+expand z21.h, p5, z10.h // 00000101-01110001-10010101-01010101
+// CHECK-INST: expand z21.h, p5, z10.h
+// CHECK-ENCODING: [0x55,0x95,0x71,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05719555 <unknown>
+
+expand z23.s, p3, z13.s // 00000101-10110001-10001101-10110111
+// CHECK-INST: expand z23.s, p3, z13.s
+// CHECK-ENCODING: [0xb7,0x8d,0xb1,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05b18db7 <unknown>
+
+expand z31.d, p7, z31.d // 00000101-11110001-10011111-11111111
+// CHECK-INST: expand z31.d, p7, z31.d
+// CHECK-ENCODING: [0xff,0x9f,0xf1,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05f19fff <unknown>
\ No newline at end of file
More information about the llvm-commits
mailing list