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:
parent
6491c8020e
commit
09a4201d3c
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue