diff options
-rw-r--r-- | lib/Transforms/Utils/InlineFunction.cpp | 13 | ||||
-rw-r--r-- | test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll | 20 |
2 files changed, 30 insertions, 3 deletions
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index a8cba6b..4989c00 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -516,7 +516,10 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) { // uses of the returned value. if (!TheCall->use_empty()) { ReturnInst *R = Returns[0]; - TheCall->replaceAllUsesWith(R->getReturnValue()); + if (TheCall == R->getReturnValue()) + TheCall->replaceAllUsesWith(UndefValue::get(TheCall->getType())); + else + TheCall->replaceAllUsesWith(R->getReturnValue()); } // Since we are now done with the Call/Invoke, we can delete it. TheCall->eraseFromParent(); @@ -605,8 +608,12 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) { } else if (!Returns.empty()) { // Otherwise, if there is exactly one return value, just replace anything // using the return value of the call with the computed value. - if (!TheCall->use_empty()) - TheCall->replaceAllUsesWith(Returns[0]->getReturnValue()); + if (!TheCall->use_empty()) { + if (TheCall == Returns[0]->getReturnValue()) + TheCall->replaceAllUsesWith(UndefValue::get(TheCall->getType())); + else + TheCall->replaceAllUsesWith(Returns[0]->getReturnValue()); + } // Splice the code from the return block into the block that it will return // to, which contains the code that was after the call. diff --git a/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll b/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll new file mode 100644 index 0000000..067fd72 --- /dev/null +++ b/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | opt -inline -disable-output +; PR4123 + %struct.S0 = type <{ i32 }> + %struct.S1 = type <{ i8, i8, i8, i8, %struct.S0 }> + %struct.S2 = type <{ %struct.S1, i32 }> + +define void @func_113(%struct.S1* noalias nocapture sret %agg.result, i8 signext %p_114) noreturn nounwind { +entry: + unreachable + +for.inc: ; preds = %for.inc + %call48 = call fastcc signext i8 @safe_sub_func_uint8_t_u_u(i8 signext %call48) ; <i8> [#uses=1] + br label %for.inc +} + +define fastcc signext i8 @safe_sub_func_uint8_t_u_u(i8 signext %_ui1) nounwind readnone { +entry: + ret i8 %_ui1 +} + |