Index: lib/CodeGen/BranchFolding.cpp =================================================================== --- lib/CodeGen/BranchFolding.cpp +++ lib/CodeGen/BranchFolding.cpp @@ -31,6 +31,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" @@ -372,6 +373,36 @@ if (UpdateLiveIns) { NewDest->clearLiveIns(); computeLiveIns(LiveRegs, *MRI, *NewDest); + + // Need to traverse all predecessors, because some of them may not be + // among the blocks in SameTails. This could happen, for example, if one + // of the blocks in SameTails is used as the common tail. + for (MachineBasicBlock *Pred : NewDest->predecessors()) { + LivePhysRegs LiveOuts(*TRI); + LiveOuts.addLiveIns(*Pred); + + // Actually recalculate the live-outs in Pred. This is necessary because + // removing an flag in mergeOperations can make the liveness info + // incorrect. The purpose of this code is to identify such cases and + // patch it with IMPLICIT_DEFs. + SmallVector, 2> Clobbers; + for (const MachineInstr &MI : *Pred) { + LiveOuts.stepForward(MI, Clobbers); + for (auto C : Clobbers) + if (C.second->isReg() && C.second->isDef() && C.second->isDead()) + LiveOuts.removeReg(C.first); + Clobbers.clear(); + } + + for (const MachineBasicBlock::RegisterMaskPair &LI : NewDest->liveins()) { + if (!LiveOuts.available(*MRI, LI.PhysReg)) + continue; + MachineBasicBlock::iterator At = Pred->getFirstTerminator(); + const DebugLoc &dl = Pred->findDebugLoc(At); + BuildMI(*Pred, At, dl, TII->get(TargetOpcode::IMPLICIT_DEF), + LI.PhysReg); + } + } } ++NumTailMerge; Index: test/CodeGen/Hexagon/branchfolder-insert-impdef.mir =================================================================== --- /dev/null +++ test/CodeGen/Hexagon/branchfolder-insert-impdef.mir @@ -0,0 +1,43 @@ +# RUN: llc -march=hexagon -run-pass branch-folder %s -o - -verify-machineinstrs | FileCheck %s + +# Branch folding will perform tail merging of bb.1 and bb.2, and bb.2 will +# become the common tail. The use of R0 in bb.2 is while the +# corresponding use in bb.1 is not. The common tail will have the +# flag removed, which will cause R0 to become a live-in to bb.2. The problem +# is that R0 is not live-out from all predecessors of bb.2, namely is not +# live-out from bb.0. To remedy that, the branch folder should add an +# IMPLICIT_DEF to that block. + +# CHECK-LABEL: bb.0: +# CHECK: %r0 = IMPLICIT_DEF +# CHECK-LABEL: bb.1: +# CHECK-LABEL: bb.2: +# CHECK: liveins: %r0 +# CHECK: PS_storerhabs 0, %r0 +# CHECK: PS_jmpret + +--- +name: fred +tracksRegLiveness: true + +body: | + bb.0: + successors: %bb.1, %bb.2 + J2_jumpt undef %p0, %bb.2, implicit-def %pc + J2_jump %bb.1, implicit-def %pc + + bb.1: + successors: %bb.3 + %r0 = L2_loadruh_io undef %r1, 0 + PS_storerhabs 0, killed %r0 + J2_jump %bb.3, implicit-def %pc + + bb.2: + successors: %bb.3 + PS_storerhabs 0, undef %r0 + J2_jump %bb.3, implicit-def %pc + + bb.3: + PS_jmpret killed %r31, implicit-def %pc +... + Index: test/CodeGen/Hexagon/livephysregs-lane-masks2.mir =================================================================== --- test/CodeGen/Hexagon/livephysregs-lane-masks2.mir +++ test/CodeGen/Hexagon/livephysregs-lane-masks2.mir @@ -13,13 +13,13 @@ body: | bb.0: - liveins: %p2, %r0 + liveins: %p0:0x1, %p2, %r0 successors: %bb.1, %bb.2 J2_jumpt killed %p2, %bb.1, implicit-def %pc J2_jump %bb.2, implicit-def %pc bb.1: - liveins: %r0, %r19 + liveins: %p0:0x1, %r0, %r19 successors: %bb.3 %r2 = A2_tfrsi 4 %r1 = COPY %r19 @@ -28,7 +28,7 @@ J2_jump %bb.3, implicit-def %pc bb.2: - liveins: %r0, %r18 + liveins: %p0:0x1, %r0, %r18 successors: %bb.3 %r2 = A2_tfrsi 5 %r1 = L2_loadrh_io %r18, 0