[llvm] Revert "Remove the optional bitcast between a musttail call and its ret" (PR #201479)

Florian Mayer via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 3 16:47:28 PDT 2026


https://github.com/fmayer created https://github.com/llvm/llvm-project/pull/201479

This broke MSan on the buildbots: https://lab.llvm.org/buildbot/#/builders/169/builds/23291/steps/10/logs/stdio

This is the only change in the batch that touched BitcodeReader

>From 5be046268f78dc1eef49a080228aadaf506b44ff Mon Sep 17 00:00:00 2001
From: Florian Mayer <florian.mayer at bitsrc.org>
Date: Wed, 3 Jun 2026 16:46:48 -0700
Subject: [PATCH] =?UTF-8?q?Revert=20"Remove=20the=20optional=20bitcast=20b?=
 =?UTF-8?q?etween=20a=20musttail=20call=20and=20its=20ret=20(#201=E2=80=A6?=
 =?UTF-8?q?"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit 91b00526a599fa21e43da82438f1e9c8a8e1b7b3.
---
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp     |  13 ------
 llvm/lib/IR/BasicBlock.cpp                    |   8 ++++
 llvm/lib/IR/Verifier.cpp                      |  43 ++++++++++++++----
 llvm/lib/Transforms/Utils/InlineFunction.cpp  |  23 +++++++++-
 llvm/test/Bitcode/musttail-bitcast-upgrade.ll |  32 -------------
 .../Bitcode/musttail-bitcast-upgrade.ll.bc    | Bin 1972 -> 0 bytes
 .../AddressSanitizer/musttail.ll              |  14 ++++++
 .../ThreadSanitizer/tsan_musttail.ll          |  13 ++++++
 .../Transforms/CallSiteSplitting/musttail.ll  |  24 ++++++++++
 .../test/Transforms/SafeStack/X86/musttail.ll |  19 ++++++++
 llvm/test/Verifier/musttail-invalid.ll        |   2 +-
 11 files changed, 134 insertions(+), 57 deletions(-)
 delete mode 100644 llvm/test/Bitcode/musttail-bitcast-upgrade.ll
 delete mode 100644 llvm/test/Bitcode/musttail-bitcast-upgrade.ll.bc

diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 4df54f259ad10..3e863f4786e1a 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -7149,19 +7149,6 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
           UpgradeIntrinsicCall(CI, It->second);
       }
     }
-
-    // Old bitcode allowed an optional bitcast between a musttail call and its
-    // return. Under opaque pointers that cast is always a no-op, and the
-    // verifier no longer accepts it, so drop it.
-    if (auto *BC = dyn_cast<BitCastInst>(&I);
-        BC && BC->getSrcTy() == BC->getDestTy() &&
-        isa_and_nonnull<ReturnInst>(BC->getNextNode())) {
-      if (auto *CI = dyn_cast<CallInst>(BC->getOperand(0));
-          CI && CI->isMustTailCall() && CI->getNextNode() == BC) {
-        BC->replaceAllUsesWith(CI);
-        BC->eraseFromParent();
-      }
-    }
   }
 
   // Look for functions that rely on old function attribute behavior.
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index 03e38b3b89061..d611e9c2d0a96 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -239,6 +239,14 @@ const CallInst *BasicBlock::getTerminatingMustTailCall() const {
   if (Value *RV = RI->getReturnValue()) {
     if (RV != Prev)
       return nullptr;
+
+    // Look through the optional bitcast.
+    if (auto *BI = dyn_cast<BitCastInst>(Prev)) {
+      RV = BI->getOperand(0);
+      Prev = BI->getPrevNode();
+      if (!Prev || RV != Prev)
+        return nullptr;
+    }
   }
 
   if (auto *CI = dyn_cast<CallInst>(Prev)) {
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 344314e39c38a..c9639d1420bfc 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4246,6 +4246,18 @@ void Verifier::verifyTailCCMustTailAttrs(const AttrBuilder &Attrs,
         Twine("byref attribute not allowed in ") + Context);
 }
 
+/// Two types are "congruent" if they are identical, or if they are both pointer
+/// types with different pointee types and the same address space.
+static bool isTypeCongruent(Type *L, Type *R) {
+  if (L == R)
+    return true;
+  PointerType *PL = dyn_cast<PointerType>(L);
+  PointerType *PR = dyn_cast<PointerType>(R);
+  if (!PL || !PR)
+    return false;
+  return PL->getAddressSpace() == PR->getAddressSpace();
+}
+
 static AttrBuilder getParameterABIAttributes(LLVMContext& C, unsigned I, AttributeList Attrs) {
   static const Attribute::AttrKind ABIAttrs[] = {
       Attribute::StructRet,  Attribute::ByVal,          Attribute::InAlloca,
@@ -4275,21 +4287,32 @@ void Verifier::verifyMustTailCall(CallInst &CI) {
   FunctionType *CalleeTy = CI.getFunctionType();
   Check(CallerTy->isVarArg() == CalleeTy->isVarArg(),
         "cannot guarantee tail call due to mismatched varargs", &CI);
-  Check(CallerTy->getReturnType() == CalleeTy->getReturnType(),
+  Check(isTypeCongruent(CallerTy->getReturnType(), CalleeTy->getReturnType()),
         "cannot guarantee tail call due to mismatched return types", &CI);
 
   // - The calling conventions of the caller and callee must match.
   Check(F->getCallingConv() == CI.getCallingConv(),
         "cannot guarantee tail call due to mismatched calling conv", &CI);
 
-  // - The call must immediately precede a :ref:`ret <i_ret>` instruction.
-  // - The ret instruction must return the value produced by the call or void.
+  // - The call must immediately precede a :ref:`ret <i_ret>` instruction,
+  //   or a pointer bitcast followed by a ret instruction.
+  // - The ret instruction must return the (possibly bitcasted) value
+  //   produced by the call or void.
+  Value *RetVal = &CI;
   Instruction *Next = CI.getNextNode();
 
+  // Handle the optional bitcast.
+  if (BitCastInst *BI = dyn_cast_or_null<BitCastInst>(Next)) {
+    Check(BI->getOperand(0) == RetVal,
+          "bitcast following musttail call must use the call", BI);
+    RetVal = BI;
+    Next = BI->getNextNode();
+  }
+
   // Check the return.
   ReturnInst *Ret = dyn_cast_or_null<ReturnInst>(Next);
-  Check(Ret, "musttail call must precede a ret", &CI);
-  Check(!Ret->getReturnValue() || Ret->getReturnValue() == &CI ||
+  Check(Ret, "musttail call must precede a ret with an optional bitcast", &CI);
+  Check(!Ret->getReturnValue() || Ret->getReturnValue() == RetVal ||
             isa<UndefValue>(Ret->getReturnValue()),
         "musttail call result must be returned", Ret);
 
@@ -4318,14 +4341,16 @@ void Verifier::verifyMustTailCall(CallInst &CI) {
     return;
   }
 
-  // - The caller and callee prototypes must match.
+  // - The caller and callee prototypes must match.  Pointer types of
+  //   parameters or return types may differ in pointee type, but not
+  //   address space.
   if (!CI.getIntrinsicID()) {
     Check(CallerTy->getNumParams() == CalleeTy->getNumParams(),
           "cannot guarantee tail call due to mismatched parameter counts", &CI);
     for (unsigned I = 0, E = CallerTy->getNumParams(); I != E; ++I) {
-      Check(CallerTy->getParamType(I) == CalleeTy->getParamType(I),
-            "cannot guarantee tail call due to mismatched parameter types",
-            &CI);
+      Check(
+          isTypeCongruent(CallerTy->getParamType(I), CalleeTy->getParamType(I)),
+          "cannot guarantee tail call due to mismatched parameter types", &CI);
     }
   }
 
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index be186ffbf7e42..1d3f66509b1c5 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -3300,13 +3300,32 @@ void llvm::InlineFunctionImpl(CallBase &CB, InlineFunctionInfo &IFI,
   // musttail.  Therefore it's safe to return without merging control into the
   // phi below.
   if (InlinedMustTailCalls) {
+    // Check if we need to bitcast the result of any musttail calls.
+    Type *NewRetTy = Caller->getReturnType();
+    bool NeedBitCast = !CB.use_empty() && CB.getType() != NewRetTy;
+
     // Handle the returns preceded by musttail calls separately.
     SmallVector<ReturnInst *, 8> NormalReturns;
     for (ReturnInst *RI : Returns) {
       CallInst *ReturnedMustTail =
           RI->getParent()->getTerminatingMustTailCall();
-      if (!ReturnedMustTail)
+      if (!ReturnedMustTail) {
         NormalReturns.push_back(RI);
+        continue;
+      }
+      if (!NeedBitCast)
+        continue;
+
+      // Delete the old return and any preceding bitcast.
+      BasicBlock *CurBB = RI->getParent();
+      auto *OldCast = dyn_cast_or_null<BitCastInst>(RI->getReturnValue());
+      RI->eraseFromParent();
+      if (OldCast)
+        OldCast->eraseFromParent();
+
+      // Insert a new bitcast and return with the right type.
+      IRBuilder<> Builder(CurBB);
+      Builder.CreateRet(Builder.CreateBitCast(ReturnedMustTail, NewRetTy));
     }
 
     // Leave behind the normal returns so we can merge control flow.
@@ -3528,7 +3547,7 @@ void llvm::InlineFunctionImpl(CallBase &CB, InlineFunctionInfo &IFI,
   CB.eraseFromParent();
 
   // If we inlined any musttail calls and the original return is now
-  // unreachable, delete it.  It can only contain a ret.
+  // unreachable, delete it.  It can only contain a bitcast and ret.
   if (InlinedMustTailCalls && pred_empty(AfterCallBB))
     AfterCallBB->eraseFromParent();
 
diff --git a/llvm/test/Bitcode/musttail-bitcast-upgrade.ll b/llvm/test/Bitcode/musttail-bitcast-upgrade.ll
deleted file mode 100644
index 63c24778a067c..0000000000000
--- a/llvm/test/Bitcode/musttail-bitcast-upgrade.ll
+++ /dev/null
@@ -1,32 +0,0 @@
-; RUN: llvm-dis %s.bc -o - | FileCheck %s
-; RUN: verify-uselistorder %s.bc
-
-; musttail-bitcast-upgrade.ll.bc was produced from the IR below using an
-; llvm-as that still emitted the optional no-op bitcast between a musttail call
-; and its return. The reader must drop that bitcast so the module verifies.
-
-; CHECK-LABEL: define ptr @caller(ptr %a)
-; CHECK-NEXT:    %c = musttail call ptr @callee(ptr %a)
-; CHECK-NEXT:    ret ptr %c
-
-define ptr @callee(ptr %a) {
-  ret ptr %a
-}
-
-define ptr @caller(ptr %a) {
-  %c = musttail call ptr @callee(ptr %a)
-  %b = bitcast ptr %c to ptr
-  ret ptr %b
-}
-
-; CHECK-LABEL: define i32 @caller_i32(ptr %a)
-; CHECK-NEXT:    %c = musttail call i32 @callee_i32(ptr %a)
-; CHECK-NEXT:    ret i32 %c
-
-declare i32 @callee_i32(ptr %a)
-
-define i32 @caller_i32(ptr %a) {
-  %c = musttail call i32 @callee_i32(ptr %a)
-  %b = bitcast i32 %c to i32
-  ret i32 %b
-}
diff --git a/llvm/test/Bitcode/musttail-bitcast-upgrade.ll.bc b/llvm/test/Bitcode/musttail-bitcast-upgrade.ll.bc
deleted file mode 100644
index 57c6bade7ebfe6dbef26baa950c85482fae4d365..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1972
zcmZ`)eM}qY8Gr4=K9 at M}T_RTO=Fam4T3K5 at ZYF8Y*p{#_Wv-TPP8Ll}>Vyv)2RfP_
z#xWn=DjRzoSyAOyR^&f239nVv{YNI+QVCU<W6Y&)#<H($MaV9OBohfNp;M$q+n$3(
z+8^6V_uRejz3+3+^ZWgt=k<$ot0x-}G9ZMy%zX0;-~agCAOB<eJBLcmr*%#P;>-wr
ztV3v at o<n+A(*!q}YI at UGs(ao at J6&(-GUlfZCabOP^{%A(Ilcd<O_}D#OvxT`$TWYY
zArhhA41MAsGaq>34Iz>Ve33nHIB+g$wsKeWk&@{^v#YIrjQ&*TbY at J>^TG4>w`bbg
zV=1%MIYwRix-(+2K98M|g^pO3YiiFvO|z}>()b%$?)2D1o$~}jm+cT6#B?}XNB`14
z`U!mwOtybM7^r{Z8FA6zcRph>e@)MS6B(bQjrw+2ik{-m;LnqveehxD&i$+ZJoxUN
zwNoEGdg)KM;v>Rm7cc*Ar+?_%ul%8UVL1O{;@Y3ZBXcHg)8osGEM3-JH;-pRXpVmU
ztkM2>3{L`$bzE`&*95X4`!(NWkBm^;5hHxi1EwveB(qRuq76FlxF}@Q34f9t9wG<w
z{pJls-KFtP61SNBw)rA^y}(3y!|t;5p)%nuiQWmqTOOK-%jByjayX#KGC3j>i6KR{
zE7tM>yqU#Sp1R0WYuk7`h+F6dc9mmpa_qchi}IJ<vuXFT=$a-xvuRI;aF at 3m5+U-{
z9`aO=5(Ar5<g6lx$b^GTJT!pY!KBh at Qu-}QEUygbQ%CM?<9ikS<s9DRiLO$CsTG*=
zu3eFsC5~B0u}hNik6F=G5?%RSJEICYQ5YxOIrTXF^wFsM_k?>&HUGL-kvo)_oR0U9
zLm?$@QR0(|_4;?Idx*Lp#I-D5Yon at mya`#@9qdZcHt)0D;Fy(^ZKcB0s_b8Nwy5Q-
zFeSELO}op%=KmxTQU-^}q5Ro1J6TFY!1j`DNn&nu>}rvHO=r^r=Gbk?c>X78p{%;6
zL at xmHXx>v3-QzG+Cw^5AnJR-2kBJ;{kg<H~#Wfml&f)bSe!w>sZ}@DrYU9l+y9xmW
ztnR6_cRGD2qY4wEtE_rvims9hIeN;0>3$OlQS}3W9g6kyMZ6iJ?pBQ3c50oc*6q~a
zgZLti*LV!W2NmO;3a$n5L%!*YO^KOLu{W!Yn;g5ru?rjv4BqCx8nyq-Ju7-=2v;uc
zDtF8R`;hDi#2HWqWySjGExg53)e64TM%|f&zo<H5;5`y@>CA&vG=$^JKxHc9b5&G;
z&I?SH+ZHC-r2<>=*;b28v^mV<s>Uw`PS$ymOJA~(0|BLTQu$F5_Fl{BJQJ!XrwYqr
zE6Aw~h?xW2SNxI<LcLyO&!rloXD;w~%T8 at oj9Wo!M{|YOE5;2wRb7T;-)>7MddOju
zVm<fNjOqp*z9R}{z>sid)1ETn0Wfo_xqbg4NEZ}UU|vhv?(2ZZ#cM`TAou|;S`I#I
zQRE~!@*X+t0LqHfK4FS*&#J;By?0h^%|UEED|YrTIvb$32mluMYwSy7_jjEjYHdy{
zmIr(~mEL7a%MtWH;2=lxe_Qai&Ol&kO}CR`D^wq-x28^f3ooVEa<y at zz$~V0H>&JP
zwNZl(!t>ccW=l|L4FfX%GK*{cS|OcqC<z(-EB$Rs?4cnZAO|N&tw;RAg3u{=?yHYE
zpw7sV4ml6pYP7hP)zJ-Rv9SNPPiq5!>z;m}Jh2wSw}Ma>R81=m>Q)f%OeIqq09w@!
zDUgSz*$(-tDopDjd~Z(G{}37gvr=VN>`YD4?Cq3oUSgIDOlePOQc*|k06D-_67L(|
zBi!&C0qDI6MXZ9{+ at NmgJte|@!~xp80p6tIX}k{l1+9gsDp=?Z%f<&;>aHDc&0#Ia
z-_i(aeUB`A0LiP+1PJeB+5-(Ct3oS8l4I`-YBG&JSx4%THrEb&v`hO|4^Q~U84dKP
zOgE(Jr;eI%oz`g)iqdu8qfL)j|Bv;&IaNRX|JV215dv4piRr@`^mD?JZA}vIYn~DM
z0i1u at nRk%L{Yx8%rM|xI?p+((d++RRaqf+^H)qQ+{uqCuH*R-zyH1{rM4uIea8x+q
zaz?to;S395XV`Tj91cs8(A_0O1lP&FzQoJN<J|-C<Nn at w_?1Za at s}?R#N$$L-_b6Z
VkOtyMFUc2TQl$G>U!N8N`ZwtAwyyvH

diff --git a/llvm/test/Instrumentation/AddressSanitizer/musttail.ll b/llvm/test/Instrumentation/AddressSanitizer/musttail.ll
index 8ec87693d1859..fed4521c195a4 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/musttail.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/musttail.ll
@@ -18,3 +18,17 @@ define i32 @call_foo(ptr %a) sanitize_address {
 ; CHECK-LABEL:  define i32 @call_foo(ptr %a) 
 ; CHECK:          %r = musttail call i32 @foo(ptr %a)
 ; CHECK-NEXT:     ret i32 %r
+
+
+define i32 @call_foo_cast(ptr %a) sanitize_address {
+  %x = alloca [10 x i8], align 1
+  call void @alloca_test_use(ptr %x)
+  %r = musttail call i32 @foo(ptr %a)
+  %t = bitcast i32 %r to i32
+  ret i32 %t
+}
+
+; CHECK-LABEL:  define i32 @call_foo_cast(ptr %a)
+; CHECK:          %r = musttail call i32 @foo(ptr %a)
+; CHECK-NEXT:     %t = bitcast i32 %r to i32
+; CHECK-NEXT:     ret i32 %t
diff --git a/llvm/test/Instrumentation/ThreadSanitizer/tsan_musttail.ll b/llvm/test/Instrumentation/ThreadSanitizer/tsan_musttail.ll
index 2d16a82f666d1..5e56aa2d11068 100644
--- a/llvm/test/Instrumentation/ThreadSanitizer/tsan_musttail.ll
+++ b/llvm/test/Instrumentation/ThreadSanitizer/tsan_musttail.ll
@@ -15,3 +15,16 @@ define i32 @call_preallocated_musttail(ptr preallocated(i32) %a) sanitize_thread
 ; CHECK:          call void @__tsan_func_exit()
 ; CHECK-NEXT:     %r = musttail call i32 @preallocated_musttail(ptr preallocated(i32) %a)
 ; CHECK-NEXT:     ret i32 %r
+
+
+define i32 @call_preallocated_musttail_cast(ptr preallocated(i32) %a) sanitize_thread {
+  %r = musttail call i32 @preallocated_musttail(ptr preallocated(i32) %a)
+  %t = bitcast i32 %r to i32
+  ret i32 %t
+}
+
+; CHECK-LABEL:  define i32 @call_preallocated_musttail_cast(ptr preallocated(i32) %a)
+; CHECK:          call void @__tsan_func_exit()
+; CHECK-NEXT:     %r = musttail call i32 @preallocated_musttail(ptr preallocated(i32) %a)
+; CHECK-NEXT:     %t = bitcast i32 %r to i32
+; CHECK-NEXT:     ret i32 %t
diff --git a/llvm/test/Transforms/CallSiteSplitting/musttail.ll b/llvm/test/Transforms/CallSiteSplitting/musttail.ll
index 1993e1e97e403..0f989a2ae4ad1 100644
--- a/llvm/test/Transforms/CallSiteSplitting/musttail.ll
+++ b/llvm/test/Transforms/CallSiteSplitting/musttail.ll
@@ -1,5 +1,29 @@
 ; RUN: opt < %s -passes=callsite-splitting -verify-dom-info -S | FileCheck %s
 
+;CHECK-LABEL: @caller
+;CHECK-LABEL: Top.split:
+;CHECK: %ca1 = musttail call ptr @callee(ptr null, ptr %b)
+;CHECK: %cb2 = bitcast ptr %ca1 to ptr
+;CHECK: ret ptr %cb2
+;CHECK-LABEL: TBB.split
+;CHECK: %ca3 = musttail call ptr @callee(ptr nonnull %a, ptr null)
+;CHECK: %cb4 = bitcast ptr %ca3 to ptr
+;CHECK: ret ptr %cb4
+define ptr @caller(ptr %a, ptr %b) {
+Top:
+  %c = icmp eq ptr %a, null
+  br i1 %c, label %Tail, label %TBB
+TBB:
+  %c2 = icmp eq ptr %b, null
+  br i1 %c2, label %Tail, label %End
+Tail:
+  %ca = musttail call ptr @callee(ptr %a, ptr %b)
+  %cb = bitcast ptr %ca to ptr
+  ret ptr %cb
+End:
+  ret ptr null
+}
+
 define ptr @callee(ptr %a, ptr %b) noinline {
   ret ptr %a
 }
diff --git a/llvm/test/Transforms/SafeStack/X86/musttail.ll b/llvm/test/Transforms/SafeStack/X86/musttail.ll
index 317bc3920fb1b..0289729f53b50 100644
--- a/llvm/test/Transforms/SafeStack/X86/musttail.ll
+++ b/llvm/test/Transforms/SafeStack/X86/musttail.ll
@@ -24,3 +24,22 @@ define i32 @call_foo(ptr %a) safestack {
   %r = musttail call i32 @foo(ptr %a)
   ret i32 %r
 }
+
+define i32 @call_foo_cast(ptr %a) safestack {
+; CHECK-LABEL: @call_foo_cast(
+; CHECK-NEXT:    [[UNSAFE_STACK_PTR:%.*]] = load ptr, ptr @__safestack_unsafe_stack_ptr, align 8
+; CHECK-NEXT:    [[UNSAFE_STACK_STATIC_TOP:%.*]] = getelementptr i8, ptr [[UNSAFE_STACK_PTR]], i32 -16
+; CHECK-NEXT:    store ptr [[UNSAFE_STACK_STATIC_TOP]], ptr @__safestack_unsafe_stack_ptr, align 8
+; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr [[UNSAFE_STACK_PTR]], i32 -10
+; CHECK-NEXT:    call void @alloca_test_use(ptr [[TMP1]])
+; CHECK-NEXT:    store ptr [[UNSAFE_STACK_PTR]], ptr @__safestack_unsafe_stack_ptr, align 8
+; CHECK-NEXT:    [[R:%.*]] = musttail call i32 @foo(ptr [[A:%.*]])
+; CHECK-NEXT:    [[T:%.*]] = bitcast i32 [[R]] to i32
+; CHECK-NEXT:    ret i32 [[T]]
+;
+  %x = alloca [10 x i8], align 1
+  call void @alloca_test_use(ptr %x)
+  %r = musttail call i32 @foo(ptr %a)
+  %t = bitcast i32 %r to i32
+  ret i32 %t
+}
diff --git a/llvm/test/Verifier/musttail-invalid.ll b/llvm/test/Verifier/musttail-invalid.ll
index 849967ee9d487..b9109a09bb543 100644
--- a/llvm/test/Verifier/musttail-invalid.ll
+++ b/llvm/test/Verifier/musttail-invalid.ll
@@ -69,7 +69,7 @@ define void @mismatched_alignment(ptr byval(i32) align 4 %a) {
 
 declare i32 @not_tail_pos_callee()
 define i32 @not_tail_pos() {
-; CHECK: musttail call must precede a ret
+; CHECK: musttail call must precede a ret with an optional bitcast
   %v = musttail call i32 @not_tail_pos_callee()
   %w = add i32 %v, 1
   ret i32 %w



More information about the llvm-commits mailing list