From 2065a2f4e60bad5315f8289612eadba3842a4071 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 28 Apr 2017 21:56:33 +0000 Subject: [PATCH] Properly handle PHIs with subregisters in UnreachableBlockElim When a PHI operand has a subregister, create a COPY instead of simply replacing the PHI output with the input it. Differential Revision: https://reviews.llvm.org/D32650 llvm-svn: 301699 --- llvm/lib/CodeGen/UnreachableBlockElim.cpp | 29 ++++++++++++++++------ .../CodeGen/Hexagon/unreachable-mbb-phi-subreg.mir | 25 +++++++++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 llvm/test/CodeGen/Hexagon/unreachable-mbb-phi-subreg.mir diff --git a/llvm/lib/CodeGen/UnreachableBlockElim.cpp b/llvm/lib/CodeGen/UnreachableBlockElim.cpp index c2db56a..f085132 100644 --- a/llvm/lib/CodeGen/UnreachableBlockElim.cpp +++ b/llvm/lib/CodeGen/UnreachableBlockElim.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -195,18 +196,30 @@ bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) { } if (phi->getNumOperands() == 3) { - unsigned Input = phi->getOperand(1).getReg(); - unsigned Output = phi->getOperand(0).getReg(); - - phi++->eraseFromParent(); + const MachineOperand &Input = phi->getOperand(1); + const MachineOperand &Output = phi->getOperand(0); + unsigned InputReg = Input.getReg(); + unsigned OutputReg = Output.getReg(); + assert(Output.getSubReg() == 0 && "Cannot have output subregister"); ModifiedPHI = true; - if (Input != Output) { + if (InputReg != OutputReg) { MachineRegisterInfo &MRI = F.getRegInfo(); - MRI.constrainRegClass(Input, MRI.getRegClass(Output)); - MRI.replaceRegWith(Output, Input); + unsigned InputSub = Input.getSubReg(); + if (InputSub == 0) { + MRI.constrainRegClass(InputReg, MRI.getRegClass(OutputReg)); + MRI.replaceRegWith(OutputReg, InputReg); + } else { + // The input register to the PHI has a subregister: + // insert a COPY instead of simply replacing the output + // with the input. + const TargetInstrInfo *TII = F.getSubtarget().getInstrInfo(); + BuildMI(*BB, BB->getFirstNonPHI(), phi->getDebugLoc(), + TII->get(TargetOpcode::COPY), OutputReg) + .addReg(InputReg, getRegState(Input), InputSub); + } + phi++->eraseFromParent(); } - continue; } diff --git a/llvm/test/CodeGen/Hexagon/unreachable-mbb-phi-subreg.mir b/llvm/test/CodeGen/Hexagon/unreachable-mbb-phi-subreg.mir new file mode 100644 index 0000000..6d65492 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/unreachable-mbb-phi-subreg.mir @@ -0,0 +1,25 @@ +# RUN: llc -march=hexagon -run-pass unreachable-mbb-elimination %s -o - | FileCheck %s + +--- +name: fred +tracksRegLiveness: true +body: | + bb.0: + liveins: %d0 + successors: %bb.2 + + %0 : doubleregs = COPY %d0 + J2_jump %bb.2, implicit-def %pc + + bb.1: + successors: %bb.2 + A2_nop + + bb.2: + ; Make sure that the subregister from the PHI operand is preserved. + ; CHECK: %[[REG:[0-9]+]] = COPY %0.isub_lo + ; CHECK: %r0 = COPY %[[REG]] + %1 : intregs = PHI %0.isub_lo, %bb.0, %0.isub_hi, %bb.1 + %r0 = COPY %1 +... + -- 2.7.4