diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2009-05-08 00:22:04 +0000 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2009-05-08 00:22:04 +0000 |
| commit | 36b9026fa71334dbc71cbaecd96990e21488c009 (patch) | |
| tree | 8637b96d5118d73a2b2311eeb8050fe2f14bc31b | |
| parent | b6e9eb695601b3cb39ab88317aa6fd6d304f4c6e (diff) | |
| download | bcm5719-llvm-36b9026fa71334dbc71cbaecd96990e21488c009.tar.gz bcm5719-llvm-36b9026fa71334dbc71cbaecd96990e21488c009.zip | |
PR4123: don't crash when inlining a call which uses its own result.
llvm-svn: 71199
| -rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 13 | ||||
| -rw-r--r-- | llvm/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll | 20 |
2 files changed, 30 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index a8cba6b9a75..4989c00ceb8 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/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/llvm/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll b/llvm/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll new file mode 100644 index 00000000000..067fd72e939 --- /dev/null +++ b/llvm/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 +} + |

