Short term fix for pr12270 before we change dominates to handle unreachable

code.
While here, reduce indentation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152803 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2012-03-15 15:52:59 +00:00
parent 847d3812ad
commit 2453dff96a
2 changed files with 48 additions and 29 deletions

View File

@ -4024,36 +4024,40 @@ bool ObjCARCContract::runOnFunction(Function &F) {
Use &U = UI.getUse();
unsigned OperandNo = UI.getOperandNo();
++UI; // Increment UI now, because we may unlink its element.
if (Instruction *UserInst = dyn_cast<Instruction>(U.getUser()))
if (Inst != UserInst && DT->dominates(Inst, UserInst)) {
Changed = true;
Instruction *Replacement = Inst;
Type *UseTy = U.get()->getType();
if (PHINode *PHI = dyn_cast<PHINode>(UserInst)) {
// For PHI nodes, insert the bitcast in the predecessor block.
unsigned ValNo =
PHINode::getIncomingValueNumForOperand(OperandNo);
BasicBlock *BB =
PHI->getIncomingBlock(ValNo);
if (Replacement->getType() != UseTy)
Replacement = new BitCastInst(Replacement, UseTy, "",
&BB->back());
for (unsigned i = 0, e = PHI->getNumIncomingValues();
i != e; ++i)
if (PHI->getIncomingBlock(i) == BB) {
// Keep the UI iterator valid.
if (&PHI->getOperandUse(
PHINode::getOperandNumForIncomingValue(i)) ==
&UI.getUse())
++UI;
PHI->setIncomingValue(i, Replacement);
}
} else {
if (Replacement->getType() != UseTy)
Replacement = new BitCastInst(Replacement, UseTy, "", UserInst);
U.set(Replacement);
}
Instruction *UserInst = dyn_cast<Instruction>(U.getUser());
if (!UserInst)
continue;
// FIXME: dominates should return true for unreachable UserInst.
if (!DT->isReachableFromEntry(UserInst->getParent()) ||
DT->dominates(Inst, UserInst)) {
Changed = true;
Instruction *Replacement = Inst;
Type *UseTy = U.get()->getType();
if (PHINode *PHI = dyn_cast<PHINode>(UserInst)) {
// For PHI nodes, insert the bitcast in the predecessor block.
unsigned ValNo =
PHINode::getIncomingValueNumForOperand(OperandNo);
BasicBlock *BB =
PHI->getIncomingBlock(ValNo);
if (Replacement->getType() != UseTy)
Replacement = new BitCastInst(Replacement, UseTy, "",
&BB->back());
for (unsigned i = 0, e = PHI->getNumIncomingValues();
i != e; ++i)
if (PHI->getIncomingBlock(i) == BB) {
// Keep the UI iterator valid.
if (&PHI->getOperandUse(
PHINode::getOperandNumForIncomingValue(i)) ==
&UI.getUse())
++UI;
PHI->setIncomingValue(i, Replacement);
}
} else {
if (Replacement->getType() != UseTy)
Replacement = new BitCastInst(Replacement, UseTy, "", UserInst);
U.set(Replacement);
}
}
}
// If Arg is a no-op casted pointer, strip one level of casts and

View File

@ -0,0 +1,15 @@
; RUN: opt -disable-output -objc-arc-contract %s
; test that we don't crash on unreachable code
%2 = type opaque
define void @_i_Test__foo(%2 *%x) {
entry:
unreachable
return: ; No predecessors!
%bar = bitcast %2* %x to i8*
%foo = call i8* @objc_autoreleaseReturnValue(i8* %bar) nounwind
ret void
}
declare i8* @objc_autoreleaseReturnValue(i8*)