Handle IMPLICIT_DEF with isUndef operand marker, part 2. This patch moves the code...
authorEvan Cheng <evan.cheng@apple.com>
Wed, 1 Jul 2009 01:59:31 +0000 (01:59 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 1 Jul 2009 01:59:31 +0000 (01:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74580 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/llvm/CodeGen/LiveIntervalAnalysis.h
lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/RegAllocLinearScan.cpp
lib/CodeGen/RegisterScavenging.cpp
lib/CodeGen/VirtRegRewriter.cpp
lib/Target/ARM/ARMInstrInfo.cpp
lib/Target/Alpha/AlphaInstrInfo.cpp
lib/Target/CellSPU/SPUInstrInfo.cpp
lib/Target/Mips/MipsInstrInfo.cpp
lib/Target/PowerPC/PPCInstrInfo.cpp
lib/Target/Sparc/SparcInstrInfo.cpp
test/CodeGen/ARM/2009-06-30-RegScavengerAssert3.ll [new file with mode: 0644]
test/CodeGen/ARM/2009-06-30-RegScavengerAssert4.ll [new file with mode: 0644]

index 7c44cc7dbf28a64f74c4cc15612a53a6aff2fa19..7ae98bb093d6acb5e551c47fcebfe758b2f7e5a0 100644 (file)
@@ -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();
 
index b017f91e6a4b23310a91457555b692e510bdf442..9339c951a81588db1f55ad60dc3c8e353fc743c3 100644 (file)
@@ -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 <algorithm>
@@ -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<unsigned, 8> ImpDefRegs;
+  SmallVector<MachineInstr*, 8> ImpDefMIs;
+  MachineBasicBlock *Entry = mf_->begin();
+  SmallPtrSet<MachineBasicBlock*,16> Visited;
+  for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> >
+         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<IdxMBBPair> OldI2MBB = Idx2MBBMap;
@@ -299,6 +389,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
   lv_ = &getAnalysis<LiveVariables>();
   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);
         }
       }
     }
index 2caa2f9d18021c08380fbc00eb6de0b305749f6a..904b4cb2a46f8fe845cf33d384c92cfc9acac03c 100644 (file)
@@ -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<MachineBasicBlock*, 4> 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;
   }
 
index 382741ee73396caf53cfa68fe31511d54bbe425e..58f4284ac75503f4b44252b174d6080cc4d9d520 100644 (file)
@@ -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))
index bbf1e248731c738862423b2f0081c66c29d8d381..be0b016b669c02c42af3a36796e4c52ff4a453b6 100644 (file)
@@ -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<unsigned, 2> 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);
index 35ebb7eec86501419087d67ceeb20fa901bc1519..482867e6ec4c54a0bb580be16d646cab91c53af3 100644 (file)
@@ -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;
index 229f9d4784a46cd094e29643311bfb7c8467b3b6..203c7b15de901d56a6975c46945e4301a51d9301 100644 (file)
@@ -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);
        }
index 4af995a78139b5c622861d854a6213c277646773..e629c8d31aaf1112d297e9e8ac26b1bbb5d89780 100644 (file)
@@ -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);
index 92af973b0d214d197f822757815b9f2d910dfe93..c2b876403dc1b48028eaa2282e1cad1a6e0b5db4 100644 (file)
@@ -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);
       }
     }
index 778f0349d10f66af9df7d701cb41e2281d847ba2..0aafe22a84bf2af448546334e77deae358d47c7e 100644 (file)
@@ -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);
     }
   }
index d2f6b9bdcb3dbf142765bf1f6138f3edb32862f7..12c286af9428d773d39e6b987e3b32f173546c90 100644 (file)
@@ -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 (file)
index 0000000..f94b59d
--- /dev/null
@@ -0,0 +1,128 @@
+; RUN: llvm-as < %s | llc -march=arm -mtriple=armv6-apple-darwin9
+
+@JJ = external global i32*             ; <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            ; <i32*> [#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 ]           ; <i16> [#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            ; <i1> [#uses=1]
+       %or.cond298 = and i1 undef, %.not297            ; <i1> [#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 ]           ; <i32> [#uses=1]
+       %cflag.418.i = phi i16 [ 0, %bb.nph.i98 ], [ %cflag.3.i, %bb218.i ]             ; <i16> [#uses=1]
+       %pj.317.i = phi i32 [ undef, %bb.nph.i98 ], [ %8, %bb218.i ]            ; <i32> [#uses=1]
+       %pi.316.i = phi i32 [ undef, %bb.nph.i98 ], [ %7, %bb218.i ]            ; <i32> [#uses=1]
+       %fj.515.i = phi i32 [ undef, %bb.nph.i98 ], [ %fj.4.i, %bb218.i ]               ; <i32> [#uses=3]
+       %ci.910.i = phi i32 [ undef, %bb.nph.i98 ], [ %ci.12.i, %bb218.i ]              ; <i32> [#uses=2]
+       %i.121.i = sub i32 undef, undef         ; <i32> [#uses=3]
+       %tmp105.i = sub i32 undef, undef                ; <i32> [#uses=1]
+       %1 = sub i32 %c.1020.i, undef           ; <i32> [#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              ; <i1> [#uses=1]
+       %3 = and i1 %2, undef           ; <i1> [#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 ]               ; <i32> [#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 ]               ; <i32> [#uses=2]
+       %scevgep88.i = getelementptr i32* null, i32 %i.121.i            ; <i32*> [#uses=3]
+       %4 = load i32* %scevgep88.i, align 4            ; <i32> [#uses=2]
+       %scevgep89.i = getelementptr i32* %0, i32 %i.121.i              ; <i32*> [#uses=3]
+       %5 = load i32* %scevgep89.i, align 4            ; <i32> [#uses=1]
+       %ci.10.i = select i1 undef, i32 %pi.316.i, i32 %i.121.i         ; <i32> [#uses=0]
+       %cj.9.i = select i1 undef, i32 %pj.317.i, i32 undef             ; <i32> [#uses=0]
+       %6 = icmp slt i32 undef, 0              ; <i1> [#uses=3]
+       %ci.12.i = select i1 %6, i32 %fi.5.i, i32 %4            ; <i32> [#uses=2]
+       %cj.11.i100 = select i1 %6, i32 %fj.4.i, i32 %5         ; <i32> [#uses=1]
+       %c.14.i = select i1 %6, i32 0, i32 undef                ; <i32> [#uses=2]
+       store i32 %c.14.i, i32* undef, align 4
+       %7 = load i32* %scevgep88.i, align 4            ; <i32> [#uses=1]
+       %8 = load i32* %scevgep89.i, align 4            ; <i32> [#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 ]                ; <i16> [#uses=2]
+       %9 = icmp slt i32 %tmp105.i, undef              ; <i1> [#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 ]            ; <i16> [#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 (file)
index 0000000..bca7f79
--- /dev/null
@@ -0,0 +1,128 @@
+; RUN: llvm-as < %s | llc -march=arm -mtriple=armv6-apple-darwin9
+
+@r = external global i32               ; <i32*> [#uses=1]
+@qr = external global i32              ; <i32*> [#uses=1]
+@II = external global i32*             ; <i32**> [#uses=1]
+@no_mis = external global i32          ; <i32*> [#uses=1]
+@name1 = external global i8*           ; <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          ; <i8*> [#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                ; <i8*> [#uses=1]
+       %2 = getelementptr i8* %B, i32 0                ; <i8*> [#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            ; <i32*> [#uses=1]
+       %4 = load i32* @r, align 4              ; <i32> [#uses=1]
+       %5 = load i32* @qr, align 4             ; <i32> [#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          ; <i32> [#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 ]           ; <i32> [#uses=1]
+       %f.419.i = phi i32 [ undef, %bb.nph.i98 ], [ %f.5.i, %bb218.i ]         ; <i32> [#uses=1]
+       %pi.316.i = phi i32 [ undef, %bb.nph.i98 ], [ %10, %bb218.i ]           ; <i32> [#uses=1]
+       %fj.515.i = phi i32 [ %6, %bb.nph.i98 ], [ %fj.4.i, %bb218.i ]          ; <i32> [#uses=2]
+       %fi.614.i = phi i32 [ undef, %bb.nph.i98 ], [ %fi.5.i, %bb218.i ]               ; <i32> [#uses=3]
+       %cj.811.i = phi i32 [ %6, %bb.nph.i98 ], [ %cj.11.i100, %bb218.i ]              ; <i32> [#uses=3]
+       %ci.910.i = phi i32 [ undef, %bb.nph.i98 ], [ %ci.12.i, %bb218.i ]              ; <i32> [#uses=2]
+       %7 = sub i32 %f.419.i, %4               ; <i32> [#uses=5]
+       %8 = sub i32 %c.1020.i, %5              ; <i32> [#uses=2]
+       %9 = icmp slt i32 %7, %8                ; <i1> [#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 ]           ; <i32> [#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 ]           ; <i32> [#uses=2]
+       %f.5.i = phi i32 [ %7, %bb167.i ], [ %8, %bb158.i ], [ %7, %bb160.i ], [ %7, %bb161.i ], [ %7, %bb163.i ]               ; <i32> [#uses=2]
+       %scevgep88.i = getelementptr i32* %3, i32 undef         ; <i32*> [#uses=1]
+       %ci.10.i = select i1 undef, i32 %pi.316.i, i32 undef            ; <i32> [#uses=0]
+       %ci.12.i = select i1 undef, i32 %fi.5.i, i32 undef              ; <i32> [#uses=1]
+       %cj.11.i100 = select i1 undef, i32 %fj.4.i, i32 undef           ; <i32> [#uses=1]
+       %c.14.i = select i1 undef, i32 %f.5.i, i32 undef                ; <i32> [#uses=1]
+       %10 = load i32* %scevgep88.i, align 4           ; <i32> [#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           ; <i32*> [#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
+}