1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[llvm-exegesis] Fix support for LEA64_32r.

Summary:
Add unit test to show the issue: We must select an *aliasing* output
register, not the exact register.

Reviewers: gchatelet

Subscribers: tschuett, mstojanovic, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D73095
This commit is contained in:
Clement Courbet 2020-01-21 11:58:51 +01:00
parent 0708e5ac82
commit 6b77481d59
2 changed files with 41 additions and 21 deletions

View File

@ -0,0 +1,16 @@
# RUN: llvm-exegesis -mode=latency -opcode-name=LEA64_32r -repetition-mode=duplicate -max-configs-per-opcode=2 | FileCheck %s
# RUN: llvm-exegesis -mode=latency -opcode-name=LEA64_32r -repetition-mode=loop -max-configs-per-opcode=2 | FileCheck %s
CHECK: ---
CHECK-NEXT: mode: latency
CHECK-NEXT: key:
CHECK-NEXT: instructions:
CHECK-NEXT: LEA64_32r
CHECK-NEXT: config: '0(%[[REG1:[A-Z0-9]+]], %[[REG1]], 1)'
CHECK: ---
CHECK-NEXT: mode: latency
CHECK-NEXT: key:
CHECK-NEXT: instructions:
CHECK-NEXT: LEA64_32r
CHECK-NEXT: config: '42(%[[REG2:[A-Z0-9]+]], %[[REG2]], 1)'

View File

@ -188,7 +188,8 @@ static void setMemOp(InstructionTemplate &IT, int OpIdx,
static Expected<std::vector<CodeTemplate>> generateLEATemplatesCommon(
const Instruction &Instr, const BitVector &ForbiddenRegisters,
const LLVMState &State, const SnippetGenerator::Options &Opts,
std::function<unsigned(unsigned, unsigned)> GetDestReg) {
std::function<void(unsigned, unsigned, BitVector &CandidateDestRegs)>
RestrictDestRegs) {
assert(Instr.Operands.size() == 6 && "invalid LEA");
assert(X86II::getMemoryOperandNo(Instr.Description.TSFlags) == 1 &&
"invalid LEA");
@ -222,8 +223,15 @@ static Expected<std::vector<CodeTemplate>> generateLEATemplatesCommon(
// SegmentReg must be 0 for LEA.
setMemOp(IT, 5, MCOperand::createReg(0));
// Output reg is selected by the caller.
setMemOp(IT, 0, MCOperand::createReg(GetDestReg(BaseReg, IndexReg)));
// Output reg candidates are selected by the caller.
auto PossibleDestRegsNow = PossibleDestRegs;
RestrictDestRegs(BaseReg, IndexReg, PossibleDestRegsNow);
assert(PossibleDestRegsNow.set_bits().begin() !=
PossibleDestRegsNow.set_bits().end() &&
"no remaining registers");
setMemOp(
IT, 0,
MCOperand::createReg(*PossibleDestRegsNow.set_bits().begin()));
CodeTemplate CT;
CT.Instructions.push_back(std::move(IT));
@ -261,12 +269,15 @@ X86SerialSnippetGenerator::generateCodeTemplates(
// LEA gets special attention.
const auto Opcode = Instr.Description.getOpcode();
if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r) {
return generateLEATemplatesCommon(Instr, ForbiddenRegisters, State, Opts,
[](unsigned BaseReg, unsigned IndexReg) {
// We just select the same base and
// output register.
return BaseReg;
});
return generateLEATemplatesCommon(
Instr, ForbiddenRegisters, State, Opts,
[this](unsigned BaseReg, unsigned IndexReg,
BitVector &CandidateDestRegs) {
// We just select a destination register that aliases the base
// register.
CandidateDestRegs &=
State.getRATC().getRegister(BaseReg).aliasedBits();
});
}
switch (getX86FPFlags(Instr)) {
@ -312,22 +323,15 @@ X86ParallelSnippetGenerator::generateCodeTemplates(
// LEA gets special attention.
const auto Opcode = Instr.Description.getOpcode();
if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r) {
// Any destination register that is not used for adddressing is fine.
auto PossibleDestRegs =
Instr.Operands[0].getRegisterAliasing().sourceBits();
remove(PossibleDestRegs, ForbiddenRegisters);
return generateLEATemplatesCommon(
Instr, ForbiddenRegisters, State, Opts,
[this, &PossibleDestRegs](unsigned BaseReg, unsigned IndexReg) {
auto PossibleDestRegsNow = PossibleDestRegs;
remove(PossibleDestRegsNow,
[this](unsigned BaseReg, unsigned IndexReg,
BitVector &CandidateDestRegs) {
// Any destination register that is not used for addressing is fine.
remove(CandidateDestRegs,
State.getRATC().getRegister(BaseReg).aliasedBits());
remove(PossibleDestRegsNow,
remove(CandidateDestRegs,
State.getRATC().getRegister(IndexReg).aliasedBits());
assert(PossibleDestRegsNow.set_bits().begin() !=
PossibleDestRegsNow.set_bits().end() &&
"no remaining registers");
return *PossibleDestRegsNow.set_bits().begin();
});
}