@@ -3244,7 +3244,7 @@ static bool isRemovableWrite(CallBase &CB, Value *UsedV,
3244
3244
return Dest && Dest->Ptr == UsedV;
3245
3245
}
3246
3246
3247
- static bool isAllocSiteRemovable (Instruction *AI,
3247
+ static std::optional<ModRefInfo> isAllocSiteRemovable (Instruction *AI,
3248
3248
SmallVectorImpl<WeakTrackingVH> &Users,
3249
3249
const TargetLibraryInfo &TLI, bool KnowInit) {
3250
3250
SmallVector<Instruction*, 4 > Worklist;
@@ -3259,7 +3259,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
3259
3259
switch (I->getOpcode ()) {
3260
3260
default :
3261
3261
// Give up the moment we see something we can't handle.
3262
- return false ;
3262
+ return std::nullopt ;
3263
3263
3264
3264
case Instruction::AddrSpaceCast:
3265
3265
case Instruction::BitCast:
@@ -3274,10 +3274,10 @@ static bool isAllocSiteRemovable(Instruction *AI,
3274
3274
// We also fold comparisons in some conditions provided the alloc has
3275
3275
// not escaped (see isNeverEqualToUnescapedAlloc).
3276
3276
if (!ICI->isEquality ())
3277
- return false ;
3277
+ return std::nullopt ;
3278
3278
unsigned OtherIndex = (ICI->getOperand (0 ) == PI) ? 1 : 0 ;
3279
3279
if (!isNeverEqualToUnescapedAlloc (ICI->getOperand (OtherIndex), TLI, AI))
3280
- return false ;
3280
+ return std::nullopt ;
3281
3281
3282
3282
// Do not fold compares to aligned_alloc calls, as they may have to
3283
3283
// return null in case the required alignment cannot be satisfied,
@@ -3297,7 +3297,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
3297
3297
if (CB && TLI.getLibFunc (*CB->getCalledFunction (), TheLibFunc) &&
3298
3298
TLI.has (TheLibFunc) && TheLibFunc == LibFunc_aligned_alloc &&
3299
3299
!AlignmentAndSizeKnownValid (CB))
3300
- return false ;
3300
+ return std::nullopt ;
3301
3301
Users.emplace_back (I);
3302
3302
continue ;
3303
3303
}
@@ -3307,20 +3307,20 @@ static bool isAllocSiteRemovable(Instruction *AI,
3307
3307
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
3308
3308
switch (II->getIntrinsicID ()) {
3309
3309
default :
3310
- return false ;
3310
+ return std::nullopt ;
3311
3311
3312
3312
case Intrinsic::memmove:
3313
3313
case Intrinsic::memcpy:
3314
3314
case Intrinsic::memset: {
3315
3315
MemIntrinsic *MI = cast<MemIntrinsic>(II);
3316
3316
if (MI->isVolatile ())
3317
- return false ;
3317
+ return std::nullopt ;
3318
3318
// Note: this could also be ModRef, but we can still interpret that
3319
3319
// as just Mod in that case.
3320
3320
ModRefInfo NewAccess =
3321
3321
MI->getRawDest () == PI ? ModRefInfo::Mod : ModRefInfo::Ref;
3322
3322
if ((Access & ~NewAccess) != ModRefInfo::NoModRef)
3323
- return false ;
3323
+ return std::nullopt ;
3324
3324
Access |= NewAccess;
3325
3325
}
3326
3326
[[fallthrough]];
@@ -3360,14 +3360,14 @@ static bool isAllocSiteRemovable(Instruction *AI,
3360
3360
continue ;
3361
3361
}
3362
3362
3363
- return false ;
3363
+ return std::nullopt ;
3364
3364
3365
3365
case Instruction::Store: {
3366
3366
StoreInst *SI = cast<StoreInst>(I);
3367
3367
if (SI->isVolatile () || SI->getPointerOperand () != PI)
3368
- return false ;
3368
+ return std::nullopt ;
3369
3369
if (isRefSet (Access))
3370
- return false ;
3370
+ return std::nullopt ;
3371
3371
Access |= ModRefInfo::Mod;
3372
3372
Users.emplace_back (I);
3373
3373
continue ;
@@ -3376,9 +3376,9 @@ static bool isAllocSiteRemovable(Instruction *AI,
3376
3376
case Instruction::Load: {
3377
3377
LoadInst *LI = cast<LoadInst>(I);
3378
3378
if (LI->isVolatile () || LI->getPointerOperand () != PI)
3379
- return false ;
3379
+ return std::nullopt ;
3380
3380
if (isModSet (Access))
3381
- return false ;
3381
+ return std::nullopt ;
3382
3382
Access |= ModRefInfo::Ref;
3383
3383
Users.emplace_back (I);
3384
3384
continue ;
@@ -3388,7 +3388,8 @@ static bool isAllocSiteRemovable(Instruction *AI,
3388
3388
}
3389
3389
} while (!Worklist.empty ());
3390
3390
3391
- return true ;
3391
+ assert (Access != ModRefInfo::ModRef);
3392
+ return Access;
3392
3393
}
3393
3394
3394
3395
Instruction *InstCombinerImpl::visitAllocSite (Instruction &MI) {
@@ -3418,20 +3419,25 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
3418
3419
3419
3420
// Determine what getInitialValueOfAllocation would return without actually
3420
3421
// allocating the result.
3421
- bool KnowInitUndef = isa<AllocaInst>(MI) ;
3422
+ bool KnowInitUndef = false ;
3422
3423
bool KnowInitZero = false ;
3423
- if (!KnowInitUndef) {
3424
- Constant *Init = getInitialValueOfAllocation (
3425
- &MI, &TLI, Type::getInt8Ty (MI.getContext ()));
3426
- if (Init) {
3427
- if (isa<UndefValue>(Init))
3428
- KnowInitUndef = true ;
3429
- else if (Init->isNullValue ())
3430
- KnowInitZero = true ;
3431
- }
3432
- }
3433
-
3434
- if (isAllocSiteRemovable (&MI, Users, TLI, KnowInitZero | KnowInitUndef)) {
3424
+ Constant *Init = getInitialValueOfAllocation (
3425
+ &MI, &TLI, Type::getInt8Ty (MI.getContext ()));
3426
+ if (Init) {
3427
+ if (isa<UndefValue>(Init))
3428
+ KnowInitUndef = true ;
3429
+ else if (Init->isNullValue ())
3430
+ KnowInitZero = true ;
3431
+ }
3432
+ // The various sanitizers don't actually return undef memory, but rather
3433
+ // memory initialized with special forms of runtime poison
3434
+ auto &F = *MI.getFunction ();
3435
+ if (F.hasFnAttribute (Attribute::SanitizeMemory) ||
3436
+ F.hasFnAttribute (Attribute::SanitizeAddress))
3437
+ KnowInitUndef = false ;
3438
+
3439
+ auto Removable = isAllocSiteRemovable (&MI, Users, TLI, KnowInitZero | KnowInitUndef);
3440
+ if (Removable) {
3435
3441
for (unsigned i = 0 , e = Users.size (); i != e; ++i) {
3436
3442
// Lowering all @llvm.objectsize and MTI calls first because they may use
3437
3443
// a bitcast/GEP of the alloca we are removing.
@@ -3452,14 +3458,14 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
3452
3458
Users[i] = nullptr ; // Skip examining in the next loop.
3453
3459
}
3454
3460
if (auto *MTI = dyn_cast<MemTransferInst>(I)) {
3455
- if (KnowInitZero && getUnderlyingObject (MTI-> getRawDest ()) != &MI ) {
3461
+ if (KnowInitZero && isRefSet (*Removable) ) {
3456
3462
IRBuilderBase::InsertPointGuard Guard (Builder);
3457
3463
Builder.SetInsertPoint (MTI);
3458
3464
auto *M = Builder.CreateMemSet (
3459
3465
MTI->getRawDest (),
3460
3466
ConstantInt::get (Type::getInt8Ty (MI.getContext ()), 0 ),
3461
3467
MTI->getLength (), MTI->getDestAlign ());
3462
- M->copyMetadata (*MTI, LLVMContext::MD_DIAssignID );
3468
+ M->copyMetadata (*MTI);
3463
3469
}
3464
3470
}
3465
3471
}
0 commit comments