From 5877ad7e90de2179c15914ff9e8f1c72152cac30 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 8 May 2009 00:22:04 +0000 Subject: [PATCH] PR4123: don't crash when inlining a call which uses its own result. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71199 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/InlineFunction.cpp | 13 +++++++++--- .../Inline/2009-05-07-CallUsingSelfCrash.ll | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index a8cba6b9a75..4989c00ceb8 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 00000000000..067fd72e939 --- /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) ; [#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 +} +