[llvm] d61d219 - Adding support in llvm-exegesis for Aarch64 for handling FPR64/128, PPR16 and ZPR128 reg class. (#127564)

via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 6 01:02:58 PST 2025


Author: lakshayk-nv
Date: 2025-03-06T09:02:54Z
New Revision: d61d2197390161db86b48d044970f48132139ccb

URL: https://github.com/llvm/llvm-project/commit/d61d2197390161db86b48d044970f48132139ccb
DIFF: https://github.com/llvm/llvm-project/commit/d61d2197390161db86b48d044970f48132139ccb.diff

LOG: Adding support in llvm-exegesis for Aarch64 for handling FPR64/128, PPR16 and ZPR128 reg class. (#127564)

Current implementation (for Aarch64) in llvm-exegesis only supports
GRP32 and GPR64 bit register class, thus for opcodes variants which used
FPR64/128, PPR16 and ZPR128, llvm-exegesis throws warning "setReg is not
implemented". This code will handle the above register class and
initialize the registers using appropriate base instruction class.

Added: 
    llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s

Modified: 
    llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s b/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s
new file mode 100644
index 0000000000000..1b69ac68a2b30
--- /dev/null
+++ b/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s
@@ -0,0 +1,39 @@
+REQUIRES: aarch64-registered-target
+
+## PPR Register Class Initialization Testcase
+## Ideally, we should use PTRUE_{B/H/S/D} instead of FADDV_VPZ_D for an isolated test case; 
+## However, exegesis does not yet support PTRUE_{B/H/S/D}.
+RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=FADDV_VPZ_D 2>&1 
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=PPR_ASM < %t.s
+PPR_ASM:            <foo>:
+PPR_ASM:            ptrue p{{[0-9]+}}.b
+PPR_ASM-NEXT:       mov z{{[0-9]+}}.d, #0x0
+PPR_ASM-NEXT:       faddv d{{[0-9]+}}, p{{[0-9]+}}, z{{[0-9]+}}
+
+## ZPR Register Class Initialization Testcase
+## Ideally, we should use DUP_ZI_{B/H/S/D} instead of FADDV_VPZ_D for an isolated test case; 
+## However, exegesis does not yet support DUP_ZI_{B/H/S/D}.
+RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=FADDV_VPZ_D 2>&1 
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=ZPR_ASM < %t.s
+ZPR_ASM:            <foo>:
+ZPR_ASM:            ptrue p{{[0-9]+}}.b
+ZPR_ASM-NEXT:       mov z{{[0-9]+}}.d, #0x0
+ZPR_ASM-NEXT:       faddv d{{[0-9]+}}, p{{[0-9]+}}, z{{[0-9]+}}
+
+## FPR128 Register Class Initialization Testcase
+RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=ADDVv16i8v 2>&1 
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=FPR128-ASM < %t.s
+FPR128-ASM:         <foo>:
+FPR128-ASM:         movi v{{[0-9]+}}.2d, #0000000000000000
+FPR128-ASM-NEXT:    addv b{{[0-9]+}}, v{{[0-9]+}}.16b
+
+## FPR64 Register Class Initialization Testcase
+RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=ADDVv4i16v 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=FPR64-ASM < %t.s
+FPR64-ASM:          <foo>:
+FPR64-ASM:          movi d{{[0-9]+}}, #0000000000000000
+FPR64-ASM-NEXT:     addv h{{[0-9]+}}, v{{[0-9]+}}.4h

diff  --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 5a7cc6f5e30d3..ed36cb2f75d5b 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -28,13 +28,52 @@ static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
 // Generates instruction to load an immediate value into a register.
 static MCInst loadImmediate(MCRegister Reg, unsigned RegBitWidth,
                             const APInt &Value) {
-  if (Value.getBitWidth() > RegBitWidth)
-    llvm_unreachable("Value must fit in the Register");
+  assert (Value.getBitWidth() <= RegBitWidth &&
+          "Value must fit in the Register");
   return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
       .addReg(Reg)
       .addImm(Value.getZExtValue());
 }
 
+static MCInst loadZPRImmediate(MCRegister Reg, unsigned RegBitWidth,
+                               const APInt &Value) {
+  assert(Value.getZExtValue() < (1 << 7) &&
+         "Value must be in the range of the immediate opcode");
+  return MCInstBuilder(AArch64::DUP_ZI_D)
+      .addReg(Reg)
+      .addImm(Value.getZExtValue())
+      .addImm(0);
+}
+
+static MCInst loadPPRImmediate(MCRegister Reg, unsigned RegBitWidth,
+                               const APInt &Value) {
+  // For PPR, we typically use PTRUE instruction to set predicate registers
+  return MCInstBuilder(AArch64::PTRUE_B)
+      .addReg(Reg)
+      .addImm(31); // All lanes true for 16 bits
+}
+
+// Fetch base-instruction to load an FP immediate value into a register.
+static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) {
+  switch (RegBitWidth) {
+  case 64:
+    return AArch64::MOVID; //FMOVDi;
+  case 128:
+    return AArch64::MOVIv2d_ns;
+  }
+  llvm_unreachable("Invalid Value Width");
+}
+
+// Generates instruction to load an FP immediate value into a register.
+static MCInst loadFPImmediate(MCRegister Reg, unsigned RegBitWidth,
+                              const APInt &Value) {
+  assert(Value.getZExtValue() == 0 &&
+         "Expected initialisation value 0");
+  return MCInstBuilder(getLoadFPImmediateOpcode(RegBitWidth))
+      .addReg(Reg)
+      .addImm(Value.getZExtValue());
+}
+
 #include "AArch64GenExegesis.inc"
 
 namespace {
@@ -51,6 +90,15 @@ class ExegesisAArch64Target : public ExegesisTarget {
       return {loadImmediate(Reg, 32, Value)};
     if (AArch64::GPR64RegClass.contains(Reg))
       return {loadImmediate(Reg, 64, Value)};
+    if (AArch64::PPRRegClass.contains(Reg))
+      return {loadPPRImmediate(Reg, 16, Value)};
+    if (AArch64::FPR64RegClass.contains(Reg))
+      return {loadFPImmediate(Reg, 64, Value)};
+    if (AArch64::FPR128RegClass.contains(Reg))
+      return {loadFPImmediate(Reg, 128, Value)};
+    if (AArch64::ZPRRegClass.contains(Reg))
+      return {loadZPRImmediate(Reg, 128, Value)};
+
     errs() << "setRegTo is not implemented, results will be unreliable\n";
     return {};
   }


        


More information about the llvm-commits mailing list