From e7c9195706ce17b5016f74005ecab5523519deea Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 25 Nov 2009 21:13:39 +0000 Subject: [PATCH] ProcessImplicitDefs should watch out for invalidated iterator and extra implicit operands on copies. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89880 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/ProcessImplicitDefs.cpp | 59 +++++++++++++++++++++------- test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll | 56 ++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll diff --git a/lib/CodeGen/ProcessImplicitDefs.cpp b/lib/CodeGen/ProcessImplicitDefs.cpp index 455964b5c5a..a484beccb9e 100644 --- a/lib/CodeGen/ProcessImplicitDefs.cpp +++ b/lib/CodeGen/ProcessImplicitDefs.cpp @@ -75,10 +75,11 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { SmallSet ImpDefRegs; SmallVector ImpDefMIs; - MachineBasicBlock *Entry = fn.begin(); + SmallVector RUses; SmallPtrSet Visited; SmallPtrSet ModInsts; + MachineBasicBlock *Entry = fn.begin(); for (df_ext_iterator > DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited); DFI != E; ++DFI) { @@ -197,38 +198,68 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { 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 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(); diff --git a/test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll b/test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll new file mode 100644 index 00000000000..9a22a6f76c2 --- /dev/null +++ b/test/CodeGen/PowerPC/2009-11-25-ImpDefBug.ll @@ -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 ; [#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 ] ; [#uses=1] + %fz.3 = phi i32 [ %fz.2, %bb32 ], [ 2147483647, %bb34 ], [ %fz.2, %bb33 ] ; [#uses=1] + %1 = add i32 undef, 1 ; [#uses=0] + br label %bb69 + +bb69: ; preds = %bb38, %bb17 + %fdgOuter.1 = phi i32 [ undef, %bb17 ], [ %fdgOuter.0, %bb38 ] ; [#uses=2] + %fz.2 = phi i32 [ undef, %bb17 ], [ %fz.3, %bb38 ] ; [#uses=2] + br i1 undef, label %bb24, label %return + +return: ; preds = %bb69, %bb28, %bb14, %entry + ret void +} -- 2.11.0