Fix this assert. IP can point to an instruction with strange dominance

properties (invoke). Just assert that the instruction we return dominates
the insertion point.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151511 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2012-02-27 02:13:03 +00:00
parent 930a1ebd92
commit 23b6ec906a
2 changed files with 50 additions and 15 deletions

View File

@ -34,16 +34,15 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
// This function must be called with the builder having a valid insertion
// point. It doesn't need to be the actual IP where the uses of the returned
// cast will be added, but it must dominate such IP.
// We use this precondition to assert that we can produce a cast that will
// dominate all its uses. In particular, this is crucial for the case
// where the builder's insertion point *is* the point where we were asked
// to put the cast.
// We use this precondition to produce a cast that will dominate all its
// uses. In particular, this is crucial for the case where the builder's
// insertion point *is* the point where we were asked to put the cast.
// Since we don't know the the builder's insertion point is actually
// where the uses will be added (only that it dominates it), we are
// not allowed to move it.
BasicBlock::iterator BIP = Builder.GetInsertPoint();
assert(BIP == IP || SE.DT->dominates(IP, BIP));
Instruction *Ret = NULL;
// Check to see if there is already a cast!
for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
@ -59,22 +58,28 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
// Create a new cast, and leave the old cast in place in case
// it is being used as an insert point. Clear its operand
// so that it doesn't hold anything live.
Instruction *NewCI = CastInst::Create(Op, V, Ty, "", IP);
NewCI->takeName(CI);
CI->replaceAllUsesWith(NewCI);
Ret = CastInst::Create(Op, V, Ty, "", IP);
Ret->takeName(CI);
CI->replaceAllUsesWith(Ret);
CI->setOperand(0, UndefValue::get(V->getType()));
rememberInstruction(NewCI);
return NewCI;
break;
}
rememberInstruction(CI);
return CI;
Ret = CI;
break;
}
}
// Create a new cast.
Instruction *I = CastInst::Create(Op, V, Ty, V->getName(), IP);
rememberInstruction(I);
return I;
if (!Ret)
Ret = CastInst::Create(Op, V, Ty, V->getName(), IP);
// We assert at the end of the function since IP might point to an
// instruction with different dominance properties than a cast
// (an invoke for example) and not dominate BIP (but the cast does).
assert(SE.DT->dominates(Ret, BIP));
rememberInstruction(Ret);
return Ret;
}
/// InsertNoopCastOfTo - Insert a cast of V to the specified type,

View File

@ -38,3 +38,33 @@ bb8:
bb9:
resume { i8*, i32 } zeroinitializer
}
define void @h() {
bb1:
invoke void @g() optsize
to label %bb2 unwind label %bb5
bb2:
%arrayctor.cur = phi i8* [ undef, %bb1 ], [ %arrayctor.next, %bb3 ]
invoke void @g() optsize
to label %bb3 unwind label %bb6
bb3:
%arrayctor.next = getelementptr inbounds i8* %arrayctor.cur, i64 1
br label %bb2
bb4:
ret void
bb5:
%tmp = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
cleanup
invoke void @g() optsize
to label %bb4 unwind label %bb7
bb6:
%tmp1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
cleanup
%arraydestroy.isempty = icmp eq i8* undef, %arrayctor.cur
ret void
bb7:
%lpad.nonloopexit = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
catch i8* null
ret void
}