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,30 @@ if (UpdateLiveIns) { NewDest->clearLiveIns(); computeLiveIns(LiveRegs, *MRI, *NewDest); + + LivePhysRegs CalcLiveIns; + for (MachineBasicBlock *Pred : NewDest->predecessors()) { + // Check if all live-ins of NewDest are live-on-exit from Pred. + // If not, add an IMPLICIT_DEF. + // Normally, this should check if for each live-in to NewDest there + // exists a downward-exposed def in Pred. To avoid using stepForward + // in LivePhysRegs, scan the block backward instead, and then check + // if we would need to add a new live-in to Pred. + CalcLiveIns.init(*TRI); + CalcLiveIns.addLiveOutsNoPristines(*Pred); + for (const MachineInstr &MI : llvm::reverse(*Pred)) + CalcLiveIns.stepBackward(MI); + + LivePhysRegs LiveIns(*TRI); + LiveIns.addLiveIns(*Pred); + for (MCPhysReg R : CalcLiveIns) { + if (!LiveIns.available(*MRI, R)) + continue; + MachineBasicBlock::iterator At = Pred->getFirstTerminator(); + const DebugLoc &dl = Pred->findDebugLoc(At); + BuildMI(*Pred, At, dl, TII->get(TargetOpcode::IMPLICIT_DEF), R); + } + } } ++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