[llvm-commits] [llvm] r89880 - in /llvm/trunk: lib/CodeGen/ProcessImplicitDefs.cpp test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll

Evan Cheng evan.cheng at apple.com
Wed Nov 25 13:13:39 PST 2009


Author: evancheng
Date: Wed Nov 25 15:13:39 2009
New Revision: 89880

URL: http://llvm.org/viewvc/llvm-project?rev=89880&view=rev
Log:
ProcessImplicitDefs should watch out for invalidated iterator and extra implicit operands on copies.

Added:
    llvm/trunk/test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll
Modified:
    llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp

Modified: llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp?rev=89880&r1=89879&r2=89880&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp (original)
+++ llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp Wed Nov 25 15:13:39 2009
@@ -75,10 +75,11 @@
 
   SmallSet<unsigned, 8> ImpDefRegs;
   SmallVector<MachineInstr*, 8> ImpDefMIs;
-  MachineBasicBlock *Entry = fn.begin();
+  SmallVector<MachineInstr*, 4> RUses;
   SmallPtrSet<MachineBasicBlock*,16> Visited;
   SmallPtrSet<MachineInstr*, 8> ModInsts;
 
+  MachineBasicBlock *Entry = fn.begin();
   for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> >
          DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
        DFI != E; ++DFI) {
@@ -197,38 +198,68 @@
       MI->eraseFromParent();
       Changed = true;
 
+      // Process each use instruction once.
       for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
-             UE = mri_->use_end(); UI != UE; ) {
-        MachineOperand &RMO = UI.getOperand();
+             UE = mri_->use_end(); UI != UE; ++UI) {
         MachineInstr *RMI = &*UI;
-        ++UI;
-        if (ModInsts.count(RMI))
-          continue;
         MachineBasicBlock *RMBB = RMI->getParent();
         if (RMBB == MBB)
           continue;
+        if (ModInsts.insert(RMI))
+          RUses.push_back(RMI);
+      }
+
+      for (unsigned i = 0, e = RUses.size(); i != e; ++i) {
+        MachineInstr *RMI = RUses[i];
 
         // Turn a copy use into an implicit_def.
         unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
         if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
             Reg == SrcReg) {
-          if (RMO.isKill()) {
+          RMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
+
+          bool isKill = false;
+          SmallVector<unsigned, 4> Ops;
+          for (unsigned j = 0, ee = RMI->getNumOperands(); j != ee; ++j) {
+            MachineOperand &RRMO = RMI->getOperand(j);
+            if (RRMO.isReg() && RRMO.getReg() == Reg) {
+              Ops.push_back(j);
+              if (RRMO.isKill())
+                isKill = true;
+            }
+          }
+          // Leave the other operands along.
+          for (unsigned j = 0, ee = Ops.size(); j != ee; ++j) {
+            unsigned OpIdx = Ops[j];
+            RMI->RemoveOperand(OpIdx-j);
+          }
+
+          // Update LiveVariables varinfo if the instruction is a kill.
+          if (isKill) {
             LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg);
             vi.removeKill(RMI);
           }
-          RMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
-          for (int j = RMI->getNumOperands() - 1, ee = 0; j > ee; --j)
-            RMI->RemoveOperand(j);
-          ModInsts.insert(RMI);
           continue;
         }
 
+        // Replace Reg with a new vreg that's marked implicit.
         const TargetRegisterClass* RC = mri_->getRegClass(Reg);
         unsigned NewVReg = mri_->createVirtualRegister(RC);
-        RMO.setReg(NewVReg);
-        RMO.setIsUndef();
-        RMO.setIsKill();
+        bool isKill = true;
+        for (unsigned j = 0, ee = RMI->getNumOperands(); j != ee; ++j) {
+          MachineOperand &RRMO = RMI->getOperand(j);
+          if (RRMO.isReg() && RRMO.getReg() == Reg) {
+            RRMO.setReg(NewVReg);
+            RRMO.setIsUndef();
+            if (isKill) {
+              // Only the first operand of NewVReg is marked kill.
+              RRMO.setIsKill();
+              isKill = false;
+            }
+          }
+        }
       }
+      RUses.clear();
     }
     ModInsts.clear();
     ImpDefRegs.clear();

Added: llvm/trunk/test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll?rev=89880&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll Wed Nov 25 15:13:39 2009
@@ -0,0 +1,56 @@
+; RUN: llc < %s -mtriple=powerpc-apple-darwin9.5 -mcpu=g5
+; rdar://7422268
+
+%struct..0EdgeT = type { i32, i32, float, float, i32, i32, i32, float, i32, i32 }
+
+define void @smooth_color_z_triangle(i32 %v0, i32 %v1, i32 %v2, i32 %pv) nounwind {
+entry:
+  br i1 undef, label %return, label %bb14
+
+bb14:                                             ; preds = %entry
+  br i1 undef, label %bb15, label %return
+
+bb15:                                             ; preds = %bb14
+  br i1 undef, label %bb16, label %bb17
+
+bb16:                                             ; preds = %bb15
+  br label %bb17
+
+bb17:                                             ; preds = %bb16, %bb15
+  %0 = fcmp olt float undef, 0.000000e+00         ; <i1> [#uses=2]
+  %eTop.eMaj = select i1 %0, %struct..0EdgeT* undef, %struct..0EdgeT* null ; <%struct..0EdgeT*> [#uses=1]
+  br label %bb69
+
+bb24:                                             ; preds = %bb69
+  br i1 undef, label %bb25, label %bb28
+
+bb25:                                             ; preds = %bb24
+  br label %bb33
+
+bb28:                                             ; preds = %bb24
+  br i1 undef, label %return, label %bb32
+
+bb32:                                             ; preds = %bb28
+  br i1 %0, label %bb38, label %bb33
+
+bb33:                                             ; preds = %bb32, %bb25
+  br i1 undef, label %bb34, label %bb38
+
+bb34:                                             ; preds = %bb33
+  br label %bb38
+
+bb38:                                             ; preds = %bb34, %bb33, %bb32
+  %eRight.08 = phi %struct..0EdgeT* [ %eTop.eMaj, %bb32 ], [ undef, %bb34 ], [ undef, %bb33 ] ; <%struct..0EdgeT*> [#uses=0]
+  %fdgOuter.0 = phi i32 [ %fdgOuter.1, %bb32 ], [ undef, %bb34 ], [ %fdgOuter.1, %bb33 ] ; <i32> [#uses=1]
+  %fz.3 = phi i32 [ %fz.2, %bb32 ], [ 2147483647, %bb34 ], [ %fz.2, %bb33 ] ; <i32> [#uses=1]
+  %1 = add i32 undef, 1                           ; <i32> [#uses=0]
+  br label %bb69
+
+bb69:                                             ; preds = %bb38, %bb17
+  %fdgOuter.1 = phi i32 [ undef, %bb17 ], [ %fdgOuter.0, %bb38 ] ; <i32> [#uses=2]
+  %fz.2 = phi i32 [ undef, %bb17 ], [ %fz.3, %bb38 ] ; <i32> [#uses=2]
+  br i1 undef, label %bb24, label %return
+
+return:                                           ; preds = %bb69, %bb28, %bb14, %entry
+  ret void
+}





More information about the llvm-commits mailing list