Fix PR7647, handling the case when 'To' ends up being

mutated by recursive simplification.  This also enhances
ReplaceAndSimplifyAllUses to actually do a real RAUW
at the end of it, which updates any value handles
pointing to "From" to start pointing to "To".  This
seems useful for debug info and random other VH users.

llvm-svn: 108415
This commit is contained in:
Chris Lattner 2010-07-15 06:36:08 +00:00
parent e41ab07c61
commit 19eff2a9f6
2 changed files with 81 additions and 14 deletions

View File

@ -440,27 +440,47 @@ void llvm::ReplaceAndSimplifyAllUses(Instruction *From, Value *To,
const TargetData *TD) {
assert(From != To && "ReplaceAndSimplifyAllUses(X,X) is not valid!");
// FromHandle - This keeps a weakvh on the from value so that we can know if
// it gets deleted out from under us in a recursive simplification.
// FromHandle/ToHandle - This keeps a WeakVH on the from/to values so that
// we can know if it gets deleted out from under us or replaced in a
// recursive simplification.
WeakVH FromHandle(From);
WeakVH ToHandle(To);
while (!From->use_empty()) {
// Update the instruction to use the new value.
Use &U = From->use_begin().getUse();
Instruction *User = cast<Instruction>(U.getUser());
U = To;
Use &TheUse = From->use_begin().getUse();
Instruction *User = cast<Instruction>(TheUse.getUser());
TheUse = To;
// Check to see if the instruction can be folded due to the operand
// replacement. For example changing (or X, Y) into (or X, -1) can replace
// the 'or' with -1.
Value *SimplifiedVal;
{
// Sanity check to make sure 'User' doesn't dangle across
// SimplifyInstruction.
AssertingVH<> UserHandle(User);
// See if we can simplify it.
if (Value *V = SimplifyInstruction(User, TD)) {
// Recursively simplify this.
ReplaceAndSimplifyAllUses(User, V, TD);
// If the recursive simplification ended up revisiting and deleting 'From'
// then we're done.
if (FromHandle == 0)
return;
SimplifiedVal = SimplifyInstruction(User, TD);
if (SimplifiedVal == 0) continue;
}
// Recursively simplify this user to the new value.
ReplaceAndSimplifyAllUses(User, SimplifiedVal, TD);
From = dyn_cast_or_null<Instruction>((Value*)FromHandle);
To = ToHandle;
assert(ToHandle && "To value deleted by recursive simplification?");
// If the recursive simplification ended up revisiting and deleting
// 'From' then we're done.
if (From == 0)
return;
}
// If 'From' has value handles referring to it, do a real RAUW to update them.
From->replaceAllUsesWith(To);
From->eraseFromParent();
}

View File

@ -387,3 +387,50 @@ if.end: ; preds = %land.end69
ret void
}
; PR7647
define void @test15() nounwind {
entry:
ret void
if.then237:
br label %lbl_664
lbl_596: ; preds = %lbl_664, %for.end37
volatile store i64 undef, i64* undef, align 4
br label %for.cond111
for.cond111: ; preds = %safe_sub_func_int64_t_s_s.exit, %lbl_596
%storemerge = phi i8 [ undef, %cond.true.i100 ], [ 22, %lbl_596 ] ; <i8> [#uses=1]
%l_678.5 = phi i64 [ %l_678.3, %cond.true.i100 ], [ undef, %lbl_596 ] ; <i64> [#uses=2]
%cmp114 = icmp slt i8 %storemerge, -2 ; <i1> [#uses=1]
br i1 %cmp114, label %lbl_664, label %if.end949
lbl_664: ; preds = %for.end1058, %if.then237, %for.cond111
%l_678.3 = phi i64 [ %l_678.5, %for.cond111 ], [ %l_678.2, %for.cond1035 ], [ 5, %if.then237 ] ; <i64> [#uses=1]
%tobool118 = icmp eq i32 undef, 0 ; <i1> [#uses=1]
br i1 %tobool118, label %cond.true.i100, label %lbl_596
cond.true.i100: ; preds = %for.inc120
br label %for.cond111
lbl_709:
br label %if.end949
for.cond603: ; preds = %for.body607, %if.end336
br i1 undef, label %for.cond603, label %if.end949
if.end949: ; preds = %for.cond603, %lbl_709, %for.cond111
%l_678.2 = phi i64 [ %l_678.5, %for.cond111 ], [ undef, %lbl_709 ], [ 5, %for.cond603 ] ; <i64> [#uses=1]
br label %for.body1016
for.body1016: ; preds = %for.cond1012
br label %for.body1016
for.cond1035: ; preds = %for.inc1055, %if.then1026
br i1 undef, label %for.cond1040, label %lbl_664
for.cond1040: ; preds = %for.body1044, %for.cond1035
ret void
}