mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
After reading memory that's already freed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49810 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
52e724ad7e
commit
9c1e06e187
@ -560,8 +560,8 @@ static void removeRange(LiveInterval &li, unsigned Start, unsigned End,
|
|||||||
|
|
||||||
/// removeIntervalIfEmpty - Check if the live interval of a physical register
|
/// removeIntervalIfEmpty - Check if the live interval of a physical register
|
||||||
/// is empty, if so remove it and also remove the empty intervals of its
|
/// is empty, if so remove it and also remove the empty intervals of its
|
||||||
/// sub-registers.
|
/// sub-registers. Return true if live interval is removed.
|
||||||
static void removeIntervalIfEmpty(LiveInterval &li, LiveIntervals *li_,
|
static bool removeIntervalIfEmpty(LiveInterval &li, LiveIntervals *li_,
|
||||||
const TargetRegisterInfo *tri_) {
|
const TargetRegisterInfo *tri_) {
|
||||||
if (li.empty()) {
|
if (li.empty()) {
|
||||||
if (TargetRegisterInfo::isPhysicalRegister(li.reg))
|
if (TargetRegisterInfo::isPhysicalRegister(li.reg))
|
||||||
@ -573,25 +573,28 @@ static void removeIntervalIfEmpty(LiveInterval &li, LiveIntervals *li_,
|
|||||||
li_->removeInterval(*SR);
|
li_->removeInterval(*SR);
|
||||||
}
|
}
|
||||||
li_->removeInterval(li.reg);
|
li_->removeInterval(li.reg);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ShortenDeadCopyLiveRange - Shorten a live range defined by a dead copy.
|
/// ShortenDeadCopyLiveRange - Shorten a live range defined by a dead copy.
|
||||||
///
|
/// Return true if live interval is removed.
|
||||||
void SimpleRegisterCoalescing::ShortenDeadCopyLiveRange(LiveInterval &li,
|
bool SimpleRegisterCoalescing::ShortenDeadCopyLiveRange(LiveInterval &li,
|
||||||
MachineInstr *CopyMI) {
|
MachineInstr *CopyMI) {
|
||||||
unsigned CopyIdx = li_->getInstructionIndex(CopyMI);
|
unsigned CopyIdx = li_->getInstructionIndex(CopyMI);
|
||||||
LiveInterval::iterator MLR =
|
LiveInterval::iterator MLR =
|
||||||
li.FindLiveRangeContaining(li_->getDefIndex(CopyIdx));
|
li.FindLiveRangeContaining(li_->getDefIndex(CopyIdx));
|
||||||
if (MLR == li.end())
|
if (MLR == li.end())
|
||||||
return; // Already removed by ShortenDeadCopySrcLiveRange.
|
return false; // Already removed by ShortenDeadCopySrcLiveRange.
|
||||||
unsigned RemoveStart = MLR->start;
|
unsigned RemoveStart = MLR->start;
|
||||||
unsigned RemoveEnd = MLR->end;
|
unsigned RemoveEnd = MLR->end;
|
||||||
// Remove the liverange that's defined by this.
|
// Remove the liverange that's defined by this.
|
||||||
if (RemoveEnd == li_->getDefIndex(CopyIdx)+1) {
|
if (RemoveEnd == li_->getDefIndex(CopyIdx)+1) {
|
||||||
removeRange(li, RemoveStart, RemoveEnd, li_, tri_);
|
removeRange(li, RemoveStart, RemoveEnd, li_, tri_);
|
||||||
removeIntervalIfEmpty(li, li_, tri_);
|
return removeIntervalIfEmpty(li, li_, tri_);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PropagateDeadness - Propagate the dead marker to the instruction which
|
/// PropagateDeadness - Propagate the dead marker to the instruction which
|
||||||
@ -614,8 +617,8 @@ static void PropagateDeadness(LiveInterval &li, MachineInstr *CopyMI,
|
|||||||
/// ShortenDeadCopyLiveRange - Shorten a live range as it's artificially
|
/// ShortenDeadCopyLiveRange - Shorten a live range as it's artificially
|
||||||
/// extended by a dead copy. Mark the last use (if any) of the val# as kill
|
/// extended by a dead copy. Mark the last use (if any) of the val# as kill
|
||||||
/// as ends the live range there. If there isn't another use, then this
|
/// as ends the live range there. If there isn't another use, then this
|
||||||
/// live range is dead.
|
/// live range is dead. Return true if live interval is removed.
|
||||||
void
|
bool
|
||||||
SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li,
|
SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li,
|
||||||
MachineInstr *CopyMI) {
|
MachineInstr *CopyMI) {
|
||||||
unsigned CopyIdx = li_->getInstructionIndex(CopyMI);
|
unsigned CopyIdx = li_->getInstructionIndex(CopyMI);
|
||||||
@ -627,20 +630,19 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li,
|
|||||||
mf_->begin()->removeLiveIn(li.reg);
|
mf_->begin()->removeLiveIn(li.reg);
|
||||||
const LiveRange *LR = li.getLiveRangeContaining(CopyIdx);
|
const LiveRange *LR = li.getLiveRangeContaining(CopyIdx);
|
||||||
removeRange(li, LR->start, LR->end, li_, tri_);
|
removeRange(li, LR->start, LR->end, li_, tri_);
|
||||||
removeIntervalIfEmpty(li, li_, tri_);
|
return removeIntervalIfEmpty(li, li_, tri_);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveInterval::iterator LR = li.FindLiveRangeContaining(CopyIdx-1);
|
LiveInterval::iterator LR = li.FindLiveRangeContaining(CopyIdx-1);
|
||||||
if (LR == li.end())
|
if (LR == li.end())
|
||||||
// Livein but defined by a phi.
|
// Livein but defined by a phi.
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
unsigned RemoveStart = LR->start;
|
unsigned RemoveStart = LR->start;
|
||||||
unsigned RemoveEnd = li_->getDefIndex(CopyIdx)+1;
|
unsigned RemoveEnd = li_->getDefIndex(CopyIdx)+1;
|
||||||
if (LR->end > RemoveEnd)
|
if (LR->end > RemoveEnd)
|
||||||
// More uses past this copy? Nothing to do.
|
// More uses past this copy? Nothing to do.
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
unsigned LastUseIdx;
|
unsigned LastUseIdx;
|
||||||
MachineOperand *LastUse = lastRegisterUse(LR->start, CopyIdx-1, li.reg,
|
MachineOperand *LastUse = lastRegisterUse(LR->start, CopyIdx-1, li.reg,
|
||||||
@ -658,7 +660,7 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li,
|
|||||||
int DeadIdx = LastUseMI->findRegisterDefOperandIdx(li.reg, false, tri_);
|
int DeadIdx = LastUseMI->findRegisterDefOperandIdx(li.reg, false, tri_);
|
||||||
LastUseMI->getOperand(DeadIdx).setIsDead();
|
LastUseMI->getOperand(DeadIdx).setIsDead();
|
||||||
}
|
}
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is it livein?
|
// Is it livein?
|
||||||
@ -678,7 +680,7 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li,
|
|||||||
PropagateDeadness(li, CopyMI, RemoveStart, li_, tri_);
|
PropagateDeadness(li, CopyMI, RemoveStart, li_, tri_);
|
||||||
|
|
||||||
removeRange(li, RemoveStart, LR->end, li_, tri_);
|
removeRange(li, RemoveStart, LR->end, li_, tri_);
|
||||||
removeIntervalIfEmpty(li, li_, tri_);
|
return removeIntervalIfEmpty(li, li_, tri_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CanCoalesceWithImpDef - Returns true if the specified copy instruction
|
/// CanCoalesceWithImpDef - Returns true if the specified copy instruction
|
||||||
@ -1952,8 +1954,8 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
}
|
}
|
||||||
if (CopyMI->registerDefIsDead(DstReg)) {
|
if (CopyMI->registerDefIsDead(DstReg)) {
|
||||||
LiveInterval &li = li_->getInterval(DstReg);
|
LiveInterval &li = li_->getInterval(DstReg);
|
||||||
ShortenDeadCopySrcLiveRange(li, CopyMI);
|
if (!ShortenDeadCopySrcLiveRange(li, CopyMI))
|
||||||
ShortenDeadCopyLiveRange(li, CopyMI);
|
ShortenDeadCopyLiveRange(li, CopyMI);
|
||||||
}
|
}
|
||||||
li_->RemoveMachineInstrFromMaps(*I);
|
li_->RemoveMachineInstrFromMaps(*I);
|
||||||
(*I)->eraseFromParent();
|
(*I)->eraseFromParent();
|
||||||
@ -1979,8 +1981,8 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
// If def of this move instruction is dead, remove its live range
|
// If def of this move instruction is dead, remove its live range
|
||||||
// from the dstination register's live interval.
|
// from the dstination register's live interval.
|
||||||
if (mii->registerDefIsDead(dstReg)) {
|
if (mii->registerDefIsDead(dstReg)) {
|
||||||
ShortenDeadCopySrcLiveRange(RegInt, mii);
|
if (!ShortenDeadCopySrcLiveRange(RegInt, mii))
|
||||||
ShortenDeadCopyLiveRange(RegInt, mii);
|
ShortenDeadCopyLiveRange(RegInt, mii);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
li_->RemoveMachineInstrFromMaps(mii);
|
li_->RemoveMachineInstrFromMaps(mii);
|
||||||
|
@ -232,14 +232,14 @@ namespace llvm {
|
|||||||
void RemoveUnnecessaryKills(unsigned Reg, LiveInterval &LI);
|
void RemoveUnnecessaryKills(unsigned Reg, LiveInterval &LI);
|
||||||
|
|
||||||
/// ShortenDeadCopyLiveRange - Shorten a live range defined by a dead copy.
|
/// ShortenDeadCopyLiveRange - Shorten a live range defined by a dead copy.
|
||||||
///
|
/// Return true if live interval is removed.
|
||||||
void ShortenDeadCopyLiveRange(LiveInterval &li, MachineInstr *CopyMI);
|
bool ShortenDeadCopyLiveRange(LiveInterval &li, MachineInstr *CopyMI);
|
||||||
|
|
||||||
/// ShortenDeadCopyLiveRange - Shorten a live range as it's artificially
|
/// ShortenDeadCopyLiveRange - Shorten a live range as it's artificially
|
||||||
/// extended by a dead copy. Mark the last use (if any) of the val# as kill
|
/// extended by a dead copy. Mark the last use (if any) of the val# as kill
|
||||||
/// as ends the live range there. If there isn't another use, then this
|
/// as ends the live range there. If there isn't another use, then this
|
||||||
/// live range is dead.
|
/// live range is dead. Return true if live interval is removed.
|
||||||
void ShortenDeadCopySrcLiveRange(LiveInterval &li, MachineInstr *CopyMI);
|
bool ShortenDeadCopySrcLiveRange(LiveInterval &li, MachineInstr *CopyMI);
|
||||||
|
|
||||||
/// lastRegisterUse - Returns the last use of the specific register between
|
/// lastRegisterUse - Returns the last use of the specific register between
|
||||||
/// cycles Start and End or NULL if there are no uses.
|
/// cycles Start and End or NULL if there are no uses.
|
||||||
|
14
test/CodeGen/PowerPC/2008-04-16-CoalescerBug.ll
Normal file
14
test/CodeGen/PowerPC/2008-04-16-CoalescerBug.ll
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin
|
||||||
|
; Avoid reading memory that's already freed.
|
||||||
|
|
||||||
|
@llvm.used = appending global [1 x i8*] [ i8* bitcast (i32 (i64)* @_Z13GetSectorSizey to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0]
|
||||||
|
|
||||||
|
define i32 @_Z13GetSectorSizey(i64 %Base) nounwind {
|
||||||
|
entry:
|
||||||
|
br i1 false, label %bb, label %UnifiedReturnBlock
|
||||||
|
bb: ; preds = %entry
|
||||||
|
%tmp10 = and i64 0, %Base ; <i64> [#uses=0]
|
||||||
|
ret i32 0
|
||||||
|
UnifiedReturnBlock: ; preds = %entry
|
||||||
|
ret i32 131072
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user