Skip to content

Commit fc95560

Browse files
committed
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
1 parent 5d0fbab commit fc95560

File tree

4 files changed

+60
-16
lines changed

4 files changed

+60
-16
lines changed

llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@ namespace llvm {
282282
I = r2iMap_.insert(std::make_pair(reg, createInterval(reg))).first;
283283
return *I->second;
284284
}
285+
286+
/// dupInterval - Duplicate a live interval. The caller is responsible for
287+
/// managing the allocated memory.
288+
LiveInterval *dupInterval(LiveInterval *li);
285289

286290
/// addLiveRangeToEndOfBlock - Given a register and an instruction,
287291
/// adds a live range from that instruction to the end of its MBB.

llvm/lib/CodeGen/LiveIntervalAnalysis.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,11 +824,18 @@ bool LiveIntervals::findReachableMBBs(unsigned Start, unsigned End,
824824
}
825825

826826
LiveInterval* LiveIntervals::createInterval(unsigned reg) {
827-
float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ?
828-
HUGE_VALF : 0.0F;
827+
float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ? HUGE_VALF : 0.0F;
829828
return new LiveInterval(reg, Weight);
830829
}
831830

831+
/// dupInterval - Duplicate a live interval. The caller is responsible for
832+
/// managing the allocated memory.
833+
LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) {
834+
LiveInterval *NewLI = createInterval(li->reg);
835+
NewLI->Copy(*li, getVNInfoAllocator());
836+
return NewLI;
837+
}
838+
832839
/// getVNInfoSourceReg - Helper function that parses the specified VNInfo
833840
/// copy field and returns the source register that defines it.
834841
unsigned LiveIntervals::getVNInfoSourceReg(const VNInfo *VNI) const {

llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,15 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
13221322
DOUT << " and "; DstInt.print(DOUT, tri_);
13231323
DOUT << ": ";
13241324

1325+
// Save a copy of the virtual register live interval. We'll manually
1326+
// merge this into the "real" physical register live interval this is
1327+
// coalesced with.
1328+
LiveInterval *SavedLI = 0;
1329+
if (RealDstReg)
1330+
SavedLI = li_->dupInterval(&SrcInt);
1331+
else if (RealSrcReg)
1332+
SavedLI = li_->dupInterval(&DstInt);
1333+
13251334
// Check if it is necessary to propagate "isDead" property.
13261335
if (!isExtSubReg && !isInsSubReg) {
13271336
MachineOperand *mopd = CopyMI->findRegisterDefOperand(DstReg, false);
@@ -1413,21 +1422,17 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
14131422
if (RealDstReg || RealSrcReg) {
14141423
LiveInterval &RealInt =
14151424
li_->getOrCreateInterval(RealDstReg ? RealDstReg : RealSrcReg);
1416-
SmallSet<const VNInfo*, 4> CopiedValNos;
1417-
for (LiveInterval::Ranges::const_iterator I = ResSrcInt->ranges.begin(),
1418-
E = ResSrcInt->ranges.end(); I != E; ++I) {
1419-
const LiveRange *DstLR = ResDstInt->getLiveRangeContaining(I->start);
1420-
assert(DstLR && "Invalid joined interval!");
1421-
const VNInfo *DstValNo = DstLR->valno;
1422-
if (CopiedValNos.insert(DstValNo)) {
1423-
VNInfo *ValNo = RealInt.getNextValue(DstValNo->def, DstValNo->copy,
1424-
li_->getVNInfoAllocator());
1425-
ValNo->hasPHIKill = DstValNo->hasPHIKill;
1426-
RealInt.addKills(ValNo, DstValNo->kills);
1427-
RealInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo);
1428-
}
1425+
for (LiveInterval::const_vni_iterator I = SavedLI->vni_begin(),
1426+
E = SavedLI->vni_end(); I != E; ++I) {
1427+
const VNInfo *ValNo = *I;
1428+
VNInfo *NewValNo = RealInt.getNextValue(ValNo->def, ValNo->copy,
1429+
li_->getVNInfoAllocator());
1430+
NewValNo->hasPHIKill = ValNo->hasPHIKill;
1431+
NewValNo->redefByEC = ValNo->redefByEC;
1432+
RealInt.addKills(NewValNo, ValNo->kills);
1433+
RealInt.MergeValueInAsValue(*SavedLI, ValNo, NewValNo);
14291434
}
1430-
1435+
RealInt.weight += SavedLI->weight;
14311436
DstReg = RealDstReg ? RealDstReg : RealSrcReg;
14321437
}
14331438

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

1505+
// Manually deleted the live interval copy.
1506+
if (SavedLI) {
1507+
SavedLI->clear();
1508+
delete SavedLI;
1509+
}
1510+
15001511
if (isEmpty) {
15011512
// Now the copy is being coalesced away, the val# previously defined
15021513
// by the copy is being defined by an IMPLICIT_DEF which defines a zero
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; RUN: llvm-as < %s | llc -march=x86
2+
; PR3486
3+
4+
define i32 @foo(i8 signext %p_26) nounwind {
5+
entry:
6+
%0 = icmp eq i8 %p_26, 0 ; <i1> [#uses=2]
7+
%or.cond = or i1 false, %0 ; <i1> [#uses=2]
8+
%iftmp.1.0 = zext i1 %or.cond to i16 ; <i16> [#uses=1]
9+
br i1 %0, label %bb.i, label %bar.exit
10+
11+
bb.i: ; preds = %entry
12+
%1 = zext i1 %or.cond to i32 ; <i32> [#uses=1]
13+
%2 = sdiv i32 %1, 0 ; <i32> [#uses=1]
14+
%3 = trunc i32 %2 to i16 ; <i16> [#uses=1]
15+
br label %bar.exit
16+
17+
bar.exit: ; preds = %bb.i, %entry
18+
%4 = phi i16 [ %3, %bb.i ], [ %iftmp.1.0, %entry ] ; <i16> [#uses=1]
19+
%5 = trunc i16 %4 to i8 ; <i8> [#uses=1]
20+
%6 = sext i8 %5 to i32 ; <i32> [#uses=1]
21+
ret i32 %6
22+
}

0 commit comments

Comments
 (0)