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.

llvm-svn: 151511
This commit is contained in:
Rafael Espindola 2012-02-27 02:13:03 +00:00
parent 6491c8020e
commit 09a4201d3c
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 // 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 // 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. // cast will be added, but it must dominate such IP.
// We use this precondition to assert that we can produce a cast that will // We use this precondition to produce a cast that will dominate all its
// dominate all its uses. In particular, this is crucial for the case // uses. In particular, this is crucial for the case where the builder's
// where the builder's insertion point *is* the point where we were asked // insertion point *is* the point where we were asked to put the cast.
// to put the cast.
// Since we don't know the the builder's insertion point is actually // 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 // where the uses will be added (only that it dominates it), we are
// not allowed to move it. // not allowed to move it.
BasicBlock::iterator BIP = Builder.GetInsertPoint(); 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! // Check to see if there is already a cast!
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); 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 // Create a new cast, and leave the old cast in place in case
// it is being used as an insert point. Clear its operand // it is being used as an insert point. Clear its operand
// so that it doesn't hold anything live. // so that it doesn't hold anything live.
Instruction *NewCI = CastInst::Create(Op, V, Ty, "", IP); Ret = CastInst::Create(Op, V, Ty, "", IP);
NewCI->takeName(CI); Ret->takeName(CI);
CI->replaceAllUsesWith(NewCI); CI->replaceAllUsesWith(Ret);
CI->setOperand(0, UndefValue::get(V->getType())); CI->setOperand(0, UndefValue::get(V->getType()));
rememberInstruction(NewCI); break;
return NewCI;
} }
rememberInstruction(CI); Ret = CI;
return CI; break;
} }
} }
// Create a new cast. // Create a new cast.
Instruction *I = CastInst::Create(Op, V, Ty, V->getName(), IP); if (!Ret)
rememberInstruction(I); Ret = CastInst::Create(Op, V, Ty, V->getName(), IP);
return I;
// 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, /// InsertNoopCastOfTo - Insert a cast of V to the specified type,

View File

@ -38,3 +38,33 @@ bb8:
bb9: bb9:
resume { i8*, i32 } zeroinitializer 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
}