Index: lib/CodeGen/PHIElimination.cpp =================================================================== --- lib/CodeGen/PHIElimination.cpp +++ lib/CodeGen/PHIElimination.cpp @@ -46,6 +46,10 @@ cl::Hidden, cl::desc("Split all critical edges during " "PHI elimination")); +static cl::opt NoPhiElimLiveOutEarlyExit( + "no-phi-elim-live-out-early-exit", cl::init(false), cl::Hidden, + cl::desc("Do not use an early exit if isLiveOutPastPHIs returns true.")); + namespace { class PHIElimination : public MachineFunctionPass { MachineRegisterInfo *MRI; // Machine register information @@ -573,12 +577,14 @@ // there is a risk it may not be coalesced away. // // If the copy would be a kill, there is no need to split the edge. - if (!isLiveOutPastPHIs(Reg, PreMBB) && !SplitAllCriticalEdges) + bool ShouldSplit = isLiveOutPastPHIs(Reg, PreMBB); + if (!ShouldSplit && !NoPhiElimLiveOutEarlyExit) continue; - - DEBUG(dbgs() << PrintReg(Reg) << " live-out before critical edge BB#" - << PreMBB->getNumber() << " -> BB#" << MBB.getNumber() - << ": " << *BBI); + if (ShouldSplit) { + DEBUG(dbgs() << PrintReg(Reg) << " live-out before critical edge BB#" + << PreMBB->getNumber() << " -> BB#" << MBB.getNumber() + << ": " << *BBI); + } // If Reg is not live-in to MBB, it means it must be live-in to some // other PreMBB successor, and we can avoid the interference by splitting @@ -588,7 +594,7 @@ // is likely to be left after coalescing. If we are looking at a loop // exiting edge, split it so we won't insert code in the loop, otherwise // don't bother. - bool ShouldSplit = !isLiveIn(Reg, &MBB) || SplitAllCriticalEdges; + ShouldSplit = ShouldSplit && !isLiveIn(Reg, &MBB); // Check for a loop exiting edge. if (!ShouldSplit && CurLoop != PreLoop) { @@ -603,7 +609,7 @@ // Split unless this edge is entering CurLoop from an outer loop. ShouldSplit = PreLoop && !PreLoop->contains(CurLoop); } - if (!ShouldSplit) + if (!ShouldSplit && !SplitAllCriticalEdges) continue; if (!PreMBB->SplitCriticalEdge(&MBB, this)) { DEBUG(dbgs() << "Failed to split critical edge.\n"); Index: test/CodeGen/X86/phielim-split.ll =================================================================== --- test/CodeGen/X86/phielim-split.ll +++ test/CodeGen/X86/phielim-split.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -verify-machineinstrs -no-phi-elim-live-out-early-exit | FileCheck %s target triple = "x86_64-apple-macosx10.8.0" ; The critical edge from for.cond to if.end2 should be split to avoid injecting @@ -28,3 +28,40 @@ %add = add nsw i32 %r.0, %b ret i32 %add } + +; CHECK: split_live_out +; CHECK: %while.body +; CHECK: cmp +; CHECK-NEXT: ja +define i8* @split_live_out(i32 %value, i8* %target) nounwind uwtable readonly ssp { +entry: + %cmp10 = icmp ugt i32 %value, 127 + br i1 %cmp10, label %while.body.preheader, label %while.end + +while.body.preheader: ; preds = %entry + br label %while.body + +while.body: ; preds = %while.body.preheader, %while.body + %target.addr.012 = phi i8* [ %incdec.ptr, %while.body ], [ %target, %while.body.preheader ] + %value.addr.011 = phi i32 [ %shr, %while.body ], [ %value, %while.body.preheader ] + %or = or i32 %value.addr.011, 128 + %conv = trunc i32 %or to i8 + store i8 %conv, i8* %target.addr.012, align 1 + %shr = lshr i32 %value.addr.011, 7 + %incdec.ptr = getelementptr inbounds i8, i8* %target.addr.012, i64 1 + %cmp = icmp ugt i32 %value.addr.011, 16383 + br i1 %cmp, label %while.body, label %while.end.loopexit + +while.end.loopexit: ; preds = %while.body + %incdec.ptr.lcssa = phi i8* [ %incdec.ptr, %while.body ] + %shr.lcssa = phi i32 [ %shr, %while.body ] + br label %while.end + +while.end: ; preds = %while.end.loopexit, %entry + %target.addr.0.lcssa = phi i8* [ %target, %entry ], [ %incdec.ptr.lcssa, %while.end.loopexit ] + %value.addr.0.lcssa = phi i32 [ %value, %entry ], [ %shr.lcssa, %while.end.loopexit ] + %conv1 = trunc i32 %value.addr.0.lcssa to i8 + store i8 %conv1, i8* %target.addr.0.lcssa, align 1 + %incdec.ptr3 = getelementptr inbounds i8, i8* %target.addr.0.lcssa, i64 1 + ret i8* %incdec.ptr3 +}