diff options
-rw-r--r-- | lib/Analysis/InstructionSimplify.cpp | 48 | ||||
-rw-r--r-- | test/Transforms/JumpThreading/crash.ll | 47 |
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 +} + + |