@@ -3277,7 +3277,7 @@ static bool isRemovableWrite(CallBase &CB, Value *UsedV,
32773277 return Dest && Dest->Ptr == UsedV;
32783278}
32793279
3280- static bool isAllocSiteRemovable (Instruction *AI,
3280+ static std::optional<ModRefInfo> isAllocSiteRemovable (Instruction *AI,
32813281 SmallVectorImpl<WeakTrackingVH> &Users,
32823282 const TargetLibraryInfo &TLI, bool KnowInit) {
32833283 SmallVector<Instruction*, 4 > Worklist;
@@ -3292,7 +3292,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
32923292 switch (I->getOpcode ()) {
32933293 default :
32943294 // Give up the moment we see something we can't handle.
3295- return false ;
3295+ return std:: nullopt ;
32963296
32973297 case Instruction::AddrSpaceCast:
32983298 case Instruction::BitCast:
@@ -3307,10 +3307,10 @@ static bool isAllocSiteRemovable(Instruction *AI,
33073307 // We also fold comparisons in some conditions provided the alloc has
33083308 // not escaped (see isNeverEqualToUnescapedAlloc).
33093309 if (!ICI->isEquality ())
3310- return false ;
3310+ return std:: nullopt ;
33113311 unsigned OtherIndex = (ICI->getOperand (0 ) == PI) ? 1 : 0 ;
33123312 if (!isNeverEqualToUnescapedAlloc (ICI->getOperand (OtherIndex), TLI, AI))
3313- return false ;
3313+ return std:: nullopt ;
33143314
33153315 // Do not fold compares to aligned_alloc calls, as they may have to
33163316 // return null in case the required alignment cannot be satisfied,
@@ -3330,7 +3330,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
33303330 if (CB && TLI.getLibFunc (*CB->getCalledFunction (), TheLibFunc) &&
33313331 TLI.has (TheLibFunc) && TheLibFunc == LibFunc_aligned_alloc &&
33323332 !AlignmentAndSizeKnownValid (CB))
3333- return false ;
3333+ return std:: nullopt ;
33343334 Users.emplace_back (I);
33353335 continue ;
33363336 }
@@ -3340,20 +3340,20 @@ static bool isAllocSiteRemovable(Instruction *AI,
33403340 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
33413341 switch (II->getIntrinsicID ()) {
33423342 default :
3343- return false ;
3343+ return std:: nullopt ;
33443344
33453345 case Intrinsic::memmove:
33463346 case Intrinsic::memcpy:
33473347 case Intrinsic::memset: {
33483348 MemIntrinsic *MI = cast<MemIntrinsic>(II);
33493349 if (MI->isVolatile ())
3350- return false ;
3350+ return std:: nullopt ;
33513351 // Note: this could also be ModRef, but we can still interpret that
33523352 // as just Mod in that case.
33533353 ModRefInfo NewAccess =
33543354 MI->getRawDest () == PI ? ModRefInfo::Mod : ModRefInfo::Ref;
33553355 if ((Access & ~NewAccess) != ModRefInfo::NoModRef)
3356- return false ;
3356+ return std:: nullopt ;
33573357 Access |= NewAccess;
33583358 }
33593359 [[fallthrough]];
@@ -3393,14 +3393,14 @@ static bool isAllocSiteRemovable(Instruction *AI,
33933393 continue ;
33943394 }
33953395
3396- return false ;
3396+ return std:: nullopt ;
33973397
33983398 case Instruction::Store: {
33993399 StoreInst *SI = cast<StoreInst>(I);
34003400 if (SI->isVolatile () || SI->getPointerOperand () != PI)
3401- return false ;
3401+ return std:: nullopt ;
34023402 if (isRefSet (Access))
3403- return false ;
3403+ return std:: nullopt ;
34043404 Access |= ModRefInfo::Mod;
34053405 Users.emplace_back (I);
34063406 continue ;
@@ -3409,9 +3409,9 @@ static bool isAllocSiteRemovable(Instruction *AI,
34093409 case Instruction::Load: {
34103410 LoadInst *LI = cast<LoadInst>(I);
34113411 if (LI->isVolatile () || LI->getPointerOperand () != PI)
3412- return false ;
3412+ return std:: nullopt ;
34133413 if (isModSet (Access))
3414- return false ;
3414+ return std:: nullopt ;
34153415 Access |= ModRefInfo::Ref;
34163416 Users.emplace_back (I);
34173417 continue ;
@@ -3421,7 +3421,8 @@ static bool isAllocSiteRemovable(Instruction *AI,
34213421 }
34223422 } while (!Worklist.empty ());
34233423
3424- return true ;
3424+ assert (Access != ModRefInfo::ModRef);
3425+ return Access;
34253426}
34263427
34273428Instruction *InstCombinerImpl::visitAllocSite (Instruction &MI) {
@@ -3451,20 +3452,25 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
34513452
34523453 // Determine what getInitialValueOfAllocation would return without actually
34533454 // allocating the result.
3454- bool KnowInitUndef = isa<AllocaInst>(MI) ;
3455+ bool KnowInitUndef = false ;
34553456 bool KnowInitZero = false ;
3456- if (!KnowInitUndef) {
3457- Constant *Init = getInitialValueOfAllocation (
3458- &MI, &TLI, Type::getInt8Ty (MI.getContext ()));
3459- if (Init) {
3460- if (isa<UndefValue>(Init))
3461- KnowInitUndef = true ;
3462- else if (Init->isNullValue ())
3463- KnowInitZero = true ;
3464- }
3465- }
3466-
3467- if (isAllocSiteRemovable (&MI, Users, TLI, KnowInitZero | KnowInitUndef)) {
3457+ Constant *Init = getInitialValueOfAllocation (
3458+ &MI, &TLI, Type::getInt8Ty (MI.getContext ()));
3459+ if (Init) {
3460+ if (isa<UndefValue>(Init))
3461+ KnowInitUndef = true ;
3462+ else if (Init->isNullValue ())
3463+ KnowInitZero = true ;
3464+ }
3465+ // The various sanitizers don't actually return undef memory, but rather
3466+ // memory initialized with special forms of runtime poison
3467+ auto &F = *MI.getFunction ();
3468+ if (F.hasFnAttribute (Attribute::SanitizeMemory) ||
3469+ F.hasFnAttribute (Attribute::SanitizeAddress))
3470+ KnowInitUndef = false ;
3471+
3472+ auto Removable = isAllocSiteRemovable (&MI, Users, TLI, KnowInitZero | KnowInitUndef);
3473+ if (Removable) {
34683474 for (unsigned i = 0 , e = Users.size (); i != e; ++i) {
34693475 // Lowering all @llvm.objectsize and MTI calls first because they may use
34703476 // a bitcast/GEP of the alloca we are removing.
@@ -3485,14 +3491,14 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
34853491 Users[i] = nullptr ; // Skip examining in the next loop.
34863492 }
34873493 if (auto *MTI = dyn_cast<MemTransferInst>(I)) {
3488- if (KnowInitZero && getUnderlyingObject (MTI-> getRawDest ()) != &MI ) {
3494+ if (KnowInitZero && isRefSet (*Removable) ) {
34893495 IRBuilderBase::InsertPointGuard Guard (Builder);
34903496 Builder.SetInsertPoint (MTI);
34913497 auto *M = Builder.CreateMemSet (
34923498 MTI->getRawDest (),
34933499 ConstantInt::get (Type::getInt8Ty (MI.getContext ()), 0 ),
34943500 MTI->getLength (), MTI->getDestAlign ());
3495- M->copyMetadata (*MTI, LLVMContext::MD_DIAssignID );
3501+ M->copyMetadata (*MTI);
34963502 }
34973503 }
34983504 }
0 commit comments