From ffc5ec8c8122b984871c59516426cdd8ad18e7ea Mon Sep 17 00:00:00 2001 From: Bjorn Pettersson Date: Mon, 15 Oct 2018 08:36:03 +0000 Subject: [PATCH] [TwoAddressInstructionPass] Replace subregister uses when processing tied operands Summary: TwoAddressInstruction pass typically rewrites %1:short = foo %0.sub_lo:long as %1:short = COPY %0.sub_lo:long %1:short = foo %1:short when having tied operands. If there are extra un-tied operands that uses the same reg and subreg, such as the second and third inputs to fie here: %1:short = fie %0.sub_lo:long, %0.sub_hi:long, %0.sub_lo:long then there was a bug which replaced the register %0 also for the un-tied operand, but without changing the subregister indices. So we used to get: %1:short = COPY %0.sub_lo:long %1:short = fie %1, %1.sub_hi:short, %1.sub_lo:short With this fix we instead get: %1:short = COPY %0.sub_lo:long %1:short = fie %1, %0.sub_hi:long, %1 Reviewers: arsenm, JesperAntonsson, kparzysz, MatzeB Reviewed By: MatzeB Subscribers: bjope, kparzysz, wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D36224 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344492 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 21 ++++++---- test/CodeGen/Hexagon/two-addr-tied-subregs.mir | 56 ++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 test/CodeGen/Hexagon/two-addr-tied-subregs.mir diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 99ccb0f9c9f..2e2fe72e539 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1608,23 +1608,28 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, } if (AllUsesCopied) { + bool ReplacedAllUntiedUses = true; if (!IsEarlyClobber) { // Replace other (un-tied) uses of regB with LastCopiedReg. for (MachineOperand &MO : MI->operands()) { - if (MO.isReg() && MO.getReg() == RegB && - MO.isUse()) { - if (MO.isKill()) { - MO.setIsKill(false); - RemovedKillFlag = true; + if (MO.isReg() && MO.getReg() == RegB && MO.isUse()) { + if (MO.getSubReg() == SubRegB) { + if (MO.isKill()) { + MO.setIsKill(false); + RemovedKillFlag = true; + } + MO.setReg(LastCopiedReg); + MO.setSubReg(0); + } else { + ReplacedAllUntiedUses = false; } - MO.setReg(LastCopiedReg); - MO.setSubReg(MO.getSubReg()); } } } // Update live variables for regB. - if (RemovedKillFlag && LV && LV->getVarInfo(RegB).removeKill(*MI)) { + if (RemovedKillFlag && ReplacedAllUntiedUses && + LV && LV->getVarInfo(RegB).removeKill(*MI)) { MachineBasicBlock::iterator PrevMI = MI; --PrevMI; LV->addVirtualRegisterKilled(RegB, *PrevMI); diff --git a/test/CodeGen/Hexagon/two-addr-tied-subregs.mir b/test/CodeGen/Hexagon/two-addr-tied-subregs.mir new file mode 100644 index 00000000000..87e117c461b --- /dev/null +++ b/test/CodeGen/Hexagon/two-addr-tied-subregs.mir @@ -0,0 +1,56 @@ +# RUN: llc -march hexagon -run-pass livevars -run-pass twoaddressinstruction -verify-machineinstrs -o - %s | FileCheck %s + + +############################################################################### + +--- +name: test1 +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $d0 + + %0:doubleregs = COPY killed $d0 + %1:intregs = S2_lsr_i_r_acc %0.isub_lo, %0.isub_lo, 16 + +... + +# Verify that both uses if %0.isub_lo are replaced here. +# (we used to get %1:intregs = S2_lsr_i_r_acc %1, %1.isub_lo, 16) +# +# CHECK-LABEL: name: test1 +# CHECK: bb.0.entry: +# CHECK: %0:doubleregs = COPY killed $d0 +# CHECK-NEXT: %1:intregs = COPY killed %0.isub_lo +# CHECK-NEXT: %1:intregs = S2_lsr_i_r_acc %1, %1, 16 + + +############################################################################### + +--- +name: test2 +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $d0 + + %0:doubleregs = COPY killed $d0 + %1:intregs = S2_lsr_i_r_acc %0.isub_lo, %0.isub_hi, 16 + +... + +# Verify that the use of %0.isub_hi isn't replaced here. +# (we used to get %1:intregs = S2_lsr_i_r_acc %1, %1.isub_hi, 16) +# +# We also used to get an incorrect "killed" for %0 in the second COPY. +# So we verify that we do not get machine verifier complaints here. +# An improvement could be to get a "killed" attribute on the last +# use of %0.isub_hi, but we do not need it for the IR to be valid. +# +# CHECK-LABEL: name: test2 +# CHECK: bb.0.entry: +# CHECK: %0:doubleregs = COPY killed $d0 +# CHECK-NEXT: %1:intregs = COPY %0.isub_lo +# CHECK-NEXT: %1:intregs = S2_lsr_i_r_acc %1, %0.isub_hi, 16 + +############################################################################### -- 2.11.4.GIT