[llvm] [LLVM][AArch64] Add assembly/disassembly of SVE BFSCALE instruction (PR #113168)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 22 04:22:15 PDT 2024


https://github.com/Lukacma updated https://github.com/llvm/llvm-project/pull/113168

>From a888d840cb8de5f0bb9e2341b365f2c1c5978507 Mon Sep 17 00:00:00 2001
From: Marian Lukac <Marian.Lukac at arm.com>
Date: Mon, 21 Oct 2024 14:11:58 +0000
Subject: [PATCH 1/3] [LLVM][AArch64] Add assembly/disassembly of SVE BFSCALE
 instruction

---
 .../lib/Target/AArch64/AArch64SVEInstrInfo.td |  4 +-
 llvm/lib/Target/AArch64/SVEInstrFormats.td    |  4 ++
 .../MC/AArch64/SVE2/bfscale-diagnostics.s     | 36 +++++++++++++
 llvm/test/MC/AArch64/SVE2/bfscale.s           | 50 +++++++++++++++++++
 .../MC/AArch64/SVE2/directive-arch-negative.s |  6 +++
 llvm/test/MC/AArch64/SVE2/directive-arch.s    |  4 ++
 .../SVE2/directive-arch_extension-negative.s  |  6 +++
 .../AArch64/SVE2/directive-arch_extension.s   |  4 ++
 .../MC/AArch64/SVE2/directive-cpu-negative.s  |  6 +++
 llvm/test/MC/AArch64/SVE2/directive-cpu.s     |  5 ++
 10 files changed, 124 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2/bfscale.s

diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 2a857234c7d745..94cbf6849fc0f5 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4163,7 +4163,9 @@ defm BFMIN_ZPZZ   : sve_fp_2op_p_zds_zeroing_bfloat<int_aarch64_sve_fmin>;
 defm BFMAX_ZPZZ   : sve_fp_2op_p_zds_zeroing_bfloat<int_aarch64_sve_fmax>;
 } // HasSVEB16B16, UseExperimentalZeroingPseudos
 
-
+let Predicates = [HasSVEBFSCALE] in {
+  def BFSCALE_ZPZZ : sve_fp_2op_p_zds_bfscale<0b1001, "bfscale", DestructiveBinaryComm>;
+} // HasSVEBFSCALE
 //===----------------------------------------------------------------------===//
 // SME2.1 or SVE2.1 instructions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index f655526fa81cfe..0fbdeab591f8ba 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -2174,6 +2174,10 @@ multiclass sve_fp_2op_p_zds_bfloat<bits<4> opc, string asm, string Ps,
   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
 }
 
+class  sve_fp_2op_p_zds_bfscale<bits<4> opc, string asm,  DestructiveInstTypeEnum flags> : sve_fp_2op_p_zds<0b00, opc, asm, ZPR16>{
+    let DestructiveInstType = flags;
+  }
+
 multiclass sve_fp_2op_p_zds_zeroing_hsd<SDPatternOperator op> {
   def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
   def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
diff --git a/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s b/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s
new file mode 100644
index 00000000000000..d95e8da5d33ba1
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s
@@ -0,0 +1,36 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve-bfscale  2>&1 < %s| FileCheck %s
+
+
+// ------------------------------------------------------------------------- //
+// Invalid element width
+
+bfscale z31.h, p7/m, z31.h, z31.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfscale z31.h, p7/m, z31.h, z31.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfscale z31.h, p7/m, z31.b, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfscale z31.h, p7/m, z31.b, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfscale z31.d, p7/m, z31.h, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfscale z31.d, p7/m, z31.h, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Predicate register out of range
+
+bfscale z31.h, p8/m, z31.h, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: bfscale z31.h, p8/m, z31.h, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Destination and source register don't match
+
+bfscale z31.h, p7/m, z20.h, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register
+// CHECK-NEXT: bfscale z31.h, p7/m, z20.h, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2/bfscale.s b/llvm/test/MC/AArch64/SVE2/bfscale.s
new file mode 100644
index 00000000000000..c655488ecd8dd1
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2/bfscale.s
@@ -0,0 +1,50 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+sve-bfscale < %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=+sve,+sve-bfscale < %s \
+// RUN:        | llvm-objdump -d --mattr=+sve,+sve-bfscale - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve,+sve-bfscale < %s \
+// RUN:        | llvm-objdump -d --mattr=-sve-bfscale - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+sve-bfscale < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sve,+sve-bfscale -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+bfscale z0.h, p0/m, z0.h, z0.h  // 01100101-00001001-10000000-00000000
+// CHECK-INST: bfscale z0.h, p0/m, z0.h, z0.h
+// CHECK-ENCODING: [0x00,0x80,0x09,0x65]
+// CHECK-ERROR: instruction requires: sve-bfscale
+// CHECK-UNKNOWN: 65098000 <unknown>
+
+bfscale z21.h, p5/m, z21.h, z10.h  // 01100101-00001001-10010101-01010101
+// CHECK-INST: bfscale z21.h, p5/m, z21.h, z10.h
+// CHECK-ENCODING: [0x55,0x95,0x09,0x65]
+// CHECK-ERROR: instruction requires: sve-bfscale
+// CHECK-UNKNOWN: 65099555 <unknown>
+
+bfscale z31.h, p7/m, z31.h, z31.h  // 01100101-00001001-10011111-11111111
+// CHECK-INST: bfscale z31.h, p7/m, z31.h, z31.h
+// CHECK-ENCODING: [0xff,0x9f,0x09,0x65]
+// CHECK-ERROR: instruction requires: sve-bfscale
+// CHECK-UNKNOWN: 65099fff <unknown>
+
+// --------------------------------------------------------------------------//
+// Test compatibility with MOVPRFX instruction.
+
+movprfx  z23.h, p3/m, z31.h
+bfscale z23.h, p3/m, z23.h, z13.h  // 01100101-00001001-10001101-10110111
+// CHECK-INST:  movprfx  z23.h, p3/m, z31.h
+// CHECK-INST: bfscale z23.h, p3/m, z23.h, z13.h
+// CHECK-ENCODING: [0xb7,0x8d,0x09,0x65]
+// CHECK-ERROR: instruction requires: sve-bfscale
+// CHECK-UNKNOWN: 65098db7 <unknown>
+
+movprfx z23, z31
+bfscale z23.h, p3/m, z23.h, z13.h  // 01100101-00001001-10001101-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: bfscale z23.h, p3/m, z23.h, z13.h
+// CHECK-ENCODING: [0xb7,0x8d,0x09,0x65]
+// CHECK-ERROR: instruction requires: sve-bfscale
+// CHECK-UNKNOWN: 65098db7 <unknown>
diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s b/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s
index 767e5dc5a1513b..858aaf9d13ecc4 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s
@@ -29,3 +29,9 @@ rax1 z0.d, z0.d, z0.d
 bgrp z21.s, z10.s, z21.s
 // CHECK: error: instruction requires: sve2-bitperm
 // CHECK-NEXT: bgrp z21.s, z10.s, z21.s
+
+.arch armv9-a+sve-bfscale
+.arch armv9-a+nosve-bfscale
+bfscale z0.h, p0/m, z0.h, z0.h
+// CHECK: error: instruction requires: sve-bfscale
+// CHECK-NEXT: bfscale z0.h, p0/m, z0.h, z0.h
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch.s b/llvm/test/MC/AArch64/SVE2/directive-arch.s
index 0a921ccf5e4f0f..b9710b67f8a1d0 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-arch.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-arch.s
@@ -19,3 +19,7 @@ rax1 z0.d, z0.d, z0.d
 .arch armv9-a+sve2-bitperm
 bgrp z21.s, z10.s, z21.s
 // CHECK: bgrp z21.s, z10.s, z21.s
+
+.arch armv9-a+sve-bfscale
+bfscale z0.h, p0/m, z0.h, z0.h
+// CHECK: bfscale z0.h, p0/m, z0.h, z0.h
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s
index 6d90f7f0574900..bd625d25262692 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s
@@ -29,3 +29,9 @@ rax1 z0.d, z0.d, z0.d
 bgrp z21.s, z10.s, z21.s
 // CHECK: error: instruction requires: sve2-bitperm
 // CHECK-NEXT: bgrp z21.s, z10.s, z21.s
+
+.arch_extension sve-bfscale
+.arch_extension nosve-bfscale
+bfscale z0.h, p0/m, z0.h, z0.h
+// CHECK: error: instruction requires: sve-bfscale
+// CHECK-NEXT: bfscale z0.h, p0/m, z0.h, z0.h
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s b/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s
index 90f5bec07d5426..28d803bf7cc88c 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s
@@ -19,3 +19,7 @@ rax1 z0.d, z0.d, z0.d
 .arch_extension sve2-bitperm
 bgrp z21.s, z10.s, z21.s
 // CHECK: bgrp z21.s, z10.s, z21.s
+
+.arch_extension sve-bfscale
+bfscale z0.h, p0/m, z0.h, z0.h
+// CHECK: bfscale z0.h, p0/m, z0.h, z0.h
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2/directive-cpu-negative.s b/llvm/test/MC/AArch64/SVE2/directive-cpu-negative.s
index ed99aa7f007865..45a04a58eac3b4 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-cpu-negative.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-cpu-negative.s
@@ -29,3 +29,9 @@ rax1 z0.d, z0.d, z0.d
 bgrp z21.s, z10.s, z21.s
 // CHECK: error: instruction requires: sve2-bitperm
 // CHECK-NEXT: bgrp z21.s, z10.s, z21.s
+
+.cpu generic+sve-bfscale
+.cpu generic+nosve-bfscale
+bfscale z0.h, p0/m, z0.h, z0.h
+// CHECK: error: instruction requires: sve-bfscale
+// CHECK-NEXT: bfscale z0.h, p0/m, z0.h, z0.h
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2/directive-cpu.s b/llvm/test/MC/AArch64/SVE2/directive-cpu.s
index b3cacc46c1ddce..e57e1fd28ffcee 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-cpu.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-cpu.s
@@ -19,3 +19,8 @@ rax1 z0.d, z0.d, z0.d
 .cpu generic+sve2-bitperm
 bgrp z21.s, z10.s, z21.s
 // CHECK: bgrp z21.s, z10.s, z21.s
+
+.cpu generic+sve-bfscale
+bfscale z0.h, p0/m, z0.h, z0.h
+// CHECK-d: error: instruction requires: sve-bfscale
+// CHECK: bfscale z0.h, p0/m, z0.h, z0.h
\ No newline at end of file

>From 926f24c851af0f6331dd180e239b84ee002a57d5 Mon Sep 17 00:00:00 2001
From: Marian Lukac <Marian.Lukac at arm.com>
Date: Tue, 22 Oct 2024 10:20:29 +0000
Subject: [PATCH 2/3] Adress review comments

---
 llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td | 2 +-
 llvm/lib/Target/AArch64/SVEInstrFormats.td     | 7 ++++---
 llvm/test/MC/AArch64/SVE2/directive-cpu.s      | 4 ++--
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 94cbf6849fc0f5..25899ee83f257d 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4164,7 +4164,7 @@ defm BFMAX_ZPZZ   : sve_fp_2op_p_zds_zeroing_bfloat<int_aarch64_sve_fmax>;
 } // HasSVEB16B16, UseExperimentalZeroingPseudos
 
 let Predicates = [HasSVEBFSCALE] in {
-  def BFSCALE_ZPZZ : sve_fp_2op_p_zds_bfscale<0b1001, "bfscale", DestructiveBinaryComm>;
+  def BFSCALE_ZPZZ : sve_fp_2op_p_zds_bfscale<0b1001, "bfscale", DestructiveBinary>;
 } // HasSVEBFSCALE
 //===----------------------------------------------------------------------===//
 // SME2.1 or SVE2.1 instructions
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 0fbdeab591f8ba..b5665e30b88d78 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -2174,9 +2174,10 @@ multiclass sve_fp_2op_p_zds_bfloat<bits<4> opc, string asm, string Ps,
   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
 }
 
-class  sve_fp_2op_p_zds_bfscale<bits<4> opc, string asm,  DestructiveInstTypeEnum flags> : sve_fp_2op_p_zds<0b00, opc, asm, ZPR16>{
-    let DestructiveInstType = flags;
-  }
+class  sve_fp_2op_p_zds_bfscale<bits<4> opc, string asm,  DestructiveInstTypeEnum flags>
+: sve_fp_2op_p_zds<0b00, opc, asm, ZPR16>{
+  let DestructiveInstType = flags;
+}
 
 multiclass sve_fp_2op_p_zds_zeroing_hsd<SDPatternOperator op> {
   def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
diff --git a/llvm/test/MC/AArch64/SVE2/directive-cpu.s b/llvm/test/MC/AArch64/SVE2/directive-cpu.s
index e57e1fd28ffcee..ed84129e9e6192 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-cpu.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-cpu.s
@@ -22,5 +22,5 @@ bgrp z21.s, z10.s, z21.s
 
 .cpu generic+sve-bfscale
 bfscale z0.h, p0/m, z0.h, z0.h
-// CHECK-d: error: instruction requires: sve-bfscale
-// CHECK: bfscale z0.h, p0/m, z0.h, z0.h
\ No newline at end of file
+// CHECK: error: instruction requires: sve-bfscale
+// CHECK-NEXT: bfscale z0.h, p0/m, z0.h, z0.h
\ No newline at end of file

>From 4ec1b32d97a30a7bfa0a583421606081a4bf9216 Mon Sep 17 00:00:00 2001
From: Marian Lukac <Marian.Lukac at arm.com>
Date: Tue, 22 Oct 2024 11:21:06 +0000
Subject: [PATCH 3/3] Added negative test for zeroing predicate

---
 llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s b/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s
index d95e8da5d33ba1..9be311df26007e 100644
--- a/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s
@@ -33,4 +33,11 @@ bfscale z31.h, p8/m, z31.h, z31.h
 bfscale z31.h, p7/m, z20.h, z31.h
 // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register
 // CHECK-NEXT: bfscale z31.h, p7/m, z20.h, z31.h
-// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Using zeroing predicate
+bfscale z0.h, p0/z, z0.h, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: bfscale z0.h, p0/z, z0.h, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:



More information about the llvm-commits mailing list