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

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 17 20:15:06 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-tools-llvm-exegesis

Author: None (lakshayk-nv)

<details>
<summary>Changes</summary>

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 error "setReg is not implemented". This code will handle the above register class and initialize the registers using appropriate base instruction class. 

---
Full diff: https://github.com/llvm/llvm-project/pull/127564.diff


1 Files Affected:

- (modified) llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp (+55-1) 


``````````diff
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 5a7cc6f5e30d3..dc312f4916703 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -35,6 +35,48 @@ static MCInst loadImmediate(MCRegister Reg, unsigned RegBitWidth,
       .addImm(Value.getZExtValue());
 }
 
+static MCInst loadZPRImmediate(MCRegister Reg, unsigned RegBitWidth,
+                               const APInt &Value) {
+  if (Value.getBitWidth() > RegBitWidth)
+    llvm_unreachable("Value must fit in the ZPR Register");
+  // For ZPR, we typically use DUPM instruction to load immediate values
+  return MCInstBuilder(AArch64::DUPM_ZI)
+      .addReg(Reg)
+      .addImm(Value.getZExtValue());
+}
+
+static MCInst loadPPRImmediate(MCRegister Reg, unsigned RegBitWidth,
+                               const APInt &Value) {
+  if (Value.getBitWidth() > RegBitWidth)
+    llvm_unreachable("Value must fit in the PPR Register");
+  // For PPR, we typically use PTRUE instruction to set predicate registers
+  return MCInstBuilder(AArch64::PTRUE_B)
+      .addReg(Reg)
+      .addImm(31); // All lanes true
+}
+
+// Generates instruction to load an FP immediate value into a register.
+static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) {
+  switch (RegBitWidth) {
+  case 64:
+    return AArch64::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) {
+  if (Value.getBitWidth() > RegBitWidth)
+    llvm_unreachable("Value must fit in the FP Register");
+  return MCInstBuilder(getLoadFPImmediateOpcode(RegBitWidth))
+      .addReg(Reg)
+      .addImm(Value.getZExtValue());
+}
+
 #include "AArch64GenExegesis.inc"
 
 namespace {
@@ -51,6 +93,18 @@ 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 {};
   }
@@ -77,4 +131,4 @@ void InitializeAArch64ExegesisTarget() {
 }
 
 } // namespace exegesis
-} // namespace llvm
+} // namespace llvm
\ No newline at end of file

``````````

</details>


https://github.com/llvm/llvm-project/pull/127564


More information about the llvm-commits mailing list