-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[llvm-exegesis] [AArch64] Reland Resolving "not all operands are initialized by snippet generator" #156423
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
[llvm-exegesis] [AArch64] Reland Resolving "not all operands are initialized by snippet generator" #156423
Changes from 30 commits
b1919dd
af68e0f
5697760
75c2e65
9d425dc
9a1feb2
f567870
66fdd39
59452e5
1726bea
c26aa00
f43b8e2
c26beda
ef67b17
aea8861
0f09343
5a56401
cd435fb
9ae23af
b0b4a5d
555ddf7
aa60946
6b593fe
ab92f0f
dbbed99
bda8043
2d7fc2f
93ec649
9787b4d
ac07228
a5c23a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| # REQUIRES: aarch64-registered-target | ||
|
|
||
|
|
||
|
|
||
| // Test for omitting OperandType::OPERAND_SHIFT_MSL | ||
|
|
||
| // MOVIv2s_msl: MOVI vd, #imm{, shift} | ||
| # RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=latency --benchmark-phase=prepare-and-assemble-snippet --opcode-name=MOVIv4s_msl 2>&1 | FileCheck %s --check-prefix=MOVIv4s_msl_latency | ||
| # RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=inverse_throughput --benchmark-phase=prepare-and-assemble-snippet --opcode-name=MOVIv4s_msl 2>&1 | FileCheck %s --check-prefix=MOVIv4s_msl_throughput | ||
| # MOVIv4s_msl_latency-NOT: Not all operands were initialized by the snippet generator for MOVIv4s_msl opcode | ||
|
|
||
| // TODO: Add test to check if the immediate value is correct when serial execution strategy is added for MOVIv4s_msl | ||
|
|
||
|
|
||
| # MOVIv4s_msl_throughput-NOT: Not all operands were initialized by the snippet generator for MOVIv4s_msl opcode | ||
| # MOVIv4s_msl_throughput: --- | ||
| # MOVIv4s_msl_throughput-NEXT: mode: inverse_throughput | ||
| # MOVIv4s_msl_throughput-NEXT: key: | ||
| # MOVIv4s_msl_throughput-NEXT: instructions: | ||
| # MOVIv4s_msl_throughput-NEXT: MOVIv4s_msl [[REG1:Q[0-9]+|LR]] i_0x1 i_0x108 | ||
| # MOVIv4s_msl_throughput: ... | ||
|
|
||
| // MOVIv2s_msl: MOVI vd, #imm{, shift} | ||
| # RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=latency --benchmark-phase=prepare-and-assemble-snippet --opcode-name=MOVIv2s_msl 2>&1 | FileCheck %s --check-prefix=MOVIv2s_msl_latency | ||
| # RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=inverse_throughput --benchmark-phase=prepare-and-assemble-snippet --opcode-name=MOVIv2s_msl 2>&1 | FileCheck %s --check-prefix=MOVIv2s_msl_throughput | ||
| # MOVIv2s_msl_latency-NOT: Not all operands were initialized by the snippet generator for MOVIv2s_msl opcode | ||
|
|
||
| // TODO: Add test to check if the immediate value is correct when serial execution strategy is added for MOVIv2s_msl | ||
|
|
||
|
|
||
| # MOVIv2s_msl_throughput-NOT: Not all operands were initialized by the snippet generator for MOVIv2s_msl opcode | ||
| # MOVIv2s_msl_throughput: --- | ||
| # MOVIv2s_msl_throughput-NEXT: mode: inverse_throughput | ||
| # MOVIv2s_msl_throughput-NEXT: key: | ||
| # MOVIv2s_msl_throughput-NEXT: instructions: | ||
| # MOVIv2s_msl_throughput-NEXT: MOVIv2s_msl [[REG1:D[0-9]+|LR]] i_0x1 i_0x108 | ||
| # MOVIv2s_msl_throughput: ... | ||
|
|
||
|
|
||
|
|
||
| // Test for omitting OperandType::OPERAND_PCREL | ||
| // LDRDl: LDRD ldr1, ldr2, [pc, #imm] | ||
| # RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=latency --benchmark-phase=prepare-and-assemble-snippet --opcode-name=LDRDl 2>&1 | FileCheck %s --check-prefix=LDRDl_latency | ||
| # RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=inverse_throughput --benchmark-phase=prepare-and-assemble-snippet --opcode-name=LDRDl 2>&1 | FileCheck %s --check-prefix=LDRDl_throughput | ||
|
|
||
| # LDRDl_latency-NOT: Not all operands were initialized by the snippet generator for LDRDl opcodes | ||
| # LDRDl_throughput-NOT: Not all operands were initialized by the snippet generator for LDRDl opcodes | ||
|
|
||
| # LDRDl_throughput: --- | ||
| # LDRDl_throughput-NEXT: mode: inverse_throughput | ||
| # LDRDl_throughput-NEXT: key: | ||
| # LDRDl_throughput-NEXT: instructions: | ||
| # LDRDl_throughput-NEXT: LDRDl [[REG1:D[0-9]+|LR]] i_0x8 | ||
| # LDRDl_throughput: ... | ||
|
|
||
|
|
||
|
|
||
| // Test for omitting OperandType::OPERAND_IMPLICIT_IMM_0 | ||
|
|
||
| // UMOVvi16_idx0: UMOV wd, vn.h[index] | ||
| # RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=latency --benchmark-phase=prepare-and-assemble-snippet --opcode-name=UMOVvi16_idx0 2>&1 | FileCheck %s --check-prefix=UMOVvi16_idx0_latency | ||
| # RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=inverse_throughput --benchmark-phase=prepare-and-assemble-snippet --opcode-name=UMOVvi16_idx0 2>&1 | FileCheck %s --check-prefix=UMOVvi16_idx0_throughput | ||
|
|
||
| # UMOVvi16_idx0_latency-NOT: UMOVvi16_idx0: Not all operands were initialized by the snippet generator for UMOVvi16_idx0 opcode. | ||
|
|
||
| # UMOVvi16_idx0_throughput-NOT: UMOVvi16_idx0: Not all operands were initialized by the snippet generator for UMOVvi16_idx0 opcode. | ||
| # UMOVvi16_idx0_throughput: --- | ||
| # UMOVvi16_idx0_throughput-NEXT: mode: inverse_throughput | ||
| # UMOVvi16_idx0_throughput-NEXT: key: | ||
| # UMOVvi16_idx0_throughput-NEXT: instructions: | ||
| # UMOVvi16_idx0_throughput-NEXT: UMOVvi16_idx0 [[REG1:W[0-9]+|LR]] [[REG2:Q[0-9]+|LR]] i_0x0 | ||
| # UMOVvi16_idx0_throughput: ... |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,6 +114,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 { | ||
|
|
@@ -152,6 +156,56 @@ 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; | ||
| // NOTE: To resolve "Not all operands were initialized by snippet generator" | ||
| // Requires OperandType to be defined for such opcode's operands in AArch64 | ||
| // tablegen files. And omit introduced OperandType(s). | ||
|
|
||
| // Hacky temporary fix works by defaulting all OPERAND_UNKNOWN to | ||
| // immediate value 0, but this introduce illegal instruction error for below | ||
| // system instructions will need to be omitted with OperandType or opcode | ||
| // specific values to avoid generating invalid encodings or unreliable | ||
| // benchmark results for these system-level instructions. | ||
| // Implement opcode-specific immediate value handling for system instrs: | ||
| // - MRS/MSR: Use valid system register encodings (e.g., NZCV, FPCR, FPSR) | ||
| // - MSRpstatesvcrImm1: Use valid PSTATE field encodings (e.g., SPSel, | ||
| // DAIFSet) | ||
| // - SYSLxt/SYSxt: Use valid system instruction encodings with proper | ||
| // CRn/CRm/op values | ||
| // - UDF: Use valid undefined instruction immediate ranges (0-65535) | ||
|
|
||
| switch (OperandType) { | ||
| // MSL (Masking Shift Left) imm operand for 32-bit splatted SIMD constants | ||
| // Correspond to AArch64InstructionSelector::tryAdvSIMDModImm321s() | ||
| case llvm::AArch64::OPERAND_SHIFT_MSL: { | ||
| // There are two valid encodings: | ||
| // - Type 7: imm at [15:8], [47:40], shift = 264 (0x108) → msl #8 | ||
| // - Type 8: imm at [23:16], [55:48], shift = 272 (0x110) → msl #16 | ||
| // Corresponds AArch64_AM::encodeAdvSIMDModImmType7() | ||
| // But, v2s_msl and v4s_msl instructions accept either form, | ||
| // Thus, Arbitrarily chosing 264 (msl #8) for simplicity. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we also count for 272 ? We may not want to enforce 264 always?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, this area needs some work in follow ups, but let's start somewhere with this, so is okay as a start. |
||
| AssignedValue = MCOperand::createImm(264); | ||
| return Error::success(); | ||
| } | ||
| case llvm::AArch64::OPERAND_IMPLICIT_IMM_0: | ||
| AssignedValue = MCOperand::createImm(0); | ||
| return Error::success(); | ||
| case MCOI::OperandType::OPERAND_PCREL: | ||
| AssignedValue = MCOperand::createImm(8); | ||
| 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() { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
but this introduces illegal instruction error for the below instructions.
System instructions ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the comment. Thanks!