]> granicus.if.org Git - llvm/commitdiff
Inliner: Don't touch indirect calls
authorDavid Blaikie <dblaikie@gmail.com>
Fri, 9 Jun 2017 03:29:20 +0000 (03:29 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Fri, 9 Jun 2017 03:29:20 +0000 (03:29 +0000)
Other comments/implications are that this isn't intended behavior (nor
perserved/reimplemented in the new inliner) & complicates fixing the
'inlining' of trivially dead calls without consulting the cost function
first.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305052 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/Inliner.cpp
test/Transforms/Inline/basictest.ll

index 673d3af0ab524ab51ed8ed8f8c9bc824844a7a10..c0dfeede05c5a8c7a425064dc468e0e9b9ac3e9e 100644 (file)
@@ -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,
index b98644cd2dd446d2b65bb8d0d6ee54f3e9343eed..f34ed08411326f43e26a4d67c3e07006eb72471b 100644 (file)
@@ -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
+}