@@ -1310,6 +1310,18 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn,
13101310 return true ;
13111311 }
13121312 break ;
1313+ case ' l' :
1314+ if (Name.starts_with (" lifetime.start" ) ||
1315+ Name.starts_with (" lifetime.end" )) {
1316+ // Unless remangling is required, do not upgrade the function declaration,
1317+ // but do upgrade the calls.
1318+ if (auto Result = llvm::Intrinsic::remangleIntrinsicFunction (F))
1319+ NewFn = *Result;
1320+ else
1321+ NewFn = F;
1322+ return true ;
1323+ }
1324+ break ;
13131325 case ' m' : {
13141326 // Updating the memory intrinsics (memcpy/memmove/memset) that have an
13151327 // alignment parameter to embedding the alignment as an attribute of
@@ -1629,7 +1641,6 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn,
16291641 NewFn = nullptr ;
16301642 bool Upgraded =
16311643 upgradeIntrinsicFunction1 (F, NewFn, CanUpgradeDebugIntrinsicsToRecords);
1632- assert (F != NewFn && " Intrinsic function upgraded to the same function" );
16331644
16341645 // Upgrade intrinsic attributes. This does not change the function.
16351646 if (NewFn)
@@ -4570,6 +4581,9 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
45704581 }
45714582
45724583 const auto &DefaultCase = [&]() -> void {
4584+ if (F == NewFn)
4585+ return ;
4586+
45734587 if (CI->getFunctionType () == NewFn->getFunctionType ()) {
45744588 // Handle generic mangling change.
45754589 assert (
@@ -5109,6 +5123,31 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
51095123 MTI->setSourceAlignment (Align->getMaybeAlignValue ());
51105124 break ;
51115125 }
5126+
5127+ case Intrinsic::lifetime_start:
5128+ case Intrinsic::lifetime_end: {
5129+ Value *Size = CI->getArgOperand (0 );
5130+ Value *Ptr = CI->getArgOperand (1 );
5131+ if (isa<AllocaInst>(Ptr)) {
5132+ DefaultCase ();
5133+ return ;
5134+ }
5135+
5136+ // Try to strip pointer casts, such that the lifetime works on an alloca.
5137+ Ptr = Ptr->stripPointerCasts ();
5138+ if (isa<AllocaInst>(Ptr)) {
5139+ // Don't use NewFn, as we might have looked through an addrspacecast.
5140+ if (NewFn->getIntrinsicID () == Intrinsic::lifetime_start)
5141+ NewCall = Builder.CreateLifetimeStart (Ptr, cast<ConstantInt>(Size));
5142+ else
5143+ NewCall = Builder.CreateLifetimeEnd (Ptr, cast<ConstantInt>(Size));
5144+ break ;
5145+ }
5146+
5147+ // Otherwise remove the lifetime marker.
5148+ CI->eraseFromParent ();
5149+ return ;
5150+ }
51125151 }
51135152 assert (NewCall && " Should have either set this variable or returned through "
51145153 " the default case" );
@@ -5131,7 +5170,8 @@ void llvm::UpgradeCallsToIntrinsic(Function *F) {
51315170 UpgradeIntrinsicCall (CB, NewFn);
51325171
51335172 // Remove old function, no longer used, from the module.
5134- F->eraseFromParent ();
5173+ if (F != NewFn)
5174+ F->eraseFromParent ();
51355175 }
51365176}
51375177
0 commit comments