aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/InstructionSimplify.cpp48
-rw-r--r--test/Transforms/JumpThreading/crash.ll47
2 files changed, 81 insertions, 14 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index dbefc2d..24cd343 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -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();
}
diff --git a/test/Transforms/JumpThreading/crash.ll b/test/Transforms/JumpThreading/crash.ll
index 480b4a0..f0fc61e 100644
--- a/test/Transforms/JumpThreading/crash.ll
+++ b/test/Transforms/JumpThreading/crash.ll
@@ -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
+}
+
+