mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-24 20:44:51 +00:00
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:
parent
63cfa4b8e0
commit
2b2265a9c5
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user