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:
parent
0708e5ac82
commit
6b77481d59
16
test/tools/llvm-exegesis/X86/latency-LEA64_32r.s
Normal file
16
test/tools/llvm-exegesis/X86/latency-LEA64_32r.s
Normal 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)'
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user