[llvm] [AArch64] Add assembly/disassembly for zeroing SVE REV{B,H,W,D} and RBIT (PR #114110)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 31 03:23:36 PDT 2024


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

>From 1042444b501ccd44baf87bb4997b7da87cc44f17 Mon Sep 17 00:00:00 2001
From: Spencer Abson <Spencer.Abson at arm.com>
Date: Tue, 29 Oct 2024 18:08:34 +0000
Subject: [PATCH 1/2] [AArch64] Add assembly/disassembly for zeroing SVE
 REV{B,H,W,D} and RBIT

- Add assembly/disassembly support for the following SVE2.2 instructions
	- RBIT (zeroing)
	- REVB (zeroing)
	- REVH (zeroing)
	- REVW (zeroing)
	- REVD (zeroing)

Co-authored-by: Marian Lukac marian.lukac at arm.com
---
 .../lib/Target/AArch64/AArch64SVEInstrInfo.td |  7 ++
 llvm/lib/Target/AArch64/SMEInstrFormats.td    | 17 +++++
 llvm/lib/Target/AArch64/SVEInstrFormats.td    | 43 +++++++++++
 llvm/test/MC/AArch64/SME/revd-diagnostics.s   |  2 +-
 .../MC/AArch64/SVE2p2/rbit_z-diagnostics.s    | 74 +++++++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/rbit_z.s          | 45 +++++++++++
 .../MC/AArch64/SVE2p2/revb_z-diagnostics.s    | 63 ++++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/revb_z.s          | 33 +++++++++
 .../MC/AArch64/SVE2p2/revd_z-diagnostics.s    | 56 ++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/revd_z.s          | 33 +++++++++
 .../MC/AArch64/SVE2p2/revh_z-diagnostics.s    | 58 +++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/revh_z.s          | 33 +++++++++
 .../MC/AArch64/SVE2p2/revw_z-diagnostics.s    | 51 +++++++++++++
 llvm/test/MC/AArch64/SVE2p2/revw_z.s          | 33 +++++++++
 14 files changed, 547 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/rbit_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/rbit_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/revb_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/revb_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/revd_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/revd_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/revh_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/revh_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/revw_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/revw_z.s

diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index d6662d15617fab..ff4c51ca1dca97 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4307,6 +4307,13 @@ let Predicates = [HasSVE2p2orSME2p2] in {
   // SVE predicate count
   defm FIRSTP_XPP : sve_int_pcount_pred_tmp<0b001, "firstp">;
   defm LASTP_XPP  : sve_int_pcount_pred_tmp<0b010, "lastp">;
+
+  // SVE reverse within elements, zeroing predicate
+  defm RBIT_ZPzZ : sve_int_perm_rev_rbit_z<"rbit">;
+  defm REVB_ZPzZ : sve_int_perm_rev_revb_z<"revb">;
+  defm REVH_ZPzZ : sve_int_perm_rev_revh_z<"revh">;
+  defm REVW_ZPzZ : sve_int_perm_rev_revw_z<"revw">;
+  def  REVD_ZPzZ : sve2_int_perm_revd_z<"revd">;
 } // End HasSME2p2orSVE2p2
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 867901ac5d9035..30113550476bf2 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -1309,6 +1309,23 @@ multiclass sve2_int_perm_revd<string asm, SDPatternOperator op> {
 
 }
 
+class sve2_int_perm_revd_z<string asm>
+    : I<(outs ZPR128:$Zd), (ins PPR3bAny:$Pg, ZPR128:$Zn),
+        asm, "\t$Zd, $Pg/z, $Zn", "", []>,
+      Sched<[]> {
+  bits<5> Zd;
+  bits<3> Pg;
+  bits<5> Zn;
+  let Inst{31-24} = 0b00000101;
+  let Inst{23-22} = 0b00; // size
+  let Inst{21-13} = 0b101110101;
+  let Inst{12-10} = Pg;
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zd;
+
+  let hasSideEffects = 0;
+}
+
 class sve2_clamp<string asm, bits<2> sz, bit U, ZPRRegOp zpr_ty>
     : I<(outs zpr_ty:$Zd), (ins zpr_ty:$_Zd, zpr_ty:$Zn, zpr_ty:$Zm),
         asm, "\t$Zd, $Zn, $Zm", "", []>,
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 552d5b9b23a7e4..f24e782197a00c 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -7429,6 +7429,49 @@ multiclass sve_int_perm_rev_revw<string asm, SDPatternOperator op> {
   def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
 }
 
+class sve_int_perm_rev_z<bits<2> sz8_64, bits<2> opc, string asm,
+                       ZPRRegOp zprty>
+: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
+  asm, "\t$Zd, $Pg/z, $Zn",
+  "",
+  []>, Sched<[]> {
+  bits<5> Zd;
+  bits<3> Pg;
+  bits<5> Zn;
+  let Inst{31-24} = 0b00000101;
+  let Inst{23-22} = sz8_64;
+  let Inst{21-18} = 0b1001;
+  let Inst{17-16} = opc;
+  let Inst{15-13} = 0b101;
+  let Inst{12-10} = Pg;
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zd;
+
+  let hasSideEffects = 0;
+}
+
+multiclass sve_int_perm_rev_rbit_z<string asm> {
+  def _B : sve_int_perm_rev_z<0b00, 0b11, asm, ZPR8>;
+  def _H : sve_int_perm_rev_z<0b01, 0b11, asm, ZPR16>;
+  def _S : sve_int_perm_rev_z<0b10, 0b11, asm, ZPR32>;
+  def _D : sve_int_perm_rev_z<0b11, 0b11, asm, ZPR64>;
+}
+
+multiclass sve_int_perm_rev_revb_z<string asm> {
+  def _H : sve_int_perm_rev_z<0b01, 0b00, asm, ZPR16>;
+  def _S : sve_int_perm_rev_z<0b10, 0b00, asm, ZPR32>;
+  def _D : sve_int_perm_rev_z<0b11, 0b00, asm, ZPR64>;
+}
+
+multiclass sve_int_perm_rev_revh_z<string asm> {
+  def _S : sve_int_perm_rev_z<0b10, 0b01, asm, ZPR32>;
+  def _D : sve_int_perm_rev_z<0b11, 0b01, asm, ZPR64>;
+}
+
+multiclass sve_int_perm_rev_revw_z<string asm> {
+  def _D : sve_int_perm_rev_z<0b11, 0b10, asm, ZPR64>;
+}
+
 class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
                          RegisterClass srcRegType>
 : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn),
diff --git a/llvm/test/MC/AArch64/SME/revd-diagnostics.s b/llvm/test/MC/AArch64/SME/revd-diagnostics.s
index 42205c26ce93fe..e7242e5dc1bbb3 100644
--- a/llvm/test/MC/AArch64/SME/revd-diagnostics.s
+++ b/llvm/test/MC/AArch64/SME/revd-diagnostics.s
@@ -11,7 +11,7 @@ revd z0.q, p8/m, z0.q
 
 // wrong predication qualifier, expected /m.
 revd z0.q, p0/z, z0.q
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: revd z0.q, p0/z, z0.q
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2p2/rbit_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/rbit_z-diagnostics.s
new file mode 100644
index 00000000000000..e20d8c4c1b97f8
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/rbit_z-diagnostics.s
@@ -0,0 +1,74 @@
+/ RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2  2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+rbit  z0.b, p8/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: rbit  z0.b, p8/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.h, p8/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: rbit  z0.h, p8/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.s, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: rbit  z0.s, p8/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.d, p8/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: rbit  z0.d, p8/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+rbit  z0.b, p7/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: rbit  z0.b, p7/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.h, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: rbit  z0.h, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.s, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: rbit  z0.s, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.d, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: rbit  z0.d, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.b, p0/z, z7.b
+rbit  z0.b, p0/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: rbit  z0.b, p0/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+rbit  z0.h, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: rbit  z0.h, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0.s, p0/z, z7.s
+rbit  z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: rbit  z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+rbit  z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: rbit  z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/rbit_z.s b/llvm/test/MC/AArch64/SVE2p2/rbit_z.s
new file mode 100644
index 00000000000000..3eb9c2d79306f3
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/rbit_z.s
@@ -0,0 +1,45 @@
+// 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=-sve - | 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
+
+rbit    z0.b, p0/z, z0.b  // 00000101-00100111-10100000-00000000
+// CHECK-INST: rbit    z0.b, p0/z, z0.b
+// CHECK-ENCODING: [0x00,0xa0,0x27,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 0527a000 <unknown>
+
+rbit    z21.b, p5/z, z10.b  // 00000101-00100111-10110101-01010101
+// CHECK-INST: rbit    z21.b, p5/z, z10.b
+// CHECK-ENCODING: [0x55,0xb5,0x27,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 0527b555 <unknown>
+
+rbit    z23.h, p3/z, z13.h  // 00000101-01100111-10101101-10110111
+// CHECK-INST: rbit    z23.h, p3/z, z13.h
+// CHECK-ENCODING: [0xb7,0xad,0x67,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 0567adb7 <unknown>
+
+rbit    z23.s, p3/z, z13.s  // 00000101-10100111-10101101-10110111
+// CHECK-INST: rbit    z23.s, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0xa7,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05a7adb7 <unknown>
+
+rbit    z31.d, p7/z, z31.d  // 00000101-11100111-10111111-11111111
+// CHECK-INST: rbit    z31.d, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0xbf,0xe7,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05e7bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revb_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/revb_z-diagnostics.s
new file mode 100644
index 00000000000000..4cf40f8fd7923d
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revb_z-diagnostics.s
@@ -0,0 +1,63 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2  2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+revb  z0.h, p8/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revb  z0.h, p8/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.s, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revb  z0.s, p8/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.d, p8/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revb  z0.d, p8/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+revb  z0.b, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revb  z0.b, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.h, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revb  z0.h, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.s, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revb  z0.s, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.d, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revb  z0.d, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0, z7
+revb  z0.h, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revb  z0.h, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0.s, p0/z, z7.s
+revb  z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revb  z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+revb  z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revb  z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revb_z.s b/llvm/test/MC/AArch64/SVE2p2/revb_z.s
new file mode 100644
index 00000000000000..16dee586bd1d17
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revb_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=-sve - | 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
+
+revb    z0.h, p0/z, z0.h  // 00000101-01100100-10100000-00000000
+// CHECK-INST: revb    z0.h, p0/z, z0.h
+// CHECK-ENCODING: [0x00,0xa0,0x64,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 0564a000 <unknown>
+
+revb    z23.s, p3/z, z13.s  // 00000101-10100100-10101101-10110111
+// CHECK-INST: revb    z23.s, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0xa4,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05a4adb7 <unknown>
+
+revb    z31.d, p7/z, z31.d  // 00000101-11100100-10111111-11111111
+// CHECK-INST: revb    z31.d, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0xbf,0xe4,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05e4bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revd_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/revd_z-diagnostics.s
new file mode 100644
index 00000000000000..ed031e4a8763d4
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revd_z-diagnostics.s
@@ -0,0 +1,56 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2  2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+revd  z0.q, p8/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revd  z0.q, p8/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+revd  z0.b, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.b, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.h, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.h, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.s, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.s, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.h, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.h, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.s, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.s, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.d, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.d, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.q, p7/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.q, p7/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0, z7
+revd  z0.q, p0/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revd  z0.q, p0/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revd_z.s b/llvm/test/MC/AArch64/SVE2p2/revd_z.s
new file mode 100644
index 00000000000000..b8675f02686792
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revd_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=-sve - | 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
+
+revd    z0.q, p0/z, z0.q  // 00000101-00101110-10100000-00000000
+// CHECK-INST: revd    z0.q, p0/z, z0.q
+// CHECK-ENCODING: [0x00,0xa0,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 052ea000 <unknown>
+
+revd    z23.q, p3/z, z13.q  // 00000101-00101110-10101101-10110111
+// CHECK-INST: revd    z23.q, p3/z, z13.q
+// CHECK-ENCODING: [0xb7,0xad,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 052eadb7 <unknown>
+
+revd    z31.q, p7/z, z31.q  // 00000101-00101110-10111111-11111111
+// CHECK-INST: revd    z31.q, p7/z, z31.q
+// CHECK-ENCODING: [0xff,0xbf,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 052ebfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revh_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/revh_z-diagnostics.s
new file mode 100644
index 00000000000000..c7b83bdf229ec6
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revh_z-diagnostics.s
@@ -0,0 +1,58 @@
+
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2  2>&1 < %s| FileCheck %s
+// ------------------------------------------------------------------------- //
+
+// Invalid predicate
+
+revh  z0.s, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revh  z0.s, p8/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revh  z0.d, p8/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revh  z0.d, p8/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+revh  z0.b, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revh  z0.b, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revh  z0.h, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revh  z0.h, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revh  z0.q, p7/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revh  z0.q, p7/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revh  z0.s, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revh  z0.s, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revh  z0.d, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revh  z0.d, p7/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
+revh  z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revh  z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+revh  z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revh  z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revh_z.s b/llvm/test/MC/AArch64/SVE2p2/revh_z.s
new file mode 100644
index 00000000000000..2a56025bde916a
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revh_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=-sve - | 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
+
+revh    z0.s, p0/z, z0.s  // 00000101-10100101-10100000-00000000
+// CHECK-INST: revh    z0.s, p0/z, z0.s
+// CHECK-ENCODING: [0x00,0xa0,0xa5,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05a5a000 <unknown>
+
+revh    z23.s, p3/z, z13.s  // 00000101-10100101-10101101-10110111
+// CHECK-INST: revh    z23.s, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0xa5,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05a5adb7 <unknown>
+
+revh    z31.d, p7/z, z31.d  // 00000101-11100101-10111111-11111111
+// CHECK-INST: revh    z31.d, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0xbf,0xe5,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05e5bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revw_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/revw_z-diagnostics.s
new file mode 100644
index 00000000000000..478492dccafa4b
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revw_z-diagnostics.s
@@ -0,0 +1,51 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2  2>&1 < %s| FileCheck %s
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+revw  z0.d, p8/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revw  z0.d, p8/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+revw  z0.b, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revw  z0.b, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revw  z0.h, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revw  z0.h, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revw  z0.s, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revw  z0.s, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revw  z0.q, p7/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revw  z0.q, p7/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revw  z0.d, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revw  z0.d, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.d, p0/z, z7.d
+revw  z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revw  z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+revw  z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revw  z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revw_z.s b/llvm/test/MC/AArch64/SVE2p2/revw_z.s
new file mode 100644
index 00000000000000..b695398098d5ab
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revw_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=-sve - | 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
+
+revw    z0.d, p0/z, z0.d  // 00000101-11100110-10100000-00000000
+// CHECK-INST: revw    z0.d, p0/z, z0.d
+// CHECK-ENCODING: [0x00,0xa0,0xe6,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05e6a000 <unknown>
+
+revw    z23.d, p3/z, z13.d  // 00000101-11100110-10101101-10110111
+// CHECK-INST: revw    z23.d, p3/z, z13.d
+// CHECK-ENCODING: [0xb7,0xad,0xe6,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05e6adb7 <unknown>
+
+revw    z31.d, p7/z, z31.d  // 00000101-11100110-10111111-11111111
+// CHECK-INST: revw    z31.d, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0xbf,0xe6,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05e6bfff <unknown>
\ No newline at end of file

>From 613482355444d086d75f756782a6a65fe50ab1e8 Mon Sep 17 00:00:00 2001
From: Spencer Abson <Spencer.Abson at arm.com>
Date: Thu, 31 Oct 2024 10:22:49 +0000
Subject: [PATCH 2/2] Remove redundant revd class and revw multiclass

---
 .../lib/Target/AArch64/AArch64SVEInstrInfo.td |  4 +--
 llvm/lib/Target/AArch64/SMEInstrFormats.td    | 17 ----------
 llvm/lib/Target/AArch64/SVEInstrFormats.td    | 32 ++++++++-----------
 3 files changed, 16 insertions(+), 37 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index ff4c51ca1dca97..acef3b09acc6f6 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4312,8 +4312,8 @@ let Predicates = [HasSVE2p2orSME2p2] in {
   defm RBIT_ZPzZ : sve_int_perm_rev_rbit_z<"rbit">;
   defm REVB_ZPzZ : sve_int_perm_rev_revb_z<"revb">;
   defm REVH_ZPzZ : sve_int_perm_rev_revh_z<"revh">;
-  defm REVW_ZPzZ : sve_int_perm_rev_revw_z<"revw">;
-  def  REVD_ZPzZ : sve2_int_perm_revd_z<"revd">;
+  def  REVW_ZPzZ : sve_int_perm_rev_z<0b11, 0b0110, "revw", ZPR64>;
+  def  REVD_ZPzZ : sve_int_perm_rev_z<0b00, 0b1110, "revd", ZPR128>;
 } // End HasSME2p2orSVE2p2
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 30113550476bf2..867901ac5d9035 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -1309,23 +1309,6 @@ multiclass sve2_int_perm_revd<string asm, SDPatternOperator op> {
 
 }
 
-class sve2_int_perm_revd_z<string asm>
-    : I<(outs ZPR128:$Zd), (ins PPR3bAny:$Pg, ZPR128:$Zn),
-        asm, "\t$Zd, $Pg/z, $Zn", "", []>,
-      Sched<[]> {
-  bits<5> Zd;
-  bits<3> Pg;
-  bits<5> Zn;
-  let Inst{31-24} = 0b00000101;
-  let Inst{23-22} = 0b00; // size
-  let Inst{21-13} = 0b101110101;
-  let Inst{12-10} = Pg;
-  let Inst{9-5}   = Zn;
-  let Inst{4-0}   = Zd;
-
-  let hasSideEffects = 0;
-}
-
 class sve2_clamp<string asm, bits<2> sz, bit U, ZPRRegOp zpr_ty>
     : I<(outs zpr_ty:$Zd), (ins zpr_ty:$_Zd, zpr_ty:$Zn, zpr_ty:$Zm),
         asm, "\t$Zd, $Zn, $Zm", "", []>,
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index f24e782197a00c..5cfcc01afd20f3 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -7429,8 +7429,8 @@ multiclass sve_int_perm_rev_revw<string asm, SDPatternOperator op> {
   def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
 }
 
-class sve_int_perm_rev_z<bits<2> sz8_64, bits<2> opc, string asm,
-                       ZPRRegOp zprty>
+class sve_int_perm_rev_z<bits<2> sz, bits<4> opc, string asm,
+                        ZPRRegOp zprty>
 : I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
   asm, "\t$Zd, $Pg/z, $Zn",
   "",
@@ -7439,9 +7439,9 @@ class sve_int_perm_rev_z<bits<2> sz8_64, bits<2> opc, string asm,
   bits<3> Pg;
   bits<5> Zn;
   let Inst{31-24} = 0b00000101;
-  let Inst{23-22} = sz8_64;
-  let Inst{21-18} = 0b1001;
-  let Inst{17-16} = opc;
+  let Inst{23-22} = sz;
+  let Inst{21-20} = 0b10;
+  let Inst{19-16} = opc;
   let Inst{15-13} = 0b101;
   let Inst{12-10} = Pg;
   let Inst{9-5}   = Zn;
@@ -7451,25 +7451,21 @@ class sve_int_perm_rev_z<bits<2> sz8_64, bits<2> opc, string asm,
 }
 
 multiclass sve_int_perm_rev_rbit_z<string asm> {
-  def _B : sve_int_perm_rev_z<0b00, 0b11, asm, ZPR8>;
-  def _H : sve_int_perm_rev_z<0b01, 0b11, asm, ZPR16>;
-  def _S : sve_int_perm_rev_z<0b10, 0b11, asm, ZPR32>;
-  def _D : sve_int_perm_rev_z<0b11, 0b11, asm, ZPR64>;
+  def _B : sve_int_perm_rev_z<0b00, 0b0111, asm, ZPR8>;
+  def _H : sve_int_perm_rev_z<0b01, 0b0111, asm, ZPR16>;
+  def _S : sve_int_perm_rev_z<0b10, 0b0111, asm, ZPR32>;
+  def _D : sve_int_perm_rev_z<0b11, 0b0111, asm, ZPR64>;
 }
 
 multiclass sve_int_perm_rev_revb_z<string asm> {
-  def _H : sve_int_perm_rev_z<0b01, 0b00, asm, ZPR16>;
-  def _S : sve_int_perm_rev_z<0b10, 0b00, asm, ZPR32>;
-  def _D : sve_int_perm_rev_z<0b11, 0b00, asm, ZPR64>;
+  def _H : sve_int_perm_rev_z<0b01, 0b0100, asm, ZPR16>;
+  def _S : sve_int_perm_rev_z<0b10, 0b0100, asm, ZPR32>;
+  def _D : sve_int_perm_rev_z<0b11, 0b0100, asm, ZPR64>;
 }
 
 multiclass sve_int_perm_rev_revh_z<string asm> {
-  def _S : sve_int_perm_rev_z<0b10, 0b01, asm, ZPR32>;
-  def _D : sve_int_perm_rev_z<0b11, 0b01, asm, ZPR64>;
-}
-
-multiclass sve_int_perm_rev_revw_z<string asm> {
-  def _D : sve_int_perm_rev_z<0b11, 0b10, asm, ZPR64>;
+  def _S : sve_int_perm_rev_z<0b10, 0b0101, asm, ZPR32>;
+  def _D : sve_int_perm_rev_z<0b11, 0b0101, asm, ZPR64>;
 }
 
 class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,



More information about the llvm-commits mailing list