Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 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
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
19 changes: 11 additions & 8 deletions llvm/lib/Target/AArch64/AArch64InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,17 @@ def timm32_0_255 : Operand<i32>, TImmLeaf<i32, [{

} // let OperandType = "OPERAND_IMMEDIATE"

let OperandType = "OPERAND_MSL_SHIFT" in {
// A vector move shifter operand:
// {0} - imm1: #8 or #16
def move_vec_shift : Operand<i32> {
let PrintMethod = "printShifter";
let OperandNamespace = "AArch64";
let EncoderMethod = "getMoveVecShifterOpValue";
let ParserMatchClass = MoveVecShifterOperand;
}
} // let OperandType = "OPERAND_MSL_SHIFT"

// An arithmetic shifter operand:
// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
// {5-0} - imm6
Expand Down Expand Up @@ -1316,14 +1327,6 @@ def logical_vec_hw_shift : Operand<i32> {
let ParserMatchClass = LogicalVecHalfWordShifterOperand;
}

// A vector move shifter operand:
// {0} - imm1: #8 or #16
def move_vec_shift : Operand<i32> {
let PrintMethod = "printShifter";
let EncoderMethod = "getMoveVecShifterOpValue";
let ParserMatchClass = MoveVecShifterOperand;
}

let DiagnosticType = "AddSubSecondSource" in {
def AddSubImmOperand : AsmOperandClass {
let Name = "AddSubImm";
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_MSL_SHIFT
};
} // 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
105 changes: 105 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,105 @@
# REQUIRES: aarch64-registered-target



// Test for omitting OperandType::OPERAND_UNKNOWN

// ADDXri: ADD Xd, Xn, #imm{, shift}
# RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=latency --benchmark-phase=prepare-and-assemble-snippet --opcode-name=ADDXri 2>&1 | FileCheck %s --check-prefix=ADDXri_latency
# ADDXri_latency-NOT: Not all operands were initialized by the snippet generator for ADDXri opcode
# ADDXri_latency: ---
# ADDXri_latency-NEXT: mode: latency
# ADDXri_latency-NEXT: key:
# ADDXri_latency-NEXT: instructions:
# ADDXri_latency-NEXT: ADDXri [[REG1:X[0-9]+|LR]] [[REG2:X[0-9]+|LR]] i_0x0 i_0x0
# ADDXri_latency: ...

# RUN: llvm-exegesis --mtriple=aarch64 --mcpu=neoverse-v2 --mode=inverse_throughput --benchmark-phase=prepare-and-assemble-snippet --opcode-name=ADDXri 2>&1 | FileCheck %s --check-prefix=ADDXri_throughput
# ADDXri_throughput-NOT: Not all operands were initialized by the snippet generator for ADDXri opcode
# ADDXri_throughput: ---
# ADDXri_throughput-NEXT: mode: inverse_throughput
# ADDXri_throughput-NEXT: key:
# ADDXri_throughput-NEXT: instructions:
# ADDXri_throughput-NEXT: ADDXri [[REG1:X[0-9]+|LR]] [[REG2:X[0-9]+|LR]] i_0x0 i_0x0
# ADDXri_throughput: ...



// Test for omitting OperandType::OPERAND_MSL_SHIFT_4S

// 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: ...



// Test for omitting OperandType::OPERAND_MSL_SHIFT_2S

// 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_0x0
# LDRDl_throughput: ...



// Test for omitting OperandType::OPERAND_FIRST_TARGET

// 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: Not all operands were initialized by the snippet generator for UMOVvi16_idx0 opcode
# UMOVvi16_idx0_latency: ---
# UMOVvi16_idx0_latency-NEXT: mode: latency
# UMOVvi16_idx0_latency-NEXT: key:
# UMOVvi16_idx0_latency-NEXT: instructions:
# UMOVvi16_idx0_latency-NEXT: UMOVvi16_idx0 [[REG1:W[0-9]+|LR]] [[REG2:Q[0-9]+|LR]] i_0x0
# UMOVvi16_idx0_latency: ...

# UMOVvi16_idx0_throughput-NOT: 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: ...
50 changes: 50 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,52 @@ 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;
// FIXME: Implement opcode-specific immediate value handling for system
// instructions:
// - 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)
// Currently defaulting to immediate value 0, which may cause invalid
// encodings or unreliable benchmark results for these system-level
// instructions.
switch (OperandType) {
case MCOI::OperandType::OPERAND_UNKNOWN: {
AssignedValue = MCOperand::createImm(0);
return Error::success();
}
// MSL (Masking Shift Left) imm operand for 32-bit splatted SIMD constants
// Correspond to AArch64InstructionSelector::tryAdvSIMDModImm321s()
case llvm::AArch64::OPERAND_MSL_SHIFT: {
// 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.
AssignedValue = MCOperand::createImm(264);
return Error::success();
}
case MCOI::OperandType::OPERAND_PCREL:
case MCOI::OperandType::OPERAND_FIRST_TARGET:
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() {
Expand Down
6 changes: 6 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,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)

case MCOI::OperandType::OPERAND_PCREL:
return State.getExegesisTarget().randomizeTargetMCOperand(
Instr, Var, AssignedValue, ForbiddenRegs);
default:
break;
}
Expand Down