Commit fc955600 authored by Tanya Lattner's avatar Tanya Lattner
Browse files

Merge from mainline.

Fix PR3486. Fix a bug in code that manually patch physical register live interval after its sub-register is coalesced with a virtual register.

llvm-svn: 64509
parent 5d0fbabe
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -283,6 +283,10 @@ namespace llvm {
      return *I->second;
    }

    /// dupInterval - Duplicate a live interval. The caller is responsible for
    /// managing the allocated memory.
    LiveInterval *dupInterval(LiveInterval *li);
    
    /// addLiveRangeToEndOfBlock - Given a register and an instruction,
    /// adds a live range from that instruction to the end of its MBB.
    LiveRange addLiveRangeToEndOfBlock(unsigned reg,
+9 −2
Original line number Diff line number Diff line
@@ -824,11 +824,18 @@ bool LiveIntervals::findReachableMBBs(unsigned Start, unsigned End,
}

LiveInterval* LiveIntervals::createInterval(unsigned reg) {
  float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ?
                       HUGE_VALF : 0.0F;
  float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ? HUGE_VALF : 0.0F;
  return new LiveInterval(reg, Weight);
}

/// dupInterval - Duplicate a live interval. The caller is responsible for
/// managing the allocated memory.
LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) {
  LiveInterval *NewLI = createInterval(li->reg);
  NewLI->Copy(*li, getVNInfoAllocator());
  return NewLI;
}

/// getVNInfoSourceReg - Helper function that parses the specified VNInfo
/// copy field and returns the source register that defines it.
unsigned LiveIntervals::getVNInfoSourceReg(const VNInfo *VNI) const {
+25 −14
Original line number Diff line number Diff line
@@ -1322,6 +1322,15 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
  DOUT << " and "; DstInt.print(DOUT, tri_);
  DOUT << ": ";

  // Save a copy of the virtual register live interval. We'll manually
  // merge this into the "real" physical register live interval this is
  // coalesced with.
  LiveInterval *SavedLI = 0;
  if (RealDstReg)
    SavedLI = li_->dupInterval(&SrcInt);
  else if (RealSrcReg)
    SavedLI = li_->dupInterval(&DstInt);

  // Check if it is necessary to propagate "isDead" property.
  if (!isExtSubReg && !isInsSubReg) {
    MachineOperand *mopd = CopyMI->findRegisterDefOperand(DstReg, false);
@@ -1413,21 +1422,17 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
    if (RealDstReg || RealSrcReg) {
      LiveInterval &RealInt =
        li_->getOrCreateInterval(RealDstReg ? RealDstReg : RealSrcReg);
      SmallSet<const VNInfo*, 4> CopiedValNos;
      for (LiveInterval::Ranges::const_iterator I = ResSrcInt->ranges.begin(),
             E = ResSrcInt->ranges.end(); I != E; ++I) {
        const LiveRange *DstLR = ResDstInt->getLiveRangeContaining(I->start);
        assert(DstLR  && "Invalid joined interval!");
        const VNInfo *DstValNo = DstLR->valno;
        if (CopiedValNos.insert(DstValNo)) {
          VNInfo *ValNo = RealInt.getNextValue(DstValNo->def, DstValNo->copy,
      for (LiveInterval::const_vni_iterator I = SavedLI->vni_begin(),
             E = SavedLI->vni_end(); I != E; ++I) {
        const VNInfo *ValNo = *I;
        VNInfo *NewValNo = RealInt.getNextValue(ValNo->def, ValNo->copy,
                                                li_->getVNInfoAllocator());
          ValNo->hasPHIKill = DstValNo->hasPHIKill;
          RealInt.addKills(ValNo, DstValNo->kills);
          RealInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo);
        }
        NewValNo->hasPHIKill = ValNo->hasPHIKill;
        NewValNo->redefByEC = ValNo->redefByEC;
        RealInt.addKills(NewValNo, ValNo->kills);
        RealInt.MergeValueInAsValue(*SavedLI, ValNo, NewValNo);
      }
      
      RealInt.weight += SavedLI->weight;      
      DstReg = RealDstReg ? RealDstReg : RealSrcReg;
    }

@@ -1497,6 +1502,12 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
  // being merged.
  li_->removeInterval(SrcReg);

  // Manually deleted the live interval copy.
  if (SavedLI) {
    SavedLI->clear();
    delete SavedLI;
  }

  if (isEmpty) {
    // Now the copy is being coalesced away, the val# previously defined
    // by the copy is being defined by an IMPLICIT_DEF which defines a zero
+22 −0
Original line number Diff line number Diff line
; RUN: llvm-as < %s | llc -march=x86
; PR3486

define i32 @foo(i8 signext %p_26) nounwind {
entry:
	%0 = icmp eq i8 %p_26, 0		; <i1> [#uses=2]
	%or.cond = or i1 false, %0		; <i1> [#uses=2]
	%iftmp.1.0 = zext i1 %or.cond to i16		; <i16> [#uses=1]
	br i1 %0, label %bb.i, label %bar.exit

bb.i:		; preds = %entry
	%1 = zext i1 %or.cond to i32		; <i32> [#uses=1]
	%2 = sdiv i32 %1, 0		; <i32> [#uses=1]
	%3 = trunc i32 %2 to i16		; <i16> [#uses=1]
	br label %bar.exit

bar.exit:		; preds = %bb.i, %entry
	%4 = phi i16 [ %3, %bb.i ], [ %iftmp.1.0, %entry ]		; <i16> [#uses=1]
	%5 = trunc i16 %4 to i8		; <i8> [#uses=1]
	%6 = sext i8 %5 to i32		; <i32> [#uses=1]
	ret i32 %6
}