Inliner: Don't mark notail calls with the 'tail' attribute
authorArnold Schwaighofer <aschwaighofer@apple.com>
Mon, 27 Nov 2017 19:03:40 +0000 (19:03 +0000)
committerArnold Schwaighofer <aschwaighofer@apple.com>
Mon, 27 Nov 2017 19:03:40 +0000 (19:03 +0000)
enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2,
                    TCK_NoTail = 3 };

TCK_NoTail is greater than TCK_Tail so taking the min does not do the
correct thing.

rdar://35639547

llvm-svn: 319075

llvm/lib/Transforms/Utils/InlineFunction.cpp
llvm/test/Transforms/Inline/inline-tail.ll

index 23a72e8..15a8bf2 100644 (file)
@@ -1850,7 +1850,8 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
         //    f ->          g -> musttail f  ==>  f ->          f
         //    f ->          g ->     tail f  ==>  f ->          f
         CallInst::TailCallKind ChildTCK = CI->getTailCallKind();
-        ChildTCK = std::min(CallSiteTailKind, ChildTCK);
+        if (ChildTCK != CallInst::TCK_NoTail)
+          ChildTCK = std::min(CallSiteTailKind, ChildTCK);
         CI->setTailCallKind(ChildTCK);
         InlinedMustTailCalls |= CI->isMustTailCall();
 
index 66a6be7..7b0fe57 100644 (file)
@@ -181,3 +181,18 @@ define i32 @test_mixedret_a(i1 zeroext %b) {
   %rv = musttail call i32 @test_mixedret_b(i1 zeroext %b)
   ret i32 %rv
 }
+
+declare i32 @donttailcall()
+
+define i32 @notail() {
+  %rv = notail call i32 @donttailcall()
+  ret i32 %rv
+}
+
+; CHECK: @test_notail
+; CHECK: notail call i32 @donttailcall
+; CHECK: ret
+define i32 @test_notail() {
+  %rv = tail call i32 @notail()
+  ret i32 %rv
+}