[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