[llvm] [AArch64] Add assembly/disassembly for zeroing SVE2 integer instructions (PR #113473)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 24 04:01:52 PDT 2024


https://github.com/SpencerAbson updated https://github.com/llvm/llvm-project/pull/113473

>From e74b114897c800e8920988b1732b4446d6d12c5e Mon Sep 17 00:00:00 2001
From: Spencer Abson <Spencer.Abson at arm.com>
Date: Wed, 23 Oct 2024 15:57:22 +0000
Subject: [PATCH] [AArch64] Add assembly/disassembly for zeroing SVE2 integer
 instructions

This patch adds assembly/disassembly for the following SVE2.2 instructions
	- SQABS  (zeroing)
	- SQNEG  (zeroing)
	- URECPE (zeroing)
	- USQRTE (zeroing)

- Refactor the existing merging forms to remove the now redundant bit 17 argument.
- In accordance with: https://developer.arm.com/documentation/ddi0602/latest/
---
 llvm/lib/Target/AArch64/AArch64.td            |  9 +++-
 .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 13 +++--
 llvm/lib/Target/AArch64/SVEInstrFormats.td    | 52 ++++++++++++++-----
 llvm/test/MC/AArch64/SVE2/sqabs-diagnostics.s |  2 +-
 llvm/test/MC/AArch64/SVE2/sqneg-diagnostics.s |  2 +-
 .../test/MC/AArch64/SVE2/urecpe-diagnostics.s |  2 +-
 .../MC/AArch64/SVE2/ursqrte-diagnostics.s     |  2 +-
 .../MC/AArch64/SVE2p2/sqabs_z-diagnostics.s   | 37 +++++++++++++
 llvm/test/MC/AArch64/SVE2p2/sqabs_z.s         | 39 ++++++++++++++
 .../MC/AArch64/SVE2p2/sqneg_z-diagnostics.s   | 37 +++++++++++++
 llvm/test/MC/AArch64/SVE2p2/sqneg_z.s         | 39 ++++++++++++++
 .../MC/AArch64/SVE2p2/urecpe_z-diagnostics.s  | 47 +++++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/urecpe_z.s        | 33 ++++++++++++
 .../MC/AArch64/SVE2p2/ursqrte_z-diagnostics.s | 47 +++++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/ursqrte_z.s       | 33 ++++++++++++
 15 files changed, 372 insertions(+), 22 deletions(-)
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/sqabs_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/sqabs_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/sqneg_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/sqneg_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/urecpe_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/urecpe_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/ursqrte_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/ursqrte_z.s

diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 2262ad1dfd0cc9..9bb508b783c36a 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -73,8 +73,13 @@ def SVEUnsupported : AArch64Unsupported {
                       SVE2Unsupported.F);
 }
 
-let F = [HasSME2p1, HasSVE2p1_or_HasSME2p1, HasSVE2p1orSSVE_AES] in
-def SME2p1Unsupported : AArch64Unsupported;
+let F = [HasSME2p2, HasSVE2p2orSME2p2] in
+def SME2p2Unsupported : AArch64Unsupported;
+
+def SME2p1Unsupported : AArch64Unsupported {
+  let F = !listconcat([HasSME2p1, HasSVE2p1_or_HasSME2p1, HasSVE2p1orSSVE_AES],
+                      SME2p2Unsupported.F);
+}
 
 def SME2Unsupported : AArch64Unsupported {
   let F = !listconcat([HasSME2, HasSVE2orSME2, HasSVE2p1_or_HasSME2, HasSSVE_FP8FMA,
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index a097c138c5d6af..4b78300390bf87 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -3586,10 +3586,10 @@ let Predicates = [HasSVE2orSME] in {
   defm UMINP_ZPmZ : sve2_int_arith_pred<0b101111, "uminp", int_aarch64_sve_uminp>;
 
   // SVE2 integer unary operations (predicated)
-  defm URECPE_ZPmZ  : sve2_int_un_pred_arit_s<0b000, "urecpe",  int_aarch64_sve_urecpe>;
-  defm URSQRTE_ZPmZ : sve2_int_un_pred_arit_s<0b001, "ursqrte", int_aarch64_sve_ursqrte>;
-  defm SQABS_ZPmZ   : sve2_int_un_pred_arit<0b100,   "sqabs",   int_aarch64_sve_sqabs>;
-  defm SQNEG_ZPmZ   : sve2_int_un_pred_arit<0b101,   "sqneg",   int_aarch64_sve_sqneg>;
+  defm URECPE_ZPmZ  : sve2_int_un_pred_arit_s<0b00, "urecpe",  int_aarch64_sve_urecpe>;
+  defm URSQRTE_ZPmZ : sve2_int_un_pred_arit_s<0b01, "ursqrte", int_aarch64_sve_ursqrte>;
+  defm SQABS_ZPmZ   : sve2_int_un_pred_arit<  0b10, "sqabs",   int_aarch64_sve_sqabs>;
+  defm SQNEG_ZPmZ   : sve2_int_un_pred_arit<  0b11, "sqneg",   int_aarch64_sve_sqneg>;
 
   // SVE2 saturating add/subtract
   defm SQADD_ZPmZ  : sve2_int_arith_pred<0b110000, "sqadd",  int_aarch64_sve_sqadd>;
@@ -4226,6 +4226,11 @@ let Predicates = [HasSVE2p2orSME2p2] in {
 
   // SVE2p2 floating-point convert single-to-bf (placing odd), zeroing predicate
   def BFCVTNT_ZPzZ      : sve_fp_fcvt2z<0b1010, "bfcvtnt", ZPR16, ZPR32>;
+
+  def URECPE_ZPzZ  : sve2_int_un_pred_arit_z<0b10, 0b00, "urecpe", ZPR32>;
+  def URSQRTE_ZPzZ : sve2_int_un_pred_arit_z<0b10, 0b01, "ursqrte", ZPR32>;
+  defm SQABS_ZPzZ  : sve2_int_un_pred_arit_z<0b10, "sqabs">;
+  defm SQNEG_ZPzZ  : sve2_int_un_pred_arit_z<0b11, "sqneg">;
 } // End HasSME2p2orSVE2p2
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 42e00b53400816..ee941b916167db 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -3895,7 +3895,7 @@ multiclass sve2_int_sadd_long_accum_pairwise<bit U, string asm, SDPatternOperato
   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
 }
 
-class sve2_int_un_pred_arit<bits<2> sz, bit Q, bits<2> opc,
+class sve2_int_un_pred_arit<bits<2> sz, bits<2> opc,
                             string asm, ZPRRegOp zprty>
 : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
   asm, "\t$Zd, $Pg/m, $Zn",
@@ -3907,23 +3907,44 @@ class sve2_int_un_pred_arit<bits<2> sz, bit Q, bits<2> opc,
   let Inst{31-24} = 0b01000100;
   let Inst{23-22} = sz;
   let Inst{21-20} = 0b00;
-  let Inst{19}    = Q;
-  let Inst{18}    = 0b0;
-  let Inst{17-16} = opc;
+  let Inst{19}    = opc{1};
+  let Inst{18-17} = 0b00;
+  let Inst{16}    = opc{0};
   let Inst{15-13} = 0b101;
   let Inst{12-10} = Pg;
   let Inst{9-5}   = Zn;
   let Inst{4-0}   = Zd;
-
   let Constraints = "$Zd = $_Zd";
   let DestructiveInstType = DestructiveUnaryPassthru;
   let ElementSize = zprty.ElementSize;
   let hasSideEffects = 0;
 }
 
-multiclass sve2_int_un_pred_arit_s<bits<3> opc, string asm,
+class sve2_int_un_pred_arit_z<bits<2> sz, bits<2> opc,
+                              string asm, ZPRRegOp zprty>
+: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
+  asm, "\t$Zd, $Pg/z, $Zn",
+  "",
+  []>, Sched<[]> {
+  bits<3> Pg;
+  bits<5> Zd;
+  bits<5> Zn;
+  let Inst{31-24} = 0b01000100;
+  let Inst{23-22} = sz;
+  let Inst{21-20} = 0b00;
+  let Inst{19}    = opc{1};
+  let Inst{18-17} = 0b01;
+  let Inst{16}    = opc{0};
+  let Inst{15-13} = 0b101;
+  let Inst{12-10} = Pg;
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zd;
+  let hasSideEffects = 0;
+}
+
+multiclass sve2_int_un_pred_arit_s<bits<2> opc, string asm,
                                    SDPatternOperator op> {
-  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
+  def _S : sve2_int_un_pred_arit<0b10, opc, asm, ZPR32>,
            SVEPseudo2Instr<NAME # _S, 1>;
 
   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
@@ -3933,14 +3954,14 @@ multiclass sve2_int_un_pred_arit_s<bits<3> opc, string asm,
   defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
 }
 
-multiclass sve2_int_un_pred_arit<bits<3> opc, string asm, SDPatternOperator op> {
-  def _B : sve2_int_un_pred_arit<0b00, opc{2}, opc{1-0}, asm, ZPR8>,
+multiclass sve2_int_un_pred_arit<bits<2> opc, string asm, SDPatternOperator op> {
+  def _B : sve2_int_un_pred_arit<0b00, opc, asm, ZPR8>,
            SVEPseudo2Instr<NAME # _B, 1>;
-  def _H : sve2_int_un_pred_arit<0b01, opc{2}, opc{1-0}, asm, ZPR16>,
+  def _H : sve2_int_un_pred_arit<0b01, opc, asm, ZPR16>,
            SVEPseudo2Instr<NAME # _H, 1>;
-  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
+  def _S : sve2_int_un_pred_arit<0b10, opc, asm, ZPR32>,
            SVEPseudo2Instr<NAME # _S, 1>;
-  def _D : sve2_int_un_pred_arit<0b11, opc{2}, opc{1-0}, asm, ZPR64>,
+  def _D : sve2_int_un_pred_arit<0b11, opc, asm, ZPR64>,
            SVEPseudo2Instr<NAME # _D, 1>;
 
   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
@@ -3959,6 +3980,13 @@ multiclass sve2_int_un_pred_arit<bits<3> opc, string asm, SDPatternOperator op>
   defm : SVE_3_Op_Undef_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
 }
 
+multiclass sve2_int_un_pred_arit_z<bits<2> opc, string asm> {
+  def _B : sve2_int_un_pred_arit_z<0b00, opc, asm, ZPR8>;
+  def _H : sve2_int_un_pred_arit_z<0b01, opc, asm, ZPR16>;
+  def _S : sve2_int_un_pred_arit_z<0b10, opc, asm, ZPR32>;
+  def _D : sve2_int_un_pred_arit_z<0b11, opc, asm, ZPR64>;
+}
+
 //===----------------------------------------------------------------------===//
 // SVE2 Widening Integer Arithmetic Group
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/SVE2/sqabs-diagnostics.s b/llvm/test/MC/AArch64/SVE2/sqabs-diagnostics.s
index 8b3a136a7d7429..7dd268dd7cddd1 100644
--- a/llvm/test/MC/AArch64/SVE2/sqabs-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/sqabs-diagnostics.s
@@ -4,7 +4,7 @@
 // Invalid predicate
 
 sqabs z0.s, p0/z, z1.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: sqabs z0.s, p0/z, z1.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2/sqneg-diagnostics.s b/llvm/test/MC/AArch64/SVE2/sqneg-diagnostics.s
index 7b0f5722b94a3f..372adad0427c09 100644
--- a/llvm/test/MC/AArch64/SVE2/sqneg-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/sqneg-diagnostics.s
@@ -4,7 +4,7 @@
 // Invalid predicate
 
 sqneg z0.s, p0/z, z1.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: sqneg z0.s, p0/z, z1.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2/urecpe-diagnostics.s b/llvm/test/MC/AArch64/SVE2/urecpe-diagnostics.s
index f04538494cd6f0..73bb6cecffa5a4 100644
--- a/llvm/test/MC/AArch64/SVE2/urecpe-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/urecpe-diagnostics.s
@@ -4,7 +4,7 @@
 // Invalid predicate
 
 urecpe z0.s, p0/z, z1.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: urecpe z0.s, p0/z, z1.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2/ursqrte-diagnostics.s b/llvm/test/MC/AArch64/SVE2/ursqrte-diagnostics.s
index 2190ff1ebd82ba..0c6746a4a7c1fe 100644
--- a/llvm/test/MC/AArch64/SVE2/ursqrte-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/ursqrte-diagnostics.s
@@ -4,7 +4,7 @@
 // Invalid predicate
 
 ursqrte z0.s, p0/z, z1.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: ursqrte z0.s, p0/z, z1.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2p2/sqabs_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/sqabs_z-diagnostics.s
new file mode 100644
index 00000000000000..8c00a74c69c8c6
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/sqabs_z-diagnostics.s
@@ -0,0 +1,37 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid element width
+
+sqabs     z31.b, p7/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: sqabs     z31.b, p7/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqabs     z31.d, p7/z, z31.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: sqabs     z31.d, p7/z, z31.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+sqabs     z31.b, p8/z, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: sqabs     z31.b, p8/z, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.h, p0/z, z7.h
+sqabs z0.h, p0/z, z3.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: sqabs z0.h, p0/z, z3.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+sqabs z0.h, p0/z, z3.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: sqabs z0.h, p0/z, z3.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/sqabs_z.s b/llvm/test/MC/AArch64/SVE2p2/sqabs_z.s
new file mode 100644
index 00000000000000..c583423fac6eba
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/sqabs_z.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=-sme2 - | 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
+
+sqabs   z0.b, p0/z, z0.b  // 01000100-00001010-10100000-00000000
+// CHECK-INST: sqabs   z0.b, p0/z, z0.b
+// CHECK-ENCODING: [0x00,0xa0,0x0a,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 440aa000 <unknown>
+
+sqabs   z21.h, p5/z, z10.h  // 01000100-01001010-10110101-01010101
+// CHECK-INST: sqabs   z21.h, p5/z, z10.h
+// CHECK-ENCODING: [0x55,0xb5,0x4a,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 444ab555 <unknown>
+
+sqabs   z23.s, p3/z, z13.s  // 01000100-10001010-10101101-10110111
+// CHECK-INST: sqabs   z23.s, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0x8a,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 448aadb7 <unknown>
+
+sqabs   z31.d, p7/z, z31.d  // 01000100-11001010-10111111-11111111
+// CHECK-INST: sqabs   z31.d, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0xbf,0xca,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 44cabfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/sqneg_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/sqneg_z-diagnostics.s
new file mode 100644
index 00000000000000..576633c0ab1b64
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/sqneg_z-diagnostics.s
@@ -0,0 +1,37 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid element width
+
+sqneg     z31.b, p7/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: sqneg     z31.b, p7/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqneg     z31.d, p7/z, z31.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: sqneg     z31.d, p7/z, z31.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+sqneg     z31.b, p8/z, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: sqneg     z31.b, p8/z, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.h, p0/z, z7.h
+sqneg z0.h, p0/z, z3.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: sqneg z0.h, p0/z, z3.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+sqneg z0.h, p0/z, z3.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: sqneg z0.h, p0/z, z3.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/sqneg_z.s b/llvm/test/MC/AArch64/SVE2p2/sqneg_z.s
new file mode 100644
index 00000000000000..287211fd3ff5dd
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/sqneg_z.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=-sme2 - | 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
+
+sqneg   z0.b, p0/z, z0.b  // 01000100-00001011-10100000-00000000
+// CHECK-INST: sqneg   z0.b, p0/z, z0.b
+// CHECK-ENCODING: [0x00,0xa0,0x0b,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 440ba000 <unknown>
+
+sqneg   z23.h, p3/z, z13.h  // 01000100-01001011-10101101-10110111
+// CHECK-INST: sqneg   z23.h, p3/z, z13.h
+// CHECK-ENCODING: [0xb7,0xad,0x4b,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 444badb7 <unknown>
+
+sqneg   z21.s, p5/z, z10.s  // 01000100-10001011-10110101-01010101
+// CHECK-INST: sqneg   z21.s, p5/z, z10.s
+// CHECK-ENCODING: [0x55,0xb5,0x8b,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 448bb555 <unknown>
+
+sqneg   z31.d, p7/z, z31.d  // 01000100-11001011-10111111-11111111
+// CHECK-INST: sqneg   z31.d, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0xbf,0xcb,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 44cbbfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/urecpe_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/urecpe_z-diagnostics.s
new file mode 100644
index 00000000000000..9da2a7e096f3af
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/urecpe_z-diagnostics.s
@@ -0,0 +1,47 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element width
+
+urecpe     z31.b, p7/z, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: urecpe     z31.b, p7/z, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+urecpe     z31.h, p7/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: urecpe     z31.h, p7/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+urecpe     z31.s, p7/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: urecpe     z31.s, p7/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+urecpe     z31.d, p7/z, z31.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: urecpe     z31.d, p7/z, z31.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+urecpe z0.s, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: urecpe z0.s, p8/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.s, p0/z, z7.s
+urecpe z0.s, p0/z, z3.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: urecpe z0.s, p0/z, z3.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+urecpe z0.s, p0/z, z3.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: urecpe z0.s, p0/z, z3.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/urecpe_z.s b/llvm/test/MC/AArch64/SVE2p2/urecpe_z.s
new file mode 100644
index 00000000000000..6b3ec79c988690
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/urecpe_z.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=-sme2 - | 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
+
+urecpe  z0.s, p0/z, z0.s  // 01000100-10000010-10100000-00000000
+// CHECK-INST: urecpe  z0.s, p0/z, z0.s
+// CHECK-ENCODING: [0x00,0xa0,0x82,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 4482a000 <unknown>
+
+urecpe  z23.s, p3/z, z13.s  // 01000100-10000010-10101101-10110111
+// CHECK-INST: urecpe  z23.s, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0x82,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 4482adb7 <unknown>
+
+urecpe  z31.s, p7/z, z31.s  // 01000100-10000010-10111111-11111111
+// CHECK-INST: urecpe  z31.s, p7/z, z31.s
+// CHECK-ENCODING: [0xff,0xbf,0x82,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 4482bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/ursqrte_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/ursqrte_z-diagnostics.s
new file mode 100644
index 00000000000000..1b6cf8d78e655e
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/ursqrte_z-diagnostics.s
@@ -0,0 +1,47 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element width
+
+ursqrte     z31.b, p7/z, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: ursqrte     z31.b, p7/z, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ursqrte     z31.h, p7/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: ursqrte     z31.h, p7/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ursqrte     z31.s, p7/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: ursqrte     z31.s, p7/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ursqrte     z31.d, p7/z, z31.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: ursqrte     z31.d, p7/z, z31.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+ursqrte z0.s, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: ursqrte z0.s, p8/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.s, p0/z, z7.s
+ursqrte z0.s, p0/z, z3.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: ursqrte z0.s, p0/z, z3.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+ursqrte z0.s, p0/z, z3.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: ursqrte z0.s, p0/z, z3.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/ursqrte_z.s b/llvm/test/MC/AArch64/SVE2p2/ursqrte_z.s
new file mode 100644
index 00000000000000..097d82bebd430b
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/ursqrte_z.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=-sme2 - | 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
+
+ursqrte z0.s, p0/z, z0.s  // 01000100-10000011-10100000-00000000
+// CHECK-INST: ursqrte z0.s, p0/z, z0.s
+// CHECK-ENCODING: [0x00,0xa0,0x83,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 4483a000 <unknown>
+
+ursqrte z21.s, p5/z, z10.s  // 01000100-10000011-10110101-01010101
+// CHECK-INST: ursqrte z21.s, p5/z, z10.s
+// CHECK-ENCODING: [0x55,0xb5,0x83,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 4483b555 <unknown>
+
+ursqrte z31.s, p7/z, z31.s  // 01000100-10000011-10111111-11111111
+// CHECK-INST: ursqrte z31.s, p7/z, z31.s
+// CHECK-ENCODING: [0xff,0xbf,0x83,0x44]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 4483bfff <unknown>
\ No newline at end of file



More information about the llvm-commits mailing list