diff options
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp | 50 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/sdr-global.mir | 24 |
3 files changed, 52 insertions, 24 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp b/llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp index 45b6f7192e0..c0d95ed453f 100644 --- a/llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp @@ -65,9 +65,7 @@ namespace { public: static char ID; - HexagonSplitDoubleRegs() : MachineFunctionPass(ID) { - initializeHexagonSplitDoubleRegsPass(*PassRegistry::getPassRegistry()); - } + HexagonSplitDoubleRegs() : MachineFunctionPass(ID) {} StringRef getPassName() const override { return "Hexagon Split Double Registers"; @@ -308,17 +306,16 @@ void HexagonSplitDoubleRegs::partitionRegisters(UUSetMap &P2Rs) { 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; - if (Lo == 0 || Lo == 0xFFFFFFFF) - P += 10; - if (Hi == 0 || Hi == 0xFFFFFFFF) + if (Imm == 0 || Imm == 0xFFFFFFFF) P += 10; return P; } int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const { unsigned ImmX = 0; +dbgs() << *MI; unsigned Opc = MI->getOpcode(); switch (Opc) { case TargetOpcode::PHI: @@ -343,21 +340,28 @@ int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const { uint64_t D = MI->getOperand(1).getImm(); unsigned Lo = D & 0xFFFFFFFFULL; unsigned Hi = D >> 32; - return profitImm(Lo, Hi); + return profitImm(Lo) + profitImm(Hi); } case Hexagon::A2_combineii: - case Hexagon::A4_combineii: - return profitImm(MI->getOperand(1).getImm(), - MI->getOperand(2).getImm()); + case Hexagon::A4_combineii: { + const MachineOperand &Op1 = MI->getOperand(1); + 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: ImmX++; // Fall through into A4_combineir. LLVM_FALLTHROUGH; case Hexagon::A4_combineir: { ImmX++; - int64_t V = MI->getOperand(ImmX).getImm(); - if (V == 0 || V == -1) - return 10; + const MachineOperand &OpX = MI->getOperand(ImmX); + if (OpX.isImm()) { + int64_t V = OpX.getImm(); + if (V == 0 || V == -1) + return 10; + } // Fall through into A2_combinew. LLVM_FALLTHROUGH; } @@ -735,23 +739,21 @@ void HexagonSplitDoubleRegs::splitCombine(MachineInstr *MI, assert(F != PairMap.end()); const UUPair &P = F->second; - if (Op1.isImm()) { + if (!Op1.isReg()) { BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second) - .addImm(Op1.getImm()); - } else if (Op1.isReg()) { + .add(Op1); + } else { BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.second) .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) - .addImm(Op2.getImm()); - } else if (Op2.isReg()) { + .add(Op2); + } else { BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first) .addReg(Op2.getReg(), getRegState(Op2), Op2.getSubReg()); - } else - llvm_unreachable("Unexpected operand"); + } } void HexagonSplitDoubleRegs::splitExt(MachineInstr *MI, diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp index cb626ebd5a0..2c75e9139ad 100644 --- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -134,6 +134,7 @@ namespace llvm { void initializeHexagonOptAddrModePass(PassRegistry&); void initializeHexagonPacketizerPass(PassRegistry&); void initializeHexagonRDFOptPass(PassRegistry&); + void initializeHexagonSplitDoubleRegsPass(PassRegistry&); void initializeHexagonVExtractPass(PassRegistry&); Pass *createHexagonLoopIdiomPass(); Pass *createHexagonVectorLoopCarriedReusePass(); @@ -199,6 +200,7 @@ extern "C" void LLVMInitializeHexagonTarget() { initializeHexagonOptAddrModePass(PR); initializeHexagonPacketizerPass(PR); initializeHexagonRDFOptPass(PR); + initializeHexagonSplitDoubleRegsPass(PR); initializeHexagonVExtractPass(PR); } diff --git a/llvm/test/CodeGen/Hexagon/sdr-global.mir b/llvm/test/CodeGen/Hexagon/sdr-global.mir new file mode 100644 index 00000000000..dc55a9b7183 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/sdr-global.mir @@ -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 +... |