From: Krzysztof Parzyszek Date: Fri, 16 Jun 2017 12:24:03 +0000 (+0000) Subject: [Hexagon] Don't kill live registers when creating mux out of tfr X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c86dcc6411c6905c880c129641036db915adbd65;p=llvm [Hexagon] Don't kill live registers when creating mux out of tfr The second part of r305300: when placing the mux at the later location, make sure that it won't use any register that was killed between the two original instructions. Remove any such kills and transfer them to the mux. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305553 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/HexagonGenMux.cpp b/lib/Target/Hexagon/HexagonGenMux.cpp index a2502ce5ec3..11ac5454f60 100644 --- a/lib/Target/Hexagon/HexagonGenMux.cpp +++ b/lib/Target/Hexagon/HexagonGenMux.cpp @@ -317,7 +317,37 @@ bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) { // Prefer "down", since this will move the MUX farther away from the // predicate definition. MachineBasicBlock::iterator At = CanDown ? Def2 : Def1; - if (!CanDown) { + if (CanDown) { + // If the MUX is placed "down", we need to make sure that there aren't + // any kills of the source registers between the two defs. + if (Used1 || Used2) { + auto ResetKill = [this] (unsigned Reg, MachineInstr &MI) -> bool { + if (MachineOperand *Op = MI.findRegisterUseOperand(Reg, true, HRI)) { + Op->setIsKill(false); + return true; + } + return false; + }; + bool KilledSR1 = false, KilledSR2 = false; + for (MachineInstr &MJ : make_range(std::next(It1), It2)) { + if (SR1) + KilledSR1 |= ResetKill(SR1, MJ); + if (SR2) + KilledSR2 |= ResetKill(SR1, MJ); + } + // If any of the source registers were killed in this range, transfer + // the kills to the source operands: they will me "moved" to the + // resulting MUX and their parent instructions will be deleted. + if (KilledSR1) { + assert(Src1->isReg()); + Src1->setIsKill(true); + } + if (KilledSR2) { + assert(Src2->isReg()); + Src2->setIsKill(true); + } + } + } else { // If the MUX is placed "up", it shouldn't kill any source registers // that are still used afterwards. We can reset the kill flags directly // on the operands, because the source instructions will be erased. diff --git a/test/CodeGen/Hexagon/mux-kill2.mir b/test/CodeGen/Hexagon/mux-kill2.mir new file mode 100644 index 00000000000..5f34097af7c --- /dev/null +++ b/test/CodeGen/Hexagon/mux-kill2.mir @@ -0,0 +1,17 @@ +# RUN: llc -march=hexagon -run-pass hexagon-gen-mux -o - -verify-machineinstrs %s | FileCheck %s +# CHECK: %r1 = C2_muxri %p0, 123, %r0 +# CHECK: %r2 = C2_muxir %p0, killed %r0, 321 +--- +name: fred +tracksRegLiveness: true + +body: | + bb.0: + liveins: %r0, %p0 + + %r2 = A2_tfrt %p0, %r0 + %r1 = C2_cmoveit %p0, 123 + %r1 = A2_tfrf %p0, killed %r0, implicit killed %r1 + %r2 = C2_cmoveif killed %p0, 321, implicit killed %r2 +... +