Index: lib/CodeGen/UnreachableBlockElim.cpp =================================================================== --- lib/CodeGen/UnreachableBlockElim.cpp +++ 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,32 @@ } if (phi->getNumOperands() == 3) { - unsigned Input = phi->getOperand(1).getReg(); - unsigned Output = phi->getOperand(0).getReg(); + const MachineOperand &Input = phi->getOperand(1); + const MachineOperand &Output = phi->getOperand(0); + unsigned InputReg = Input.getReg(); + unsigned OutputReg = Output.getReg(); - phi++->eraseFromParent(); 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: + // create a new register and insert a COPY instead. + const TargetRegisterClass *OutRC = MRI.getRegClass(OutputReg); + unsigned NewOutput = MRI.createVirtualRegister(OutRC); + const TargetInstrInfo *TII = F.getSubtarget().getInstrInfo(); + BuildMI(*BB, BB->getFirstNonPHI(), phi->getDebugLoc(), + TII->get(TargetOpcode::COPY), NewOutput) + .addReg(InputReg, getRegState(Input), InputSub); + MRI.replaceRegWith(OutputReg, NewOutput); + } + phi++->eraseFromParent(); } - continue; } Index: test/CodeGen/Hexagon/unreachable-mbb-phi-subreg.mir =================================================================== --- /dev/null +++ test/CodeGen/Hexagon/unreachable-mbb-phi-subreg.mir @@ -0,0 +1,35 @@ +# RUN: llc -march=hexagon -run-pass unreachable-mbb-elimination %s -o - | FileCheck %s + +--- | + define void @fred() { + ret void + } +... + +--- +name: fred +tracksRegLiveness: true + +registers: + - { id: 0, class: doubleregs } + - { id: 1, class: intregs } +body: | + bb.0: + liveins: %d0 + successors: %bb.2 + + %0 = 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 = PHI %0.isub_lo, %bb.0, %0.isub_hi, %bb.1 + %r0 = COPY %1 +... +