Index: include/llvm/CodeGen/LivePhysRegs.h =================================================================== --- include/llvm/CodeGen/LivePhysRegs.h +++ include/llvm/CodeGen/LivePhysRegs.h @@ -152,6 +152,10 @@ /// \brief Adds live-in registers from basic block \p MBB, taking associated /// lane masks into consideration. void addBlockLiveIns(const MachineBasicBlock &MBB); + + /// Adds pristine registers. Pristine registers are callee saved registers + /// that are unused in the function. + void addPristines(const MachineFunction &MF); }; inline raw_ostream &operator<<(raw_ostream &OS, const LivePhysRegs& LR) { Index: lib/CodeGen/LivePhysRegs.cpp =================================================================== --- lib/CodeGen/LivePhysRegs.cpp +++ lib/CodeGen/LivePhysRegs.cpp @@ -166,17 +166,21 @@ LiveRegs.addReg(*CSR); } -/// Adds pristine registers to the given \p LiveRegs. Pristine registers are -/// callee saved registers that are unused in the function. -static void addPristines(LivePhysRegs &LiveRegs, const MachineFunction &MF) { +void LivePhysRegs::addPristines(const MachineFunction &MF) { const MachineFrameInfo &MFI = MF.getFrameInfo(); if (!MFI.isCalleeSavedInfoValid()) return; + /// If a callee-saved register that is not pristine is already present + /// in the set, we should make sure that it stays in it. Precompute the + /// set of pristine registers in a separate object. /// Add all callee saved regs, then remove the ones that are saved+restored. - addCalleeSavedRegs(LiveRegs, MF); + LivePhysRegs Pristine(*TRI); + addCalleeSavedRegs(Pristine, MF); /// Remove the ones that are not saved/restored; they are pristine. for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) - LiveRegs.removeReg(Info.getReg()); + Pristine.removeReg(Info.getReg()); + for (MCPhysReg R : Pristine) + addReg(R); } void LivePhysRegs::addLiveOutsNoPristines(const MachineBasicBlock &MBB) { @@ -201,7 +205,7 @@ void LivePhysRegs::addLiveOuts(const MachineBasicBlock &MBB) { const MachineFunction &MF = *MBB.getParent(); if (!MBB.succ_empty()) { - addPristines(*this, MF); + addPristines(MF); addLiveOutsNoPristines(MBB); } else if (MBB.isReturnBlock()) { // For the return block: Add all callee saved registers. @@ -213,7 +217,7 @@ void LivePhysRegs::addLiveIns(const MachineBasicBlock &MBB) { const MachineFunction &MF = *MBB.getParent(); - addPristines(*this, MF); + addPristines(MF); addBlockLiveIns(MBB); } Index: test/CodeGen/Hexagon/livephysregs-add-pristines.mir =================================================================== --- /dev/null +++ test/CodeGen/Hexagon/livephysregs-add-pristines.mir @@ -0,0 +1,37 @@ +# RUN: llc -march=hexagon -run-pass if-converter -o - %s -verify-machineinstrs | FileCheck %s + +# The register r23 is live on the path bb.0->bb.2->bb.3. Make sure we add +# an implicit use of r23 to the predicated redefinition: +# CHECK: %r23 = A2_tfrt %p0, killed %r1, implicit %r23 + +# LivePhysRegs::addPristines could accidentally remove a callee-saved +# register, if it determined that it wasn't pristine. Doing that caused +# r23 in this testcase to be dropped from the Redefs set, and subsequently +# the necessary implicit use was not added for it. + +--- +name: foo +tracksRegLiveness: true +fixedStack: + - { id: 0, offset: 0, size: 4, alignment: 4, callee-saved-register: '%r23' } +body: | + bb.0: + successors: %bb.1, %bb.2 + liveins: %r0, %r1, %r23 + %p0 = C2_cmpgti killed %r0, 0 + J2_jumpf killed %p0, %bb.2, implicit-def %pc + + bb.1: + successors: %bb.3 + liveins: %r1 + %r23 = A2_tfr killed %r1 + J2_jump %bb.3, implicit-def %pc + + bb.2: + successors: %bb.3 + liveins: %r1, %r23 + %r0 = A2_tfr %r1 + + bb.3: + liveins: %r23 +...