Index: llvm/lib/Analysis/AliasAnalysis.cpp =================================================================== --- llvm/lib/Analysis/AliasAnalysis.cpp +++ llvm/lib/Analysis/AliasAnalysis.cpp @@ -30,6 +30,7 @@ #include "llvm/Analysis/CFLSteensAliasAnalysis.h" #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/ObjCARCAliasAnalysis.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" @@ -237,7 +238,7 @@ // aggregate set of AA results. auto MRB = getModRefBehavior(Call); if (onlyAccessesInaccessibleMem(MRB)) - return ModRefInfo::NoModRef; + return isAllocLikeFn(Call, &TLI) ? ModRefInfo::Mod : ModRefInfo::NoModRef; if (onlyReadsMemory(MRB)) Result = clearMod(Result); Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp =================================================================== --- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -926,13 +926,17 @@ } // Check if we can ignore \p D for DSE. -bool canSkipDef(MemoryDef *D, bool DefVisibleToCaller) { +bool canSkipDef(MemoryDef *D, bool DefVisibleToCaller, + const TargetLibraryInfo &TLI) { Instruction *DI = D->getMemoryInst(); // Calls that only access inaccessible memory cannot read or write any memory // locations we consider for elimination. if (auto *CB = dyn_cast(DI)) - if (CB->onlyAccessesInaccessibleMemory()) + if (CB->onlyAccessesInaccessibleMemory()) { + if (isAllocLikeFn(DI, &TLI)) + return false; return true; + } // We can eliminate stores to locations not visible to the caller across // throwing instructions. @@ -948,7 +952,7 @@ return true; // Skip intrinsics that do not really read or modify memory. - if (isNoopIntrinsic(D->getMemoryInst())) + if (isNoopIntrinsic(DI)) return true; return false; @@ -1243,8 +1247,11 @@ return false; if (auto *CB = dyn_cast(UseInst)) - if (CB->onlyAccessesInaccessibleMemory()) + if (CB->onlyAccessesInaccessibleMemory()) { + if (isAllocLikeFn(CB, &TLI)) + return true; return false; + } // NOTE: For calls, the number of stores removed could be slightly improved // by using AA.callCapturesBefore(UseInst, DefLoc, &DT), but that showed to @@ -1346,7 +1353,7 @@ MemoryDef *CurrentDef = cast(Current); Instruction *CurrentI = CurrentDef->getMemoryInst(); - if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(DefUO))) { + if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(DefUO), TLI)) { StepAgain = true; Current = CurrentDef->getDefiningAccess(); continue; Index: llvm/test/Transforms/DeadStoreElimination/noop-stores.ll =================================================================== --- llvm/test/Transforms/DeadStoreElimination/noop-stores.ll +++ llvm/test/Transforms/DeadStoreElimination/noop-stores.ll @@ -313,7 +313,6 @@ define i8* @store_zero_after_calloc_inaccessiblememonly() { ; CHECK-LABEL: @store_zero_after_calloc_inaccessiblememonly( ; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @calloc(i64 1, i64 10) #[[ATTR6:[0-9]+]] -; CHECK-NEXT: store i8 0, i8* [[CALL]], align 1 ; CHECK-NEXT: ret i8* [[CALL]] ; %call = tail call i8* @calloc(i64 1, i64 10) inaccessiblememonly @@ -407,7 +406,6 @@ define i8* @zero_memset_after_calloc_inaccessiblememonly() { ; CHECK-LABEL: @zero_memset_after_calloc_inaccessiblememonly( ; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @calloc(i64 10000, i64 4) #[[ATTR6]] -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[CALL]], i8 0, i64 40000, i1 false) ; CHECK-NEXT: ret i8* [[CALL]] ; %call = tail call i8* @calloc(i64 10000, i64 4) inaccessiblememonly