Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b1919dd
[llvm-exegesis] [AArch64] Resolve " Not all operands were initialized…
lakshayk-nv May 30, 2025
af68e0f
[llvm-exegesis] [AArch64] Include OPERAND_PCREL operand handling in s…
lakshayk-nv Jun 1, 2025
5697760
[llvm-exegesis] [AArch64] WIP. Introduce handling for OPERAND_FIRST_T…
lakshayk-nv Jun 2, 2025
75c2e65
[llvm-exegesis] [AArch64] Explore opcode-specific immediate values fo…
lakshayk-nv Jun 2, 2025
9d425dc
[llvm-exegesis] [AArch64] Refactor operand handling in randomizeTarge…
lakshayk-nv Jun 2, 2025
9a1feb2
[llvm-exegesis] [AArch64] Update comments for operand handling and re…
lakshayk-nv Jun 3, 2025
f567870
[llvm-exegesis] [AArch64] Format changes.
lakshayk-nv Jun 3, 2025
66fdd39
[llvm-exegesis] [AArch64] Remove unneccessary AArch64 guard
lakshayk-nv Jun 3, 2025
59452e5
[llvm-exegesis] [AArch64] Add handling for OPERAND_FIRST_TARGET in ra…
lakshayk-nv Jun 11, 2025
1726bea
[llvm-exegesis] [AArch64] Documenting opcodes requiring some specific…
lakshayk-nv Jun 11, 2025
c26aa00
[llvm-exegesis] [AArch64] Add tests for operand omission scenarios in…
lakshayk-nv Jun 16, 2025
f43b8e2
[llvm-exegesis] [AArch64] Reporting limitation in initializing operan…
lakshayk-nv Jun 27, 2025
c26beda
[llvm-exegesis] [AArch64] Enhance randomizeTargetMCOperand to support…
lakshayk-nv Jul 2, 2025
ef67b17
[llvm-exegesis] [AArch64] Update test to reflect changes in immediate…
lakshayk-nv Jul 2, 2025
aea8861
[llvm-exegesis] [AArch64] Clang Format
lakshayk-nv Jul 2, 2025
0f09343
[AArch64] Introduce new operand types for MSL shifts and update relat…
lakshayk-nv Aug 13, 2025
5a56401
[AArch64] Update randomizeTargetMCOperand to handle MSL immediate ope…
lakshayk-nv Aug 13, 2025
cd435fb
[AArch64] Clang Format
lakshayk-nv Aug 14, 2025
9ae23af
[llvm-exegesis] [AArch64] Updated tescase to check introduced OPERAND…
lakshayk-nv Aug 14, 2025
b0b4a5d
Merge branch 'main' into llvm-exegesis-uninit-operands
lakshayk-nv Aug 14, 2025
555ddf7
[AArch64] Introduce single `OPERAND_MSL_SHIFT` for both 2s and 4s o…
lakshayk-nv Aug 19, 2025
aa60946
[AArch64] Update MSL shift handling toopcode specific switch case
lakshayk-nv Aug 19, 2025
6b593fe
[AArch64] Cleanup unrequired changes
lakshayk-nv Aug 19, 2025
ab92f0f
[llvm-exegesis] [AArch64] Revert redundant PR_PAC_* constants
lakshayk-nv Aug 20, 2025
dbbed99
[llvm-exegesis] [AArch64] Simplifies shift value for all move_vec_shi…
lakshayk-nv Aug 20, 2025
bda8043
[AArch64] Shifted defination OPERAND_MSL_SHIFT for readability NFC
lakshayk-nv Aug 20, 2025
2d7fc2f
clang format
lakshayk-nv Aug 20, 2025
93ec649
[AArch64] Refactor move_vec_shift operand def and update operand type…
lakshayk-nv Aug 26, 2025
9787b4d
[[lvm-exegesis] [AArch64] Updated PCREL imm value to 8 and Updated co…
lakshayk-nv Aug 27, 2025
ac07228
[llvm-exegesis] [AArch64] Correct UMOVvi16_idx0 latency testcase
lakshayk-nv Sep 2, 2025
a5c23a3
[llvm-exegesis] [AArch64] Fixed comment clarity on hacky fix by omitt…
lakshayk-nv Sep 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,8 @@ def move_vec_shift : Operand<i32> {
let PrintMethod = "printShifter";
let EncoderMethod = "getMoveVecShifterOpValue";
let ParserMatchClass = MoveVecShifterOperand;
let OperandType = "OPERAND_SHIFT_MSL";
let OperandNamespace = "AArch64";
}

let DiagnosticType = "AddSubSecondSource" in {
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,16 @@ void initLLVMToCVRegMapping(MCRegisterInfo *MRI);
bool isHForm(const MCInst &MI, const MCInstrInfo *MCII);
bool isQForm(const MCInst &MI, const MCInstrInfo *MCII);
bool isFpOrNEON(const MCInst &MI, const MCInstrInfo *MCII);
}
} // namespace AArch64_MC

namespace AArch64 {
enum OperandType {
OPERAND_IMPLICIT_IMM_0 = MCOI::OPERAND_FIRST_TARGET,
OPERAND_SHIFT_MSL,
};
} // namespace AArch64

} // End llvm namespace
} // namespace llvm

// Defines symbolic names for AArch64 registers. This defines a mapping from
// register name to register number.
Expand Down
72 changes: 72 additions & 0 deletions llvm/test/tools/llvm-exegesis/AArch64/error-resolution.s
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: ...
54 changes: 54 additions & 0 deletions llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 Fix: Defaulting all OPERAND_UNKNOWN to immediate value 0 works with a
// limitation that it introduces illegal instruction error for system
// instructions. 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.
Copy link
Contributor

@abhilash1910 abhilash1910 Sep 2, 2025

Choose a reason for hiding this comment

The 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?
Edit: This can be extended for other imm operands which are defaulted to some value, probably in a separate patch- essentially "taking value as an arg" . @boomanaiden154 @sjoerdmeijer @davemgreen what do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The 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() {
Expand Down
4 changes: 4 additions & 0 deletions llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ static Error randomizeMCOperand(const LLVMState &State,
AssignedValue = MCOperand::createReg(randomBit(AllowedRegs));
break;
}
/// Omit pc-relative operands to imm value based on the instruction
case MCOI::OperandType::OPERAND_PCREL:
return State.getExegesisTarget().randomizeTargetMCOperand(
Instr, Var, AssignedValue, ForbiddenRegs);
default:
break;
}
Expand Down