summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp6
-rw-r--r--llvm/test/Transforms/Inline/inline-tail.ll21
2 files changed, 27 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index a90628f26fd..761c368508b 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1826,6 +1826,10 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
if (CallInst *CI = dyn_cast<CallInst>(TheCall))
CallSiteTailKind = CI->getTailCallKind();
+ // For inlining purposes, the "notail" marker is the same as no marker.
+ if (CallSiteTailKind == CallInst::TCK_NoTail)
+ CallSiteTailKind = CallInst::TCK_None;
+
for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E;
++BB) {
for (auto II = BB->begin(); II != BB->end();) {
@@ -1885,6 +1889,8 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
// f -> musttail g -> tail f ==> f -> tail f
// f -> g -> musttail f ==> f -> f
// f -> g -> tail f ==> f -> f
+ //
+ // Inlined notail calls should remain notail calls.
CallInst::TailCallKind ChildTCK = CI->getTailCallKind();
if (ChildTCK != CallInst::TCK_NoTail)
ChildTCK = std::min(CallSiteTailKind, ChildTCK);
diff --git a/llvm/test/Transforms/Inline/inline-tail.ll b/llvm/test/Transforms/Inline/inline-tail.ll
index 7b0fe57b68e..10b486c5154 100644
--- a/llvm/test/Transforms/Inline/inline-tail.ll
+++ b/llvm/test/Transforms/Inline/inline-tail.ll
@@ -196,3 +196,24 @@ define i32 @test_notail() {
%rv = tail call i32 @notail()
ret i32 %rv
}
+
+; PR31014: Inlining a musttail call through a notail call site should remove
+; any tail marking, otherwise we break verifier invariants.
+
+declare void @do_ret(i32)
+
+define void @test_notail_inline_musttail(i32 %a) {
+ notail call void @inline_musttail(i32 %a)
+ musttail call void @do_ret(i32 %a)
+ ret void
+}
+
+define internal void @inline_musttail(i32 %a) {
+ musttail call void @do_ret(i32 %a)
+ ret void
+}
+
+; CHECK-LABEL: define void @test_notail_inline_musttail(i32 %a)
+; CHECK: {{^ *}}call void @do_ret(i32 %a)
+; CHECK: musttail call void @do_ret(i32 %a)
+; CHECK: ret void
OpenPOWER on IntegriCloud