From: Evan Cheng Date: Wed, 1 Jul 2009 01:59:31 +0000 (+0000) Subject: Handle IMPLICIT_DEF with isUndef operand marker, part 2. This patch moves the code... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=2578ba26e72e36dde64be0f52a2788480aad3378;p=oota-llvm.git Handle IMPLICIT_DEF with isUndef operand marker, part 2. This patch moves the code to annotate machineoperands to LiveIntervalAnalysis. It also add markers for implicit_def that define physical registers. The rest, is just a lot of details. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74580 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 7c44cc7dbf2..7ae98bb093d 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -390,6 +390,10 @@ namespace llvm { unsigned getNumConflictsWithPhysReg(const LiveInterval &li, unsigned PhysReg) const; + /// processImplicitDefs - Process IMPLICIT_DEF instructions. Add isUndef + /// marker to implicit_def defs and their uses. + void processImplicitDefs(); + /// computeNumbering - Compute the index numbering. void computeNumbering(); diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index b017f91e6a4..9339c951a81 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -23,6 +23,7 @@ #include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" @@ -33,6 +34,8 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include @@ -98,6 +101,93 @@ void LiveIntervals::releaseMemory() { } } +/// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure +/// there is one implicit_def for each use. Add isUndef marker to +/// implicit_def defs and their uses. +void LiveIntervals::processImplicitDefs() { + SmallSet ImpDefRegs; + SmallVector ImpDefMIs; + MachineBasicBlock *Entry = mf_->begin(); + SmallPtrSet Visited; + for (df_ext_iterator > + DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited); + DFI != E; ++DFI) { + MachineBasicBlock *MBB = *DFI; + for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); + I != E; ) { + MachineInstr *MI = &*I; + ++I; + if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) { + unsigned Reg = MI->getOperand(0).getReg(); + MI->getOperand(0).setIsUndef(); + ImpDefRegs.insert(Reg); + ImpDefMIs.push_back(MI); + continue; + } + for (unsigned i = 0; i != MI->getNumOperands(); ++i) { + MachineOperand& MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isUse()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (!ImpDefRegs.count(Reg)) + continue; + MO.setIsUndef(); + if (MO.isKill() || MI->isRegTiedToDefOperand(i)) + ImpDefRegs.erase(Reg); + } + + for (unsigned i = 0; i != MI->getNumOperands(); ++i) { + MachineOperand& MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) + continue; + ImpDefRegs.erase(MO.getReg()); + } + } + + // Any outstanding liveout implicit_def's? + for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) { + MachineInstr *MI = ImpDefMIs[i]; + unsigned Reg = MI->getOperand(0).getReg(); + if (TargetRegisterInfo::isPhysicalRegister(Reg)) + // Physical registers are not liveout (yet). + continue; + if (!ImpDefRegs.count(Reg)) + continue; + bool HasLocalUse = false; + for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(Reg), + RE = mri_->reg_end(); RI != RE; ) { + MachineOperand &RMO = RI.getOperand(); + MachineInstr *RMI = &*RI; + ++RI; + if (RMO.isDef()) { + // Don't expect another def of the same register. + assert(RMI == MI && + "Register with multiple defs including an implicit_def?"); + continue; + } + MachineBasicBlock *RMBB = RMI->getParent(); + if (RMBB == MBB) { + HasLocalUse = true; + continue; + } + const TargetRegisterClass* RC = mri_->getRegClass(Reg); + unsigned NewVReg = mri_->createVirtualRegister(RC); + BuildMI(*RMBB, RMI, RMI->getDebugLoc(), + tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg); + RMO.setReg(NewVReg); + RMO.setIsUndef(); + RMO.setIsKill(); + } + if (!HasLocalUse) + MI->eraseFromParent(); + } + ImpDefRegs.clear(); + ImpDefMIs.clear(); + } +} + void LiveIntervals::computeNumbering() { Index2MiMap OldI2MI = i2miMap_; std::vector OldI2MBB = Idx2MBBMap; @@ -299,6 +389,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { lv_ = &getAnalysis(); allocatableRegs_ = tri_->getAllocatableSet(fn); + processImplicitDefs(); computeNumbering(); computeIntervals(); @@ -1785,8 +1876,6 @@ LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm, if (MO.isReg() && MO.getReg() == li.reg) { MO.setReg(NewVReg); MO.setIsUndef(); - if (MO.isKill()) - MO.setIsKill(false); } } } diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index 2caa2f9d180..904b4cb2a46 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -545,26 +545,6 @@ void RALinScan::linearScan() if (!isPhys && vrm_->getPreSplitReg(cur.reg)) continue; - // A register defined by an implicit_def can be liveout the def BB and livein - // to a use BB. Add it to the livein set of the use BB's. - if (!isPhys && cur.empty()) { - if (MachineInstr *DefMI = mri_->getVRegDef(cur.reg)) { - assert(DefMI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF); - MachineBasicBlock *DefMBB = DefMI->getParent(); - SmallPtrSet Seen; - Seen.insert(DefMBB); - for (MachineRegisterInfo::reg_iterator ri = mri_->reg_begin(cur.reg), - re = mri_->reg_end(); ri != re; ++ri) { - MachineInstr *UseMI = &*ri; - MachineBasicBlock *UseMBB = UseMI->getParent(); - if (Seen.insert(UseMBB)) { - assert(TargetRegisterInfo::isPhysicalRegister(Reg) && - "Adding a virtual register to livein set?"); - UseMBB->addLiveIn(Reg); - } - } - } - } for (LiveInterval::Ranges::const_iterator I = cur.begin(), E = cur.end(); I != E; ++I) { const LiveRange &LR = *I; @@ -905,17 +885,6 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) DOUT << tri_->getName(physReg) << '\n'; // Note the register is not really in use. vrm_->assignVirt2Phys(cur->reg, physReg); - // Since the register allocator is allowed to assign this virtual register - // physical register that overlaps other live intervals. Mark these - // operands as "Undef" which means later passes, e.g. register scavenger - // can ignore them. - for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(cur->reg), - RE = mri_->reg_end(); RI != RE; ++RI) { - MachineOperand &MO = RI.getOperand(); - MO.setIsUndef(); - if (MO.isKill()) - MO.setIsKill(false); - } return; } diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 382741ee733..58f4284ac75 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -254,6 +254,8 @@ void RegScavenger::forward() { unsigned Idx = (i < NumECs) ? EarlyClobberMOs[i].second : DefMOs[i-NumECs].second; unsigned Reg = MO.getReg(); + if (MO.isUndef()) + continue; // If it's dead upon def, then it is now free. if (MO.isDead()) { @@ -262,7 +264,9 @@ void RegScavenger::forward() { } // Skip two-address destination operand. - if (MI->isRegTiedToUseOperand(Idx)) { + unsigned UseIdx; + if (MI->isRegTiedToUseOperand(Idx, &UseIdx) && + !MI->getOperand(UseIdx).isUndef()) { assert(isUsed(Reg) && "Using an undefined register!"); continue; } @@ -316,6 +320,8 @@ void RegScavenger::backward() { ? *DefMOs[i].first : *EarlyClobberMOs[i-NumDefs].first; unsigned Idx = (i < NumECs) ? DefMOs[i].second : EarlyClobberMOs[i-NumDefs].second; + if (MO.isUndef()) + continue; // Skip two-address destination operand. if (MI->isRegTiedToUseOperand(Idx)) diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index bbf1e248731..be0b016b669 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -2029,8 +2029,12 @@ private: if (!TargetRegisterInfo::isVirtualRegister(VirtReg)) { // Check to see if this is a noop copy. If so, eliminate the // instruction before considering the dest reg to be changed. + // Also check if it's copying from an "undef", if so, we can't + // eliminate this or else the undef marker is lost and it will + // confuses the scavenger. This is extremely rare. unsigned Src, Dst, SrcSR, DstSR; - if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) { + if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst && + !MI.findRegisterUseOperand(Src)->isUndef()) { ++NumDCE; DOUT << "Removing now-noop copy: " << MI; SmallVector KillRegs; @@ -2049,7 +2053,7 @@ private: Spills.disallowClobberPhysReg(VirtReg); goto ProcessNextInst; } - + // If it's not a no-op copy, it clobbers the value in the destreg. Spills.ClobberPhysReg(VirtReg); ReusedOperands.markClobbered(VirtReg); diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp index 35ebb7eec86..482867e6ec4 100644 --- a/lib/Target/ARM/ARMInstrInfo.cpp +++ b/lib/Target/ARM/ARMInstrInfo.cpp @@ -619,14 +619,19 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, if (OpNum == 0) { // move -> store unsigned SrcReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR)) - .addReg(SrcReg, getKillRegState(isKill)) + .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); } else { // move -> load unsigned DstReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR)) - .addReg(DstReg, RegState::Define | getDeadRegState(isDead)) + .addReg(DstReg, + RegState::Define | + getDeadRegState(isDead) | + getUndefRegState(isUndef)) .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); } break; @@ -636,14 +641,22 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, unsigned PredReg = MI->getOperand(3).getReg(); if (OpNum == 0) { // move -> store unsigned SrcReg = MI->getOperand(1).getReg(); + bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS)) - .addReg(SrcReg).addFrameIndex(FI) + .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) + .addFrameIndex(FI) .addImm(0).addImm(Pred).addReg(PredReg); } else { // move -> load unsigned DstReg = MI->getOperand(0).getReg(); - NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS), DstReg) - .addFrameIndex(FI) - .addImm(0).addImm(Pred).addReg(PredReg); + bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); + NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS)) + .addReg(DstReg, + RegState::Define | + getDeadRegState(isDead) | + getUndefRegState(isUndef)) + .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); } break; } @@ -653,14 +666,19 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, if (OpNum == 0) { // move -> store unsigned SrcReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD)) - .addReg(SrcReg, getKillRegState(isKill)) + .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); } else { // move -> load unsigned DstReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDD)) - .addReg(DstReg, RegState::Define | getDeadRegState(isDead)) + .addReg(DstReg, + RegState::Define | + getDeadRegState(isDead) | + getUndefRegState(isUndef)) .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); } break; diff --git a/lib/Target/Alpha/AlphaInstrInfo.cpp b/lib/Target/Alpha/AlphaInstrInfo.cpp index 229f9d4784a..203c7b15de9 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.cpp +++ b/lib/Target/Alpha/AlphaInstrInfo.cpp @@ -289,19 +289,22 @@ MachineInstr *AlphaInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, if (Ops[0] == 0) { // move -> store unsigned InReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); Opc = (Opc == Alpha::BISr) ? Alpha::STQ : ((Opc == Alpha::CPYSS) ? Alpha::STS : Alpha::STT); NewMI = BuildMI(MF, MI->getDebugLoc(), get(Opc)) - .addReg(InReg, getKillRegState(isKill)) + .addReg(InReg, getKillRegState(isKill) | getUndefRegState(isUndef)) .addFrameIndex(FrameIndex) .addReg(Alpha::F31); } else { // load -> move unsigned OutReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); Opc = (Opc == Alpha::BISr) ? Alpha::LDQ : ((Opc == Alpha::CPYSS) ? Alpha::LDS : Alpha::LDT); NewMI = BuildMI(MF, MI->getDebugLoc(), get(Opc)) - .addReg(OutReg, RegState::Define | getDeadRegState(isDead)) + .addReg(OutReg, RegState::Define | getDeadRegState(isDead) | + getUndefRegState(isUndef)) .addFrameIndex(FrameIndex) .addReg(Alpha::F31); } diff --git a/lib/Target/CellSPU/SPUInstrInfo.cpp b/lib/Target/CellSPU/SPUInstrInfo.cpp index 4af995a7813..e629c8d31aa 100644 --- a/lib/Target/CellSPU/SPUInstrInfo.cpp +++ b/lib/Target/CellSPU/SPUInstrInfo.cpp @@ -491,19 +491,22 @@ SPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, if (OpNum == 0) { // move -> store unsigned InReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); if (FrameIndex < SPUFrameInfo::maxFrameOffset()) { MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(SPU::STQDr32)); - MIB.addReg(InReg, getKillRegState(isKill)); + MIB.addReg(InReg, getKillRegState(isKill) | getUndefRegState(isUndef)); NewMI = addFrameReference(MIB, FrameIndex); } } else { // move -> load unsigned OutReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(Opc)); - MIB.addReg(OutReg, RegState::Define | getDeadRegState(isDead)); + MIB.addReg(OutReg, RegState::Define | getDeadRegState(isDead) | + getUndefRegState(isUndef)); Opc = (FrameIndex < SPUFrameInfo::maxFrameOffset()) ? SPU::STQDr32 : SPU::STQXr32; NewMI = addFrameReference(MIB, FrameIndex); diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index 92af973b0d2..c2b876403dc 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -291,14 +291,17 @@ foldMemoryOperandImpl(MachineFunction &MF, if (Ops[0] == 0) { // COPY -> STORE unsigned SrcReg = MI->getOperand(2).getReg(); bool isKill = MI->getOperand(2).isKill(); + bool isUndef = MI->getOperand(2).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::SW)) - .addReg(SrcReg, getKillRegState(isKill)) + .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) .addImm(0).addFrameIndex(FI); } else { // COPY -> LOAD unsigned DstReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::LW)) - .addReg(DstReg, RegState::Define | getDeadRegState(isDead)) + .addReg(DstReg, RegState::Define | getDeadRegState(isDead) | + getUndefRegState(isUndef)) .addImm(0).addFrameIndex(FI); } } @@ -321,14 +324,17 @@ foldMemoryOperandImpl(MachineFunction &MF, if (Ops[0] == 0) { // COPY -> STORE unsigned SrcReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(2).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(StoreOpc)) - .addReg(SrcReg, getKillRegState(isKill)) + .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) .addImm(0).addFrameIndex(FI) ; } else { // COPY -> LOAD unsigned DstReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(LoadOpc)) - .addReg(DstReg, RegState::Define | getDeadRegState(isDead)) + .addReg(DstReg, RegState::Define | getDeadRegState(isDead) | + getUndefRegState(isUndef)) .addImm(0).addFrameIndex(FI); } } diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 778f0349d10..0aafe22a84b 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -691,16 +691,21 @@ MachineInstr *PPCInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, if (OpNum == 0) { // move -> store unsigned InReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STW)) - .addReg(InReg, getKillRegState(isKill)), + .addReg(InReg, + getKillRegState(isKill) | + getUndefRegState(isUndef)), FrameIndex); } else { // move -> load unsigned OutReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LWZ)) .addReg(OutReg, RegState::Define | - getDeadRegState(isDead)), + getDeadRegState(isDead) | + getUndefRegState(isUndef)), FrameIndex); } } else if ((Opc == PPC::OR8 && @@ -708,48 +713,63 @@ MachineInstr *PPCInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, if (OpNum == 0) { // move -> store unsigned InReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STD)) - .addReg(InReg, getKillRegState(isKill)), + .addReg(InReg, + getKillRegState(isKill) | + getUndefRegState(isUndef)), FrameIndex); } else { // move -> load unsigned OutReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LD)) .addReg(OutReg, RegState::Define | - getDeadRegState(isDead)), + getDeadRegState(isDead) | + getUndefRegState(isUndef)), FrameIndex); } } else if (Opc == PPC::FMRD) { if (OpNum == 0) { // move -> store unsigned InReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFD)) - .addReg(InReg, getKillRegState(isKill)), + .addReg(InReg, + getKillRegState(isKill) | + getUndefRegState(isUndef)), FrameIndex); } else { // move -> load unsigned OutReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFD)) .addReg(OutReg, RegState::Define | - getDeadRegState(isDead)), + getDeadRegState(isDead) | + getUndefRegState(isUndef)), FrameIndex); } } else if (Opc == PPC::FMRS) { if (OpNum == 0) { // move -> store unsigned InReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFS)) - .addReg(InReg, getKillRegState(isKill)), + .addReg(InReg, + getKillRegState(isKill) | + getUndefRegState(isUndef)), FrameIndex); } else { // move -> load unsigned OutReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFS)) .addReg(OutReg, RegState::Define | - getDeadRegState(isDead)), + getDeadRegState(isDead) | + getUndefRegState(isUndef)), FrameIndex); } } diff --git a/lib/Target/Sparc/SparcInstrInfo.cpp b/lib/Target/Sparc/SparcInstrInfo.cpp index d2f6b9bdcb3..12c286af942 100644 --- a/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/lib/Target/Sparc/SparcInstrInfo.cpp @@ -256,17 +256,20 @@ MachineInstr *SparcInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, if (OpNum == 0) { // COPY -> STORE unsigned SrcReg = MI->getOperand(1).getReg(); bool isKill = MI->getOperand(1).isKill(); + bool isUndef = MI->getOperand(1).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(isFloat ? SP::STFri : SP::STDFri)) .addFrameIndex(FI) .addImm(0) - .addReg(SrcReg, getKillRegState(isKill)); + .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)); } else { // COPY -> LOAD unsigned DstReg = MI->getOperand(0).getReg(); bool isDead = MI->getOperand(0).isDead(); + bool isUndef = MI->getOperand(0).isUndef(); NewMI = BuildMI(MF, MI->getDebugLoc(), get(isFloat ? SP::LDFri : SP::LDDFri)) - .addReg(DstReg, RegState::Define | getDeadRegState(isDead)) + .addReg(DstReg, RegState::Define | + getDeadRegState(isDead) | getUndefRegState(isUndef)) .addFrameIndex(FI) .addImm(0); } diff --git a/test/CodeGen/ARM/2009-06-30-RegScavengerAssert3.ll b/test/CodeGen/ARM/2009-06-30-RegScavengerAssert3.ll new file mode 100644 index 00000000000..f94b59dc91b --- /dev/null +++ b/test/CodeGen/ARM/2009-06-30-RegScavengerAssert3.ll @@ -0,0 +1,128 @@ +; RUN: llvm-as < %s | llc -march=arm -mtriple=armv6-apple-darwin9 + +@JJ = external global i32* ; [#uses=1] + +define arm_apcscc void @SIM(i8* %A, i8* %B, i32 %M, i32 %N, i32 %K, [256 x i32]* %V, i32 %Q, i32 %R, i32 %nseq) nounwind { +entry: + br i1 undef, label %bb5, label %bb + +bb: ; preds = %bb, %entry + br label %bb + +bb5: ; preds = %entry + br i1 undef, label %bb6, label %bb8 + +bb6: ; preds = %bb6, %bb5 + br i1 undef, label %bb8, label %bb6 + +bb8: ; preds = %bb6, %bb5 + br label %bb15 + +bb9: ; preds = %bb15 + br i1 undef, label %bb10, label %bb11 + +bb10: ; preds = %bb9 + unreachable + +bb11: ; preds = %bb9 + br i1 undef, label %bb15, label %bb12 + +bb12: ; preds = %bb11 + %0 = load i32** @JJ, align 4 ; [#uses=1] + br label %bb228.i + +bb74.i: ; preds = %bb228.i + br i1 undef, label %bb138.i, label %bb145.i + +bb138.i: ; preds = %bb74.i + br label %bb145.i + +bb145.i: ; preds = %bb228.i, %bb138.i, %bb74.i + %cflag.0.i = phi i16 [ 0, %bb228.i ], [ 0, %bb74.i ], [ 1, %bb138.i ] ; [#uses=1] + br i1 undef, label %bb146.i, label %bb151.i + +bb146.i: ; preds = %bb145.i + br i1 undef, label %bb228.i, label %bb151.i + +bb151.i: ; preds = %bb146.i, %bb145.i + %.not297 = icmp ne i16 %cflag.0.i, 0 ; [#uses=1] + %or.cond298 = and i1 undef, %.not297 ; [#uses=1] + br i1 %or.cond298, label %bb153.i, label %bb228.i + +bb153.i: ; preds = %bb151.i + br i1 undef, label %bb220.i, label %bb.nph.i98 + +bb.nph.i98: ; preds = %bb153.i + br label %bb158.i + +bb158.i: ; preds = %bb218.i, %bb.nph.i98 + %c.1020.i = phi i32 [ 0, %bb.nph.i98 ], [ %c.14.i, %bb218.i ] ; [#uses=1] + %cflag.418.i = phi i16 [ 0, %bb.nph.i98 ], [ %cflag.3.i, %bb218.i ] ; [#uses=1] + %pj.317.i = phi i32 [ undef, %bb.nph.i98 ], [ %8, %bb218.i ] ; [#uses=1] + %pi.316.i = phi i32 [ undef, %bb.nph.i98 ], [ %7, %bb218.i ] ; [#uses=1] + %fj.515.i = phi i32 [ undef, %bb.nph.i98 ], [ %fj.4.i, %bb218.i ] ; [#uses=3] + %ci.910.i = phi i32 [ undef, %bb.nph.i98 ], [ %ci.12.i, %bb218.i ] ; [#uses=2] + %i.121.i = sub i32 undef, undef ; [#uses=3] + %tmp105.i = sub i32 undef, undef ; [#uses=1] + %1 = sub i32 %c.1020.i, undef ; [#uses=0] + br i1 undef, label %bb168.i, label %bb160.i + +bb160.i: ; preds = %bb158.i + br i1 undef, label %bb161.i, label %bb168.i + +bb161.i: ; preds = %bb160.i + br i1 undef, label %bb168.i, label %bb163.i + +bb163.i: ; preds = %bb161.i + %2 = icmp slt i32 %fj.515.i, undef ; [#uses=1] + %3 = and i1 %2, undef ; [#uses=1] + br i1 %3, label %bb167.i, label %bb168.i + +bb167.i: ; preds = %bb163.i + br label %bb168.i + +bb168.i: ; preds = %bb167.i, %bb163.i, %bb161.i, %bb160.i, %bb158.i + %fi.5.i = phi i32 [ undef, %bb167.i ], [ %ci.910.i, %bb158.i ], [ undef, %bb160.i ], [ %ci.910.i, %bb161.i ], [ undef, %bb163.i ] ; [#uses=1] + %fj.4.i = phi i32 [ undef, %bb167.i ], [ undef, %bb158.i ], [ %fj.515.i, %bb160.i ], [ undef, %bb161.i ], [ %fj.515.i, %bb163.i ] ; [#uses=2] + %scevgep88.i = getelementptr i32* null, i32 %i.121.i ; [#uses=3] + %4 = load i32* %scevgep88.i, align 4 ; [#uses=2] + %scevgep89.i = getelementptr i32* %0, i32 %i.121.i ; [#uses=3] + %5 = load i32* %scevgep89.i, align 4 ; [#uses=1] + %ci.10.i = select i1 undef, i32 %pi.316.i, i32 %i.121.i ; [#uses=0] + %cj.9.i = select i1 undef, i32 %pj.317.i, i32 undef ; [#uses=0] + %6 = icmp slt i32 undef, 0 ; [#uses=3] + %ci.12.i = select i1 %6, i32 %fi.5.i, i32 %4 ; [#uses=2] + %cj.11.i100 = select i1 %6, i32 %fj.4.i, i32 %5 ; [#uses=1] + %c.14.i = select i1 %6, i32 0, i32 undef ; [#uses=2] + store i32 %c.14.i, i32* undef, align 4 + %7 = load i32* %scevgep88.i, align 4 ; [#uses=1] + %8 = load i32* %scevgep89.i, align 4 ; [#uses=1] + store i32 %ci.12.i, i32* %scevgep88.i, align 4 + store i32 %cj.11.i100, i32* %scevgep89.i, align 4 + store i32 %4, i32* undef, align 4 + br i1 undef, label %bb211.i, label %bb218.i + +bb211.i: ; preds = %bb168.i + br label %bb218.i + +bb218.i: ; preds = %bb211.i, %bb168.i + %cflag.3.i = phi i16 [ %cflag.418.i, %bb168.i ], [ 1, %bb211.i ] ; [#uses=2] + %9 = icmp slt i32 %tmp105.i, undef ; [#uses=1] + br i1 %9, label %bb220.i, label %bb158.i + +bb220.i: ; preds = %bb218.i, %bb153.i + %cflag.4.lcssa.i = phi i16 [ 0, %bb153.i ], [ %cflag.3.i, %bb218.i ] ; [#uses=0] + br i1 undef, label %bb221.i, label %bb228.i + +bb221.i: ; preds = %bb220.i + br label %bb228.i + +bb228.i: ; preds = %bb221.i, %bb220.i, %bb151.i, %bb146.i, %bb12 + br i1 undef, label %bb74.i, label %bb145.i + +bb15: ; preds = %bb11, %bb8 + br i1 undef, label %return, label %bb9 + +return: ; preds = %bb15 + ret void +} diff --git a/test/CodeGen/ARM/2009-06-30-RegScavengerAssert4.ll b/test/CodeGen/ARM/2009-06-30-RegScavengerAssert4.ll new file mode 100644 index 00000000000..bca7f793eef --- /dev/null +++ b/test/CodeGen/ARM/2009-06-30-RegScavengerAssert4.ll @@ -0,0 +1,128 @@ +; RUN: llvm-as < %s | llc -march=arm -mtriple=armv6-apple-darwin9 + +@r = external global i32 ; [#uses=1] +@qr = external global i32 ; [#uses=1] +@II = external global i32* ; [#uses=1] +@no_mis = external global i32 ; [#uses=1] +@name1 = external global i8* ; [#uses=1] + +declare arm_apcscc void @diff(i8*, i8*, i32, i32, i32, i32) nounwind + +define arm_apcscc void @SIM(i8* %A, i8* %B, i32 %M, i32 %N, i32 %K, [256 x i32]* %V, i32 %Q, i32 %R, i32 %nseq) nounwind { +entry: + br i1 undef, label %bb5, label %bb + +bb: ; preds = %bb, %entry + br label %bb + +bb5: ; preds = %entry + br i1 undef, label %bb6, label %bb8 + +bb6: ; preds = %bb6, %bb5 + br i1 undef, label %bb8, label %bb6 + +bb8: ; preds = %bb6, %bb5 + %0 = load i8** @name1, align 4 ; [#uses=0] + br label %bb15 + +bb9: ; preds = %bb15 + br i1 undef, label %bb10, label %bb11 + +bb10: ; preds = %bb9 + unreachable + +bb11: ; preds = %bb9 + store i32 0, i32* @no_mis, align 4 + %1 = getelementptr i8* %A, i32 0 ; [#uses=1] + %2 = getelementptr i8* %B, i32 0 ; [#uses=1] + tail call arm_apcscc void @diff(i8* %1, i8* %2, i32 undef, i32 undef, i32 undef, i32 undef) nounwind + br i1 undef, label %bb15, label %bb12 + +bb12: ; preds = %bb11 + %3 = load i32** @II, align 4 ; [#uses=1] + %4 = load i32* @r, align 4 ; [#uses=1] + %5 = load i32* @qr, align 4 ; [#uses=1] + br label %bb228.i + +bb74.i: ; preds = %bb228.i + br i1 undef, label %bb138.i, label %bb145.i + +bb138.i: ; preds = %bb74.i + br label %bb145.i + +bb145.i: ; preds = %bb228.i, %bb138.i, %bb74.i + br i1 undef, label %bb146.i, label %bb151.i + +bb146.i: ; preds = %bb145.i + br i1 undef, label %bb228.i, label %bb151.i + +bb151.i: ; preds = %bb146.i, %bb145.i + br i1 undef, label %bb153.i, label %bb228.i + +bb153.i: ; preds = %bb151.i + %6 = add i32 undef, -1 ; [#uses=3] + br i1 undef, label %bb220.i, label %bb.nph.i98 + +bb.nph.i98: ; preds = %bb153.i + br label %bb158.i + +bb158.i: ; preds = %bb218.i, %bb.nph.i98 + %c.1020.i = phi i32 [ 0, %bb.nph.i98 ], [ %c.14.i, %bb218.i ] ; [#uses=1] + %f.419.i = phi i32 [ undef, %bb.nph.i98 ], [ %f.5.i, %bb218.i ] ; [#uses=1] + %pi.316.i = phi i32 [ undef, %bb.nph.i98 ], [ %10, %bb218.i ] ; [#uses=1] + %fj.515.i = phi i32 [ %6, %bb.nph.i98 ], [ %fj.4.i, %bb218.i ] ; [#uses=2] + %fi.614.i = phi i32 [ undef, %bb.nph.i98 ], [ %fi.5.i, %bb218.i ] ; [#uses=3] + %cj.811.i = phi i32 [ %6, %bb.nph.i98 ], [ %cj.11.i100, %bb218.i ] ; [#uses=3] + %ci.910.i = phi i32 [ undef, %bb.nph.i98 ], [ %ci.12.i, %bb218.i ] ; [#uses=2] + %7 = sub i32 %f.419.i, %4 ; [#uses=5] + %8 = sub i32 %c.1020.i, %5 ; [#uses=2] + %9 = icmp slt i32 %7, %8 ; [#uses=1] + br i1 %9, label %bb168.i, label %bb160.i + +bb160.i: ; preds = %bb158.i + br i1 undef, label %bb161.i, label %bb168.i + +bb161.i: ; preds = %bb160.i + br i1 undef, label %bb168.i, label %bb163.i + +bb163.i: ; preds = %bb161.i + br i1 undef, label %bb167.i, label %bb168.i + +bb167.i: ; preds = %bb163.i + br label %bb168.i + +bb168.i: ; preds = %bb167.i, %bb163.i, %bb161.i, %bb160.i, %bb158.i + %fi.5.i = phi i32 [ %fi.614.i, %bb167.i ], [ %ci.910.i, %bb158.i ], [ %fi.614.i, %bb160.i ], [ %ci.910.i, %bb161.i ], [ %fi.614.i, %bb163.i ] ; [#uses=2] + %fj.4.i = phi i32 [ %cj.811.i, %bb167.i ], [ %cj.811.i, %bb158.i ], [ %fj.515.i, %bb160.i ], [ %cj.811.i, %bb161.i ], [ %fj.515.i, %bb163.i ] ; [#uses=2] + %f.5.i = phi i32 [ %7, %bb167.i ], [ %8, %bb158.i ], [ %7, %bb160.i ], [ %7, %bb161.i ], [ %7, %bb163.i ] ; [#uses=2] + %scevgep88.i = getelementptr i32* %3, i32 undef ; [#uses=1] + %ci.10.i = select i1 undef, i32 %pi.316.i, i32 undef ; [#uses=0] + %ci.12.i = select i1 undef, i32 %fi.5.i, i32 undef ; [#uses=1] + %cj.11.i100 = select i1 undef, i32 %fj.4.i, i32 undef ; [#uses=1] + %c.14.i = select i1 undef, i32 %f.5.i, i32 undef ; [#uses=1] + %10 = load i32* %scevgep88.i, align 4 ; [#uses=1] + br i1 undef, label %bb211.i, label %bb218.i + +bb211.i: ; preds = %bb168.i + br label %bb218.i + +bb218.i: ; preds = %bb211.i, %bb168.i + br i1 undef, label %bb220.i, label %bb158.i + +bb220.i: ; preds = %bb218.i, %bb153.i + %11 = getelementptr i32* null, i32 %6 ; [#uses=1] + store i32 undef, i32* %11, align 4 + br i1 undef, label %bb221.i, label %bb228.i + +bb221.i: ; preds = %bb220.i + br label %bb228.i + +bb228.i: ; preds = %bb221.i, %bb220.i, %bb151.i, %bb146.i, %bb12 + br i1 undef, label %bb74.i, label %bb145.i + +bb15: ; preds = %bb11, %bb8 + br i1 undef, label %return, label %bb9 + +return: ; preds = %bb15 + ret void +}