[llvm] 9ce30fe - Extract utility function for checking initial value of allocation [NFC]
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 6 18:17:01 PST 2022
Author: Philip Reames
Date: 2022-01-06T18:02:14-08:00
New Revision: 9ce30fe86f58df45b2c5daa601802593601c471d
URL: https://github.com/llvm/llvm-project/commit/9ce30fe86f58df45b2c5daa601802593601c471d
DIFF: https://github.com/llvm/llvm-project/commit/9ce30fe86f58df45b2c5daa601802593601c471d.diff
LOG: Extract utility function for checking initial value of allocation [NFC]
This is a reoccuring pattern, we can consolidate three copies into one. The main motivation is to reduce usages of isMallocLike.
Added:
Modified:
llvm/include/llvm/Analysis/MemoryBuiltins.h
llvm/lib/Analysis/MemoryBuiltins.cpp
llvm/lib/Transforms/IPO/Attributor.cpp
llvm/lib/Transforms/Scalar/GVN.cpp
llvm/lib/Transforms/Scalar/NewGVN.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h
index d7eab9a0812cd..189ebdb91d131 100644
--- a/llvm/include/llvm/Analysis/MemoryBuiltins.h
+++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h
@@ -115,6 +115,16 @@ inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI));
}
+//===----------------------------------------------------------------------===//
+// Properties of allocation functions
+//
+
+/// If this allocation function initializes memory to a fixed value, return
+/// said value in the requested type. Otherwise, return nullptr.
+Constant *getInitialValueOfAllocation(const CallInst *Alloc,
+ const TargetLibraryInfo *TLI,
+ Type *Ty);
+
//===----------------------------------------------------------------------===//
// Utility functions to compute size of objects.
//
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 505b2a8261bc4..8291cfdd5af02 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -312,6 +312,22 @@ bool llvm::isStrdupLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
return getAllocationData(V, StrDupLike, TLI).hasValue();
}
+Constant *llvm::getInitialValueOfAllocation(const CallInst *Alloc,
+ const TargetLibraryInfo *TLI,
+ Type *Ty) {
+ assert(isAllocationFn(Alloc, TLI));
+
+ // malloc and aligned_alloc are uninitialized (undef)
+ if (isMallocLikeFn(Alloc, TLI) || isAlignedAllocLikeFn(Alloc, TLI))
+ return UndefValue::get(Ty);
+
+ // calloc zero initializes
+ if (isCallocLikeFn(Alloc, TLI))
+ return Constant::getNullValue(Ty);
+
+ return nullptr;
+}
+
/// isLibFreeFunction - Returns true if the function is a builtin free()
bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) {
unsigned ExpectedNumParams;
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index 4b10e52d49fb4..12f2e8ef4fe03 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -207,13 +207,9 @@ Constant *AA::getInitialValueForObj(Value &Obj, Type &Ty,
const TargetLibraryInfo *TLI) {
if (isa<AllocaInst>(Obj))
return UndefValue::get(&Ty);
- if (isNoAliasFn(&Obj, TLI)) {
- if (isMallocLikeFn(&Obj, TLI) || isAlignedAllocLikeFn(&Obj, TLI))
- return UndefValue::get(&Ty);
- if (isCallocLikeFn(&Obj, TLI))
- return Constant::getNullValue(&Ty);
- return nullptr;
- }
+ if (isAllocationFn(&Obj, TLI))
+ return getInitialValueOfAllocation(&cast<CallInst>(Obj), TLI, &Ty);
+
auto *GV = dyn_cast<GlobalVariable>(&Obj);
if (!GV || !GV->hasLocalLinkage())
return nullptr;
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index ee7a2e4aed253..a45a9d772a94c 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1104,20 +1104,19 @@ bool GVNPass::AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo,
}
assert(DepInfo.isDef() && "follows from above");
- // Loading the allocation -> undef.
- if (isa<AllocaInst>(DepInst) || isMallocLikeFn(DepInst, TLI) ||
- isAlignedAllocLikeFn(DepInst, TLI) ||
- // Loading immediately after lifetime begin -> undef.
- isLifetimeStart(DepInst)) {
+ // Loading the alloca -> undef.
+ // Loading immediately after lifetime begin -> undef.
+ if (isa<AllocaInst>(DepInst) || isLifetimeStart(DepInst)) {
Res = AvailableValue::get(UndefValue::get(Load->getType()));
return true;
}
- // Loading from calloc (which zero initializes memory) -> zero
- if (isCallocLikeFn(DepInst, TLI)) {
- Res = AvailableValue::get(Constant::getNullValue(Load->getType()));
- return true;
- }
+ if (isAllocationFn(DepInst, TLI))
+ if (auto *InitVal = getInitialValueOfAllocation(cast<CallInst>(DepInst),
+ TLI, Load->getType())) {
+ Res = AvailableValue::get(InitVal);
+ return true;
+ }
if (StoreInst *S = dyn_cast<StoreInst>(DepInst)) {
// Reject loads and stores that are to the same address but are of
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 3558ce3e11a41..8046d97d9658c 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -1493,8 +1493,7 @@ NewGVN::performSymbolicLoadCoercion(Type *LoadType, Value *LoadPtr,
// undef value. This can happen when loading for a fresh allocation with no
// intervening stores, for example. Note that this is only true in the case
// that the result of the allocation is pointer equal to the load ptr.
- if (isa<AllocaInst>(DepInst) || isMallocLikeFn(DepInst, TLI) ||
- isAlignedAllocLikeFn(DepInst, TLI)) {
+ if (isa<AllocaInst>(DepInst)) {
return createConstantExpression(UndefValue::get(LoadType));
}
// If this load occurs either right after a lifetime begin,
@@ -1502,12 +1501,10 @@ NewGVN::performSymbolicLoadCoercion(Type *LoadType, Value *LoadPtr,
else if (auto *II = dyn_cast<IntrinsicInst>(DepInst)) {
if (II->getIntrinsicID() == Intrinsic::lifetime_start)
return createConstantExpression(UndefValue::get(LoadType));
- }
- // If this load follows a calloc (which zero initializes memory),
- // then the loaded value is zero
- else if (isCallocLikeFn(DepInst, TLI)) {
- return createConstantExpression(Constant::getNullValue(LoadType));
- }
+ } else if (isAllocationFn(DepInst, TLI))
+ if (auto *InitVal = getInitialValueOfAllocation(cast<CallInst>(DepInst),
+ TLI, LoadType))
+ return createConstantExpression(InitVal);
return nullptr;
}
More information about the llvm-commits
mailing list