[llvm] 9cc477b - [llvm-exegesis][AArch64] Handle register classes FPR8/16/32 and FPCR (#130595)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 11 06:47:19 PDT 2025


Author: lakshayk-nv
Date: 2025-03-11T13:47:16Z
New Revision: 9cc477be6ea1a4f7dd55e3dfa66a59c2dc59da25

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

LOG: [llvm-exegesis][AArch64] Handle register classes FPR8/16/32 and FPCR (#130595)

Current implementation (for AArch64) only supports the GRP32, GPR64,
FPR64/128, PPR16 and ZPR128 register classes. This adds support for
the other floating point register classes to initialize registers and avoid
the "setReg is not implemented" warning for these cases.

Added: 
    

Modified: 
    llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s
    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
index da28388c96094..a4350fc6dc2cb 100644
--- a/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s
+++ b/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s
@@ -37,3 +37,39 @@ 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
+
+## FPR32 Register Class Initialization Testcase
+RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=FABSSr --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=FPR32-ASM < %t.s
+FPR32-ASM:         <foo>:
+FPR32-ASM:         movi d{{[0-9]+}}, #0000000000000000
+FPR32-ASM-NEXT:    fabs s{{[0-9]+}}, s{{[0-9]+}}
+
+
+## FPR16 Register Class Initialization Testcase
+RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=FABSHr --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=FPR16-ASM < %t.s
+FPR16-ASM:         <foo>:
+FPR16-ASM:         movi d{{[0-9]+}}, #0000000000000000
+FPR16-ASM-NEXT:    fabs h{{[0-9]+}}, h{{[0-9]+}}
+
+## FPR8 Register Class Initialization Testcase
+RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=SQABSv1i8 --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=FPR8-ASM < %t.s
+FPR8-ASM:         <foo>:
+FPR8-ASM:         movi    d{{[0-9]+}}, #0000000000000000
+FPR8-ASM-NEXT:    sqabs   b{{[0-9]+}}, b{{[0-9]+}}
+
+
+## FPCR Register Class Initialization Testcase
+RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=BFCVT --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=FPCR-ASM < %t.s
+FPCR-ASM:         <foo>:
+FPCR-ASM:         movi    d{{[0-9]+}}, #0000000000000000
+FPCR-ASM-NEXT:    mov     x8, #0x0
+FPCR-ASM-NEXT:    msr     FPCR, x8
+FPCR-ASM-NEXT:    bfcvt   h{{[0-9]+}}, s{{[0-9]+}}

diff  --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index ed36cb2f75d5b..bf2b053003ce3 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -28,8 +28,8 @@ 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) {
-  assert (Value.getBitWidth() <= RegBitWidth &&
-          "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());
@@ -53,11 +53,25 @@ static MCInst loadPPRImmediate(MCRegister Reg, unsigned RegBitWidth,
       .addImm(31); // All lanes true for 16 bits
 }
 
+// Generates instructions to load an immediate value into an FPCR register.
+static std::vector<MCInst>
+loadFPCRImmediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value) {
+  MCRegister TempReg = AArch64::X8;
+  MCInst LoadImm = MCInstBuilder(AArch64::MOVi64imm).addReg(TempReg).addImm(0);
+  MCInst MoveToFPCR =
+      MCInstBuilder(AArch64::MSR).addImm(AArch64SysReg::FPCR).addReg(TempReg);
+  return {LoadImm, MoveToFPCR};
+}
+
 // Fetch base-instruction to load an FP immediate value into a register.
 static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) {
   switch (RegBitWidth) {
+  case 16:
+    return AArch64::FMOVH0; // FMOVHi;
+  case 32:
+    return AArch64::FMOVS0; // FMOVSi;
   case 64:
-    return AArch64::MOVID; //FMOVDi;
+    return AArch64::MOVID; // FMOVDi;
   case 128:
     return AArch64::MOVIv2d_ns;
   }
@@ -67,11 +81,12 @@ static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) {
 // 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());
+  assert(Value.getZExtValue() == 0 && "Expected initialisation value 0");
+  MCInst Instructions =
+      MCInstBuilder(getLoadFPImmediateOpcode(RegBitWidth)).addReg(Reg);
+  if (RegBitWidth >= 64)
+    Instructions.addOperand(MCOperand::createImm(Value.getZExtValue()));
+  return Instructions;
 }
 
 #include "AArch64GenExegesis.inc"
@@ -92,12 +107,20 @@ class ExegesisAArch64Target : public ExegesisTarget {
       return {loadImmediate(Reg, 64, Value)};
     if (AArch64::PPRRegClass.contains(Reg))
       return {loadPPRImmediate(Reg, 16, Value)};
+    if (AArch64::FPR8RegClass.contains(Reg))
+      return {loadFPImmediate(Reg - AArch64::B0 + AArch64::D0, 64, Value)};
+    if (AArch64::FPR16RegClass.contains(Reg))
+      return {loadFPImmediate(Reg, 16, Value)};
+    if (AArch64::FPR32RegClass.contains(Reg))
+      return {loadFPImmediate(Reg, 32, 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)};
+    if (Reg == AArch64::FPCR)
+      return {loadFPCRImmediate(Reg, 32, Value)};
 
     errs() << "setRegTo is not implemented, results will be unreliable\n";
     return {};


        


More information about the llvm-commits mailing list