Skip to content

[llvm-exegesis] [AArch64] Resolving "not all operands are initialized by snippet generator" #142529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: main
Choose a base branch
from

Conversation

lakshayk-nv
Copy link
Contributor

@lakshayk-nv lakshayk-nv commented Jun 3, 2025

Exegesis for AArch64 arch, before this patch only handles/initialize Immediate and Register Operands.
For opcodes requiring rest operand types exegesis exits with Error: "not all operands are initialized by snippet generator".

Thus, to resolve a given error we have to initialize required operand types.
i.e., For "not all operands are initialized by snippet generator" init OPERAND_UNKNOWN, OPERAND_PCREL,
And For "targets with target-specific operands should implement this" init "OPERAND_FIRST_TARGET"

Implementing randomizeTargetMCOperand() for AArch64 that omitting OPERAND_UNKNOWN and OPERAND_PCREL to an immediate value based on opcode.
PS: Omitting OPERAND_FIRST_TARGET similarly, It was low hanging change thus added in this PR only.

For any future operand type of AArch64 if not initialized will exit with error "Unimplemented operand type: MCOI::OperandType:<#Number>"


FIXME: Init operands forMRS, MSR, MSRpstatesvcrImm1, SYSLxt, SYSxt, UDF
This patch in --mode=inverse_throughput for opcodes MRS, MSR, MSRpstatesvcrImm1, SYSLxt, SYSxt, UDF exits with handled error of snippet crashed while running: Illegal instruction, they previously used to exits with error not all operands initialized by snippet generator.

This patch doesn't regress any working opcode. And valid initialization of operands for those 6 opcodes will be in upcoming PRs.

[For completeness] Additionally, exegesis beforehand and with this patch too, throws illegal instruction in throughput mode, for these opcodes too (APAS, DCPS1, DCPS2, DCPS3, HLT, HVC, SMC, STGM, STZGM). Will look into them later.

  • Remove aarch64 guard in SnippetGenerator.cpp.

Please review: @sjoerdmeijer, @boomanaiden154, @davemgreen

@llvmbot
Copy link
Member

llvmbot commented Jun 3, 2025

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

Author: Lakshay Kumar (lakshayk-nv)

Changes

Implementing randomizeTargetMCOperand() for AArch64 that omitting OPERAND_UNKNOWN and OPERAND_PCREL to an immediate value based on opcode.


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

2 Files Affected:

  • (modified) llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp (+38)
  • (modified) llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp (+8)
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index a1eb5a46f21fc..285d888770a53 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -162,6 +162,10 @@ class ExegesisAArch64Target : public ExegesisTarget {
   ExegesisAArch64Target()
       : ExegesisTarget(AArch64CpuPfmCounters, AArch64_MC::isOpcodeAvailable) {}
 
+  Error randomizeTargetMCOperand(
+      const Instruction &Instr, const Variable &Var, MCOperand &AssignedValue,
+      const BitVector &ForbiddenRegs) const override;
+
 private:
   std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, MCRegister Reg,
                                const APInt &Value) const override {
@@ -229,6 +233,40 @@ class ExegesisAArch64Target : public ExegesisTarget {
   }
 };
 
+Error ExegesisAArch64Target::randomizeTargetMCOperand(
+    const Instruction &Instr, const Variable &Var, MCOperand &AssignedValue,
+    const BitVector &ForbiddenRegs) const {
+  const Operand &Op = Instr.getPrimaryOperand(Var);
+  const auto OperandType = Op.getExplicitOperandInfo().OperandType;
+  // Introducing some illegal instructions for (15) a few opcodes
+  // TODO: Look into immediate values to be opcode specific
+  switch (OperandType) {
+    case MCOI::OperandType::OPERAND_UNKNOWN: {
+      unsigned Opcode = Instr.getOpcode();
+      switch (Opcode) {
+        case AArch64::MOVIv2s_msl:
+        case AArch64::MOVIv4s_msl:
+        case AArch64::MVNIv2s_msl:
+        case AArch64::MVNIv4s_msl:
+          AssignedValue = MCOperand::createImm(8); // or 16, as needed
+          return Error::success();
+        default:
+          AssignedValue = MCOperand::createImm(0);
+          return Error::success();
+      }
+    }
+    case MCOI::OperandType::OPERAND_PCREL:
+      AssignedValue = MCOperand::createImm(0);
+      return Error::success();
+    default:
+      break;
+  }
+
+  return make_error<Failure>(
+      Twine("Unimplemented operand type: MCOI::OperandType:")
+          .concat(Twine(static_cast<int>(OperandType))));
+}
+
 } // namespace
 
 static ExegesisTarget *getTheExegesisAArch64Target() {
diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
index 04064ae1d8441..d4381c3b123f0 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
@@ -276,6 +276,14 @@ static Error randomizeMCOperand(const LLVMState &State,
     AssignedValue = MCOperand::createReg(randomBit(AllowedRegs));
     break;
   }
+  /// Omit unknown and pc-relative operands to imm value based on the instruction
+  // TODO: Neccesity of AArch64 guard ?
+#ifdef __aarch64__
+  case MCOI::OperandType::OPERAND_UNKNOWN:
+  case MCOI::OperandType::OPERAND_PCREL:
+    return State.getExegesisTarget().randomizeTargetMCOperand(
+        Instr, Var, AssignedValue, ForbiddenRegs);
+#endif
   default:
     break;
   }

Copy link

github-actions bot commented Jun 3, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@RKSimon RKSimon requested a review from boomanaiden154 June 3, 2025 07:01
Copy link
Contributor

@boomanaiden154 boomanaiden154 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also needs a test.

case AArch64::MOVIv4s_msl:
case AArch64::MVNIv2s_msl:
case AArch64::MVNIv4s_msl:
AssignedValue = MCOperand::createImm(8); // or 16, as needed
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this would be marked as a OPERAND_IMMEDIATE with a range that tablegen understood, so that it could be used for validation of codegen and reused here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, If i understood this correctly Ideally tablegen file can be updated.
Currently, the generated .inc file have OPERAND_UNKNOWN for opcode that thrown uninit operands.
Omission works out to get us benchmarking measurements for opcodes throwing this error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As expanded on later comments, Introduced two new operand kinds OPERAND_MSL_SHIFT_2S and OPERAND_MSL_SHIFT_4S in AArch64 backend.

Thanks!

@davemgreen davemgreen requested a review from sjoerdmeijer June 3, 2025 08:08
@lakshayk-nv
Copy link
Contributor Author

Resolving: targets with target-specific operands should implement this
Low hanging, Omission OPERAND_FIRST_TARGET with Immediate of value 0.
[Effect]
Support added for ASIMD UMOV, SMOV INDEX_RR_H, and few Load instructions.

INDEX_RR_H,
UMOVvi8_idx0,UMOVvi16_idx0,UMOVvi32_idx0,UMOVvi64_idx0,
SMOVvi8to64_idx0,SMOVvi8to32_idx0,SMOVvi32to64_idx0,SMOVvi16to64_idx0,SMOVvi16to32_idx0

Support added and expectedly segfault appears
LD2W,LD1Onev16b,LD2Twov16b,LD4Fourv4h,LDPSi,LD2Rv4s,LD4Rv2s

@sjoerdmeijer
Copy link
Collaborator

I would also like to see a test case.
Or is that difficult because this is randomising the registers? But from a quick look, we are not really randomly assigning values, always 0, so we could easily add test cases?

@boomanaiden154
Copy link
Contributor

Or is that difficult because this is randomising the registers?

Even if we are randomizing registers, a regex of some form would probably suffice.

@lakshayk-nv
Copy link
Contributor Author

Added the testcase for the patch for each operand type and mode (latency and throughput).
Thanks!

Copy link
Collaborator

@sjoerdmeijer sjoerdmeijer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is forward progress as it now is able to successfully generate and execute more snippets and handle more cases, so looks good to me from that point of view, and I am okay that are limitations and TODOs. However, before we merge this, I would like to see more crisps descriptions and comments, so that we understand better the limitations of the current work and what we would need to do next.

The description of this patch isn't clear to me, it doesn't parse for me:

Implementing randomizeTargetMCOperand() for AArch64 that omitting OPERAND_UNKNOWN and OPERAND_PCREL to an immediate value based on opcode.

I don't understand "omitting" here, so please clarify. The way I understand it at this moment, I think you mean to say that you now actually handle these operand types, but I could be wrong.

Copy link
Contributor

@abhilash1910 abhilash1910 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo other reviewer's comments

Copy link
Collaborator

@davemgreen davemgreen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this, I think it will be useful for adding verifier checks too.

// Creates 2-element 32-bit vector with 8-bit imm at positions [15:8] &
// [47:40] Shift value 264 (0x108) for Type 7 pattern encoding Corresponds
// to AArch64_AM::encodeAdvSIMDModImmType7()
AssignedValue = MCOperand::createImm(264);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use 264 for one and 272 for the other? (And does the immediate matter for scheduling?)

Am I right that both MOVIv2s_msl and MOVIv4s_msl accept both immediates, depending on the shift amount. We might as well just pick one for both I think. Maybe in the comment say that it can be 264 (msl #8) or 272 (msl #16), so we pick 264.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, For simplicity we can use 264 (msl#8). As, there is no change in instruction characteristics (inverse_throughput), just the underlying generated assembly from msl #16 to msl #8

@@ -276,6 +276,12 @@ static Error randomizeMCOperand(const LLVMState &State,
AssignedValue = MCOperand::createReg(randomBit(AllowedRegs));
break;
}
/// Omit unknown and pc-relative operands to imm value based on the
/// instruction
case MCOI::OperandType::OPERAND_UNKNOWN:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be removed too I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is helps us to get measurement values for 1000+ opcode. We have sanity checked this by comparing the measurements values reported by exegesis and (latency and inverse-throughput) for them. And there are few opcodes for which omitting immediate with value 0 is incorrect, They are documented in code and this PR (like UDF, `SYSLxt)

@@ -1319,7 +1319,9 @@ def logical_vec_hw_shift : Operand<i32> {
// A vector move shifter operand:
// {0} - imm1: #8 or #16
def move_vec_shift : Operand<i32> {
let OperandNamespace = "AArch64";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is needed put it next to OperandType and maybe put them both at the bottom.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved definition below OPERAND_IMMEDIATE. Please confirm if this is what is meant by you.
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants