[Hexagon] Handle non-immediate constants in HexagonSplitDouble

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@331527 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Krzysztof Parzyszek 2018-05-04 15:04:48 +00:00
parent aff0c11ab4
commit 66648415b9
3 changed files with 52 additions and 24 deletions

View File

@ -65,9 +65,7 @@ namespace {
public: public:
static char ID; static char ID;
HexagonSplitDoubleRegs() : MachineFunctionPass(ID) { HexagonSplitDoubleRegs() : MachineFunctionPass(ID) {}
initializeHexagonSplitDoubleRegsPass(*PassRegistry::getPassRegistry());
}
StringRef getPassName() const override { StringRef getPassName() const override {
return "Hexagon Split Double Registers"; return "Hexagon Split Double Registers";
@ -308,17 +306,16 @@ void HexagonSplitDoubleRegs::partitionRegisters(UUSetMap &P2Rs) {
P2Rs[I.second].insert(I.first); P2Rs[I.second].insert(I.first);
} }
static inline int32_t profitImm(unsigned Lo, unsigned Hi) { static inline int32_t profitImm(unsigned Imm) {
int32_t P = 0; int32_t P = 0;
if (Lo == 0 || Lo == 0xFFFFFFFF) if (Imm == 0 || Imm == 0xFFFFFFFF)
P += 10;
if (Hi == 0 || Hi == 0xFFFFFFFF)
P += 10; P += 10;
return P; return P;
} }
int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const { int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const {
unsigned ImmX = 0; unsigned ImmX = 0;
dbgs() << *MI;
unsigned Opc = MI->getOpcode(); unsigned Opc = MI->getOpcode();
switch (Opc) { switch (Opc) {
case TargetOpcode::PHI: case TargetOpcode::PHI:
@ -343,21 +340,28 @@ int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const {
uint64_t D = MI->getOperand(1).getImm(); uint64_t D = MI->getOperand(1).getImm();
unsigned Lo = D & 0xFFFFFFFFULL; unsigned Lo = D & 0xFFFFFFFFULL;
unsigned Hi = D >> 32; unsigned Hi = D >> 32;
return profitImm(Lo, Hi); return profitImm(Lo) + profitImm(Hi);
} }
case Hexagon::A2_combineii: case Hexagon::A2_combineii:
case Hexagon::A4_combineii: case Hexagon::A4_combineii: {
return profitImm(MI->getOperand(1).getImm(), const MachineOperand &Op1 = MI->getOperand(1);
MI->getOperand(2).getImm()); const MachineOperand &Op2 = MI->getOperand(2);
int32_t Prof1 = Op1.isImm() ? profitImm(Op1.getImm()) : 0;
int32_t Prof2 = Op2.isImm() ? profitImm(Op2.getImm()) : 0;
return Prof1 + Prof2;
}
case Hexagon::A4_combineri: case Hexagon::A4_combineri:
ImmX++; ImmX++;
// Fall through into A4_combineir. // Fall through into A4_combineir.
LLVM_FALLTHROUGH; LLVM_FALLTHROUGH;
case Hexagon::A4_combineir: { case Hexagon::A4_combineir: {
ImmX++; ImmX++;
int64_t V = MI->getOperand(ImmX).getImm(); const MachineOperand &OpX = MI->getOperand(ImmX);
if (V == 0 || V == -1) if (OpX.isImm()) {
return 10; int64_t V = OpX.getImm();
if (V == 0 || V == -1)
return 10;
}
// Fall through into A2_combinew. // Fall through into A2_combinew.
LLVM_FALLTHROUGH; LLVM_FALLTHROUGH;
} }
@ -735,23 +739,21 @@ void HexagonSplitDoubleRegs::splitCombine(MachineInstr *MI,
assert(F != PairMap.end()); assert(F != PairMap.end());
const UUPair &P = F->second; const UUPair &P = F->second;
if (Op1.isImm()) { if (!Op1.isReg()) {
BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second) BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second)
.addImm(Op1.getImm()); .add(Op1);
} else if (Op1.isReg()) { } else {
BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.second) BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.second)
.addReg(Op1.getReg(), getRegState(Op1), Op1.getSubReg()); .addReg(Op1.getReg(), getRegState(Op1), Op1.getSubReg());
} else }
llvm_unreachable("Unexpected operand");
if (Op2.isImm()) { if (!Op2.isReg()) {
BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.first) BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.first)
.addImm(Op2.getImm()); .add(Op2);
} else if (Op2.isReg()) { } else {
BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first) BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first)
.addReg(Op2.getReg(), getRegState(Op2), Op2.getSubReg()); .addReg(Op2.getReg(), getRegState(Op2), Op2.getSubReg());
} else }
llvm_unreachable("Unexpected operand");
} }
void HexagonSplitDoubleRegs::splitExt(MachineInstr *MI, void HexagonSplitDoubleRegs::splitExt(MachineInstr *MI,

View File

@ -134,6 +134,7 @@ namespace llvm {
void initializeHexagonOptAddrModePass(PassRegistry&); void initializeHexagonOptAddrModePass(PassRegistry&);
void initializeHexagonPacketizerPass(PassRegistry&); void initializeHexagonPacketizerPass(PassRegistry&);
void initializeHexagonRDFOptPass(PassRegistry&); void initializeHexagonRDFOptPass(PassRegistry&);
void initializeHexagonSplitDoubleRegsPass(PassRegistry&);
void initializeHexagonVExtractPass(PassRegistry&); void initializeHexagonVExtractPass(PassRegistry&);
Pass *createHexagonLoopIdiomPass(); Pass *createHexagonLoopIdiomPass();
Pass *createHexagonVectorLoopCarriedReusePass(); Pass *createHexagonVectorLoopCarriedReusePass();
@ -199,6 +200,7 @@ extern "C" void LLVMInitializeHexagonTarget() {
initializeHexagonOptAddrModePass(PR); initializeHexagonOptAddrModePass(PR);
initializeHexagonPacketizerPass(PR); initializeHexagonPacketizerPass(PR);
initializeHexagonRDFOptPass(PR); initializeHexagonRDFOptPass(PR);
initializeHexagonSplitDoubleRegsPass(PR);
initializeHexagonVExtractPass(PR); initializeHexagonVExtractPass(PR);
} }

View File

@ -0,0 +1,24 @@
# RUN: llc -march=hexagon -run-pass hexagon-split-double %s -o - | FileCheck %s
# This used to crash because the constant operand was not an immediate.
# Make sure we can handle such a case.
# CHECK: = A2_tfrsi 0
# CHECK: = A2_tfrsi @g0
--- |
define i32 @fred() {
ret i32 0
}
@g0 = global i32 zeroinitializer
...
name: fred
tracksRegLiveness: true
body: |
bb.0:
%0:doubleregs = A4_combineir 0, @g0
$r0 = COPY %0.isub_lo
PS_jmpret $r31, implicit-def $pc, implicit $r0
...