diff --git a/llvm/test/tools/llvm-exegesis/AArch64/unknown-operand.s b/llvm/test/tools/llvm-exegesis/AArch64/unknown-operand.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-exegesis/AArch64/unknown-operand.s @@ -0,0 +1,39 @@ +# RUN: llvm-exegesis --opcode-name=ADDSWrx --mcpu=cortex-a78 --mtriple=aarch64-linux-gnu \ +# RUN: --mode=latency --benchmark-phase=prepare-snippet 2>&1 | FileCheck %s --check-prefix=REG + +# RUN: llvm-exegesis --opcode-name=LDRXroX --mcpu=cortex-a78 --mtriple=aarch64-linux-gnu \ +# RUN: --mode=latency --benchmark-phase=prepare-snippet 2>&1 | FileCheck %s --check-prefix=IMM1 + +# RUN: llvm-exegesis --opcode-name=MOVIv2s_msl --mcpu=cortex-a78 --mtriple=aarch64-linux-gnu \ +# RUN: --mode=inverse_throughput --benchmark-phase=prepare-snippet 2>&1 | FileCheck %s --check-prefix=IMM2 + +# RUN: llvm-exegesis --opcode-name=MOVIv4s_msl --mcpu=cortex-a78 --mtriple=aarch64-linux-gnu \ +# RUN: --mode=inverse_throughput --benchmark-phase=prepare-snippet 2>&1 | FileCheck %s --check-prefix=IMM3 + +# RUN: llvm-exegesis --opcode-name=MVNIv2s_msl --mcpu=cortex-a78 --mtriple=aarch64-linux-gnu \ +# RUN: --mode=inverse_throughput --benchmark-phase=prepare-snippet 2>&1 | FileCheck %s --check-prefix=IMM4 + +# RUN: llvm-exegesis --opcode-name=MVNIv4s_msl --mcpu=cortex-a78 --mtriple=aarch64-linux-gnu \ +# RUN: --mode=inverse_throughput --benchmark-phase=prepare-snippet 2>&1 | FileCheck %s --check-prefix=IMM5 + +# unknown operand is register +# REG: instructions: +# REG-NEXT: ADDSWrx + +# unknown operand is set to zero value immediate +# IMM1: instructions: +# IMM1-NEXT: LDRXroX + +# unknown operand is set to non-zero value immediate +# IMM2: instructions: +# IMM2-NEXT: MOVIv2s_msl + +# IMM3: instructions: +# IMM3-NEXT: MOVIv4s_msl + +# IMM4: instructions: +# IMM4-NEXT: MVNIv2s_msl + +# IMM5: instructions: +# IMM5-NEXT: MVNIv4s_msl + diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp --- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp @@ -59,6 +59,25 @@ // Function return is a pseudo-instruction that needs to be expanded PM.add(createAArch64ExpandPseudoPass()); } + + int getUnknownOperandType(const Instruction &I, + const Operand &Op) const override { + return Op.isReg() ? MCOI::OPERAND_REGISTER : MCOI::OPERAND_IMMEDIATE; + } + + // Gets immediate based on instruction opcode + int64_t getImmediateForOperand(const Instruction &I, + const Operand &Op) const override { + switch (I.Description.getOpcode()) { + default: + return 0; + case AArch64::MOVIv2s_msl: + case AArch64::MOVIv4s_msl: + case AArch64::MVNIv2s_msl: + case AArch64::MVNIv4s_msl: + return 8; + } + } }; } // namespace diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp --- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp +++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp @@ -238,14 +238,21 @@ MCOperand &AssignedValue, const BitVector &ForbiddenRegs) { const Operand &Op = Instr.getPrimaryOperand(Var); + auto &ET = State.getExegesisTarget(); if (Op.getExplicitOperandInfo().OperandType >= MCOI::OperandType::OPERAND_FIRST_TARGET) - return State.getExegesisTarget().randomizeTargetMCOperand( - Instr, Var, AssignedValue, ForbiddenRegs); - switch (Op.getExplicitOperandInfo().OperandType) { + return ET.randomizeTargetMCOperand(Instr, Var, AssignedValue, + ForbiddenRegs); + // FIXME: explore immediate values too. + int64_t OpType = Op.getExplicitOperandInfo().OperandType, ImmVal = 1; + if (OpType == MCOI::OperandType::OPERAND_UNKNOWN) + if ((OpType = ET.getUnknownOperandType(Instr, Op)) == + MCOI::OperandType::OPERAND_IMMEDIATE) + ImmVal = ET.getImmediateForOperand(Instr, Op); + + switch (OpType) { case MCOI::OperandType::OPERAND_IMMEDIATE: - // FIXME: explore immediate values too. - AssignedValue = MCOperand::createImm(1); + AssignedValue = MCOperand::createImm(ImmVal); break; case MCOI::OperandType::OPERAND_REGISTER: { assert(Op.isReg()); diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -38,6 +38,8 @@ extern cl::OptionCategory BenchmarkOptions; extern cl::OptionCategory AnalysisOptions; +struct Operand; + struct PfmCountersInfo { // An optional name of a performance counter that can be used to measure // cycles. @@ -100,6 +102,18 @@ // Returns a counter usable as a loop counter. virtual unsigned getLoopCounterRegister(const Triple &) const { return 0; } + // Gets the real operand type for OPERAND_UNKNOWN + virtual int getUnknownOperandType(const Instruction &I, + const Operand &Op) const { + return MCOI::OperandType::OPERAND_UNKNOWN; + } + + // Gets immediate value + virtual int64_t getImmediateForOperand(const Instruction &I, + const Operand &Op) const { + return 0; + } + // Adds the code to decrement the loop counter and virtual void decrementLoopCounterAndJump(MachineBasicBlock &MBB, MachineBasicBlock &TargetMBB, @@ -192,7 +206,6 @@ virtual std::unique_ptr withSavedState() const { return std::make_unique(); } - private: virtual bool matchesArch(Triple::ArchType Arch) const = 0;