diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/IPO/Inliner.cpp | 8 | ||||
| -rw-r--r-- | llvm/test/Transforms/Inline/basictest.ll | 24 |
2 files changed, 28 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index 673d3af0ab5..c0dfeede05c 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -519,6 +519,10 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG, Function *Caller = CS.getCaller(); Function *Callee = CS.getCalledFunction(); + // We can only inline direct calls to non-declarations. + if (!Callee || Callee->isDeclaration()) + continue; + // If this call site is dead and it is to a readonly function, we should // just delete the call instead of trying to inline it, regardless of // size. This happens because IPSCCP propagates the result out of the @@ -531,10 +535,6 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG, CS.getInstruction()->eraseFromParent(); ++NumCallsDeleted; } else { - // We can only inline direct calls to non-declarations. - if (!Callee || Callee->isDeclaration()) - continue; - // If this call site was obtained by inlining another function, verify // that the include path for the function did not include the callee // itself. If so, we'd be recursively inlining the same function, diff --git a/llvm/test/Transforms/Inline/basictest.ll b/llvm/test/Transforms/Inline/basictest.ll index b98644cd2dd..f34ed084113 100644 --- a/llvm/test/Transforms/Inline/basictest.ll +++ b/llvm/test/Transforms/Inline/basictest.ll @@ -91,3 +91,27 @@ define i32 @test() { ret i32 %e ; CHECK: } } + +; Inliner shouldn't delete calls it can't inline, even if they're trivially dead +; CHECK-LABEL: @outer4( +define void @outer4(void ()* %inner4) { +entry: +; CHECK: call void %inner4() + call void %inner4() nounwind readnone + ret void +} + +declare void @inner5_inner() + +define void @inner5(void ()* %x) { + call void %x() nounwind readnone + ret void +} + +; Inliner shouldn't delete calls it can't inline, even if they're trivially dead and temporarily indirect +; CHECK-LABEL: @outer5( +define void @outer5() { +; CHECK: call void @inner5_inner( + call void @inner5(void ()* @inner5_inner) + ret void +} |

