Skip to content

[LLVM][AARCH64] Add assembly/disassembly of zeroing convert instructions #113292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 23, 2024

Conversation

Lukacma
Copy link
Contributor

@Lukacma Lukacma commented Oct 22, 2024

This patch adds the zeroing predicate forms (Pg/z) of the following instructions:
- FCVTXNT
- FCVTNT
- FCVTLT
- BFCVTNT

As specified in https://developer.arm.com/documentation/ddi0602.

Co-authored-by: Spencer Abson [email protected]

@llvmbot
Copy link
Member

llvmbot commented Oct 22, 2024

@llvm/pr-subscribers-mc

@llvm/pr-subscribers-backend-aarch64

Author: None (Lukacma)

Changes

This patch adds the zeroing predicate forms (Pg/z) of the following instructions:
- FCVTXNT
- FCVNT
- FCVTLT
- BFCVTNT

As specified in https://developer.arm.com/documentation/ddi0602.

Co-authored-by: Spencer Abson [[email protected]](mailto:[email protected])


Patch is 26.26 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113292.diff

20 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td (+16)
  • (modified) llvm/lib/Target/AArch64/SVEInstrFormats.td (+31)
  • (modified) llvm/test/MC/AArch64/SVE/bfcvtnt-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE2/fcvtlt-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE2/fcvtnt-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE2/fcvtxnt-diagnostics.s (+1-1)
  • (added) llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z-diagnostics.s (+52)
  • (added) llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/directive-arch-negative.s (+7)
  • (added) llvm/test/MC/AArch64/SVE2p2/directive-arch.s (+5)
  • (added) llvm/test/MC/AArch64/SVE2p2/directive-arch_extension-negative.s (+7)
  • (added) llvm/test/MC/AArch64/SVE2p2/directive-arch_extension.s (+5)
  • (added) llvm/test/MC/AArch64/SVE2p2/directive-cpu-negative.s (+7)
  • (added) llvm/test/MC/AArch64/SVE2p2/directive-cpu.s (+5)
  • (added) llvm/test/MC/AArch64/SVE2p2/fcvtlt_z-diagnostics.s (+57)
  • (added) llvm/test/MC/AArch64/SVE2p2/fcvtlt_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/fcvtnt_z-diagnostics.s (+56)
  • (added) llvm/test/MC/AArch64/SVE2p2/fcvtnt_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z-diagnostics.s (+62)
  • (added) llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z.s (+33)
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 2a857234c7d745..fb7cc7373be5ad 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4197,6 +4197,22 @@ defm TBXQ_ZZZ : sve2_int_perm_tbx<"tbxq", 0b10, int_aarch64_sve_tbxq>;
 defm TBLQ_ZZZ  : sve2p1_tblq<"tblq", int_aarch64_sve_tblq>;
 } // End HasSVE2p1_or_HasSME2p1
 
+
+//===----------------------------------------------------------------------===//
+// SME2.2 or SVE2.2 instructions
+//===----------------------------------------------------------------------===//
+let Predicates = [HasSVE2p2orSME2p2] in {
+  // SVE2p2 floating-point convert precision down (placing odd), zeroing predicate
+  defm FCVTNT_ZPzZ      : sve_fp_fcvtntz<"fcvtnt">;
+  def FCVTXNT_ZPzZ_DtoS : sve_fp_fcvt2z<0b0010, "fcvtxnt", ZPR32, ZPR64>;
+
+  // SVE2p2 floating-point convert precision up, zeroing predicate
+  defm FCVTLT_ZPzZ      : sve_fp_fcvtltz<"fcvtlt">;
+
+  // SVE2p2 floating-point convert single-to-bf (placing odd), zeroing predicate
+  def BFCVTNT_ZPzZ      : sve_fp_fcvt2z<0b1010, "bfcvtnt", ZPR16, ZPR32>;
+} // End HasSME2p2orSVE2p2
+
 //===----------------------------------------------------------------------===//
 // SVE2 FP8 instructions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index f655526fa81cfe..4547fe3898e60c 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -2730,6 +2730,37 @@ multiclass sve2_fp_convert_down_odd_rounding_top<string asm, string op> {
   def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
 }
 
+class sve_fp_fcvt2z<bits<4> opc, string asm, ZPRRegOp zprty1,
+                    ZPRRegOp zprty2>
+  : I<(outs zprty1:$Zd), (ins PPR3bAny:$Pg, zprty2:$Zn),
+    asm, "\t$Zd, $Pg/z, $Zn",
+    "",
+    []>, Sched<[]> {
+    bits<5> Zd;
+    bits<5> Zn;
+    bits<3> Pg;
+    let Inst{31-24} = 0b01100100;
+    let Inst{23-22} = opc{3-2};
+    let Inst{21-18} = 0b0000;
+    let Inst{17-16} = opc{1-0};
+    let Inst{15-13} = 0b101;
+    let Inst{12-10} = Pg;
+    let Inst{9-5}   = Zn;
+    let Inst{4-0}   = Zd;
+    let hasSideEffects = 0;
+    let mayRaiseFPException = 1;
+}
+
+multiclass sve_fp_fcvtntz<string asm> {
+  def _StoH : sve_fp_fcvt2z<0b1000, asm,  ZPR16, ZPR32>;
+  def _DtoS : sve_fp_fcvt2z<0b1110, asm,  ZPR32, ZPR64>;
+}
+
+multiclass sve_fp_fcvtltz<string asm> {
+  def _HtoS  : sve_fp_fcvt2z<0b1001, asm,  ZPR32, ZPR16>;
+  def _StoD  : sve_fp_fcvt2z<0b1111, asm,  ZPR64, ZPR32>;
+}
+
 //===----------------------------------------------------------------------===//
 // SVE2 Floating Point Pairwise Group
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/SVE/bfcvtnt-diagnostics.s b/llvm/test/MC/AArch64/SVE/bfcvtnt-diagnostics.s
index 4717204fb8620e..d21a555ff87c60 100644
--- a/llvm/test/MC/AArch64/SVE/bfcvtnt-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/bfcvtnt-diagnostics.s
@@ -11,7 +11,7 @@ bfcvtnt z0.h, p0/m, z1.h
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 bfcvtnt z0.h, 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: bfcvtnt z0.h, p0/z, z1.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2/fcvtlt-diagnostics.s b/llvm/test/MC/AArch64/SVE2/fcvtlt-diagnostics.s
index 01ff152191fc48..95c69b84057d54 100644
--- a/llvm/test/MC/AArch64/SVE2/fcvtlt-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/fcvtlt-diagnostics.s
@@ -39,7 +39,7 @@ fcvtlt z0.q, p0/m, z0.d
 // Invalid predicate operation
 
 fcvtlt z0.s, p0/z, z0.h
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: fcvtlt z0.s, p0/z, z0.h
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2/fcvtnt-diagnostics.s b/llvm/test/MC/AArch64/SVE2/fcvtnt-diagnostics.s
index ae287b94ec01b8..c42b8f56e62002 100644
--- a/llvm/test/MC/AArch64/SVE2/fcvtnt-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/fcvtnt-diagnostics.s
@@ -39,7 +39,7 @@ fcvtnt z0.d, p0/m, z0.q
 // Invalid predicate operation
 
 fcvtnt z0.h, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: fcvtnt z0.h, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2/fcvtxnt-diagnostics.s b/llvm/test/MC/AArch64/SVE2/fcvtxnt-diagnostics.s
index e5903fdd379624..3b3a24a52055d9 100644
--- a/llvm/test/MC/AArch64/SVE2/fcvtxnt-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/fcvtxnt-diagnostics.s
@@ -44,7 +44,7 @@ fcvtxnt z0.d, p0/m, z0.q
 // Invalid predicate operation
 
 fcvtxnt z0.s, p0/z, z0.d
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: fcvtxnt z0.s, p0/z, z0.d
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z-diagnostics.s
new file mode 100644
index 00000000000000..9a43f1f9e7c605
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z-diagnostics.s
@@ -0,0 +1,52 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element width
+
+bfcvtnt z0.s, p0/z, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.s, p0/z, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfcvtnt z0.d, p0/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.d, p0/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfcvtnt z0.h, p0/z, z1.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfcvtnt z0.h, p0/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfcvtnt z0.h, p0/z, z1.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}
+
+// --------------------------------------------------------------------------//
+// Predicate not in restricted predicate range
+
+bfcvtnt z0.h, p8/z, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: bfcvtnt z0.h, p8/z, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.h, p0/m, z7.h
+bfcvtnt z0.h, p0/z, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+bfcvtnt z0.h, p0/z, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z.s b/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z.s
new file mode 100644
index 00000000000000..6e4ab9d6ced902
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_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
+
+bfcvtnt z0.h, p0/z, z0.s  // 01100100-10000010-10100000-00000000
+// CHECK-INST: bfcvtnt z0.h, p0/z, z0.s
+// CHECK-ENCODING: [0x00,0xa0,0x82,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6482a000 <unknown>
+
+bfcvtnt z23.h, p3/z, z13.s  // 01100100-10000010-10101101-10110111
+// CHECK-INST: bfcvtnt z23.h, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0x82,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6482adb7 <unknown>
+
+bfcvtnt z31.h, p7/z, z31.s  // 01100100-10000010-10111111-11111111
+// CHECK-INST: bfcvtnt z31.h, p7/z, z31.s
+// CHECK-ENCODING: [0xff,0xbf,0x82,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6482bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-arch-negative.s b/llvm/test/MC/AArch64/SVE2p2/directive-arch-negative.s
new file mode 100644
index 00000000000000..6d5837eddec2cd
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-arch-negative.s
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch armv9-a+sve2p2
+.arch armv9-a+nosve2p2
+bfcvtnt z23.h, p3/z, z13.s
+// CHECK: error: instruction requires: sme2p2 or sve2p2
+// CHECK-NEXT: bfcvtnt z23.h, p3/z, z13.s
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-arch.s b/llvm/test/MC/AArch64/SVE2p2/directive-arch.s
new file mode 100644
index 00000000000000..e7a5c6efd9d7e3
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-arch.s
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch armv9-a+sve2p2
+bfcvtnt z23.h, p3/z, z13.s
+// CHECK: bfcvtnt z23.h, p3/z, z13.s
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension-negative.s
new file mode 100644
index 00000000000000..14b4cd722d04db
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension-negative.s
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch_extension sve2p2
+.arch_extension nosve2p2
+bfcvtnt z0.h, p0/z, z0.s
+// CHECK: error: instruction requires: sme2p2 or sve2p2
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z0.s
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension.s b/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension.s
new file mode 100644
index 00000000000000..d18ac8081b3e08
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension.s
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch_extension sve2p2
+bfcvtnt z0.h, p0/z, z0.s
+// CHECK: bfcvtnt z0.h, p0/z, z0.s
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-cpu-negative.s b/llvm/test/MC/AArch64/SVE2p2/directive-cpu-negative.s
new file mode 100644
index 00000000000000..fc172bbf756dbd
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-cpu-negative.s
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.cpu generic+sve2p2
+.cpu generic+nosve2p2
+fcvtnt  z0.s, p0/z, z0.d
+// CHECK: error: instruction requires: sme2p2 or sve2p2
+// CHECK-NEXT: fcvtnt  z0.s, p0/z, z0.d
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-cpu.s b/llvm/test/MC/AArch64/SVE2p2/directive-cpu.s
new file mode 100644
index 00000000000000..7874fa10f393c5
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-cpu.s
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.cpu generic+sve2p2
+fcvtnt  z0.s, p0/z, z0.d
+// CHECK: fcvtnt  z0.s, p0/z, z0.d
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z-diagnostics.s
new file mode 100644
index 00000000000000..14deea93ce946f
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z-diagnostics.s
@@ -0,0 +1,57 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element width
+
+fcvtlt z0.b, p0/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.b, p0/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.h, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.h, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.h, p0/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.h, p0/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.q, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.q, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Predicate not in restricted predicate range
+
+fcvtlt z0.s, p8/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: fcvtlt z0.s, p8/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.s, p0/z, z7.s
+fcvtlt z0.s, p7/z, z1.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtlt z0.s, p7/z, z1.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+fcvtlt z0.s, p7/z, z1.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtlt z0.s, p7/z, z1.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z.s b/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z.s
new file mode 100644
index 00000000000000..00028de3208dfd
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtlt_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
+
+fcvtlt  z0.d, p0/z, z0.s  // 01100100-11000011-10100000-00000000
+// CHECK-INST: fcvtlt  z0.d, p0/z, z0.s
+// CHECK-ENCODING: [0x00,0xa0,0xc3,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 64c3a000 <unknown>
+
+fcvtlt  z23.d, p3/z, z13.s  // 01100100-11000011-10101101-10110111
+// CHECK-INST: fcvtlt  z23.d, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0xc3,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 64c3adb7 <unknown>
+
+fcvtlt  z31.s, p7/z, z31.h  // 01100100-10000001-10111111-11111111
+// CHECK-INST: fcvtlt  z31.s, p7/z, z31.h
+// CHECK-ENCODING: [0xff,0xbf,0x81,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6481bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z-diagnostics.s
new file mode 100644
index 00000000000000..317eae1e3f6ea2
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z-diagnostics.s
@@ -0,0 +1,56 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element width
+
+fcvtnt z0.h, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtnt z0.h, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtnt z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtnt z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtnt z0.d, p0/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtnt z0.d, p0/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid operand for instruction
+
+fcvtnt z0.b, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fcvtnt z0.b, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtnt z0.b, p0/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fcvtnt z0.b, p0/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Predicate not in restricted predicate range
+
+fcvtnt z0.h, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: fcvtnt z0.h, 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
+fcvtnt z0.s, p7/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtnt z0.s, p7/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+fcvtnt z0.s, p7/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtnt z0.s, p7/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z.s b/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z.s
new file mode 100644
index 00000000000000..6c86c6d15e76b3
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtnt_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 \
+// R...
[truncated]

Copy link
Contributor

@jthackray jthackray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your commit message says: "FCVNT" but I think this should be "FCVTNT"

Copy link
Contributor

@jthackray jthackray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Lukacma Lukacma merged commit 2c5208a into llvm:main Oct 23, 2024
9 of 11 checks passed
@frobtech frobtech mentioned this pull request Oct 25, 2024
NoumanAmir657 pushed a commit to NoumanAmir657/llvm-project that referenced this pull request Nov 4, 2024
…ons (llvm#113292)

This patch adds the zeroing predicate forms (Pg/z) of the following
instructions:
	- FCVTXNT
	- FCVTNT
	- FCVTLT
	- BFCVTNT

As specified in https://developer.arm.com/documentation/ddi0602. 

Co-authored-by: Spencer Abson
[[email protected]](mailto:[email protected])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants