summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-01-07 09:57:53 +0100
committerNikita Popov <npopov@redhat.com>2022-01-10 09:18:15 +0100
commit92d55e7336db8597e90eefcdd72bc33ef553a454 (patch)
tree3f1240a4bc250ef3b0eff4b025fc48f332995a4c
parentc0fdc748871f44a2c98cdf54abf2dc8fe2c172aa (diff)
downloadllvm-92d55e7336db8597e90eefcdd72bc33ef553a454.tar.gz
[MemoryBuiltins] Remove isNoAliasFn() in favor of isNoAliasCall()
We currently have two similar implementations of this concept: isNoAliasCall() only checks for the noalias return attribute. isNoAliasFn() also checks for allocation functions. We should switch to only checking the attribute. SLC is responsible for inferring the noalias return attribute for non-new allocation functions (with a missing case fixed in https://github.com/llvm/llvm-project/commit/348bc76e3548c52dbcd442590ca0a7f5b09b7534). For new, clang is responsible for setting the attribute, if -fno-assume-sane-operator-new is not passed. Differential Revision: https://reviews.llvm.org/D116800
-rw-r--r--llvm/include/llvm/Analysis/MemoryBuiltins.h4
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp14
-rw-r--r--llvm/lib/Analysis/MemoryDependenceAnalysis.cpp2
-rw-r--r--llvm/lib/Transforms/IPO/Attributor.cpp5
-rw-r--r--llvm/lib/Transforms/IPO/AttributorAttributes.cpp3
-rw-r--r--llvm/test/Transforms/GVN/malloc-load-removal.ll6
-rw-r--r--llvm/unittests/Analysis/MemoryBuiltinsTest.cpp4
7 files changed, 6 insertions, 32 deletions
diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h
index 28104c5ed420..95881bd2480e 100644
--- a/llvm/include/llvm/Analysis/MemoryBuiltins.h
+++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h
@@ -56,10 +56,6 @@ bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI);
bool isAllocationFn(const Value *V,
function_ref<const TargetLibraryInfo &(Function &)> GetTLI);
-/// Tests if a value is a call or invoke to a function that returns a
-/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
-bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI);
-
/// Tests if a value is a call or invoke to a library function that
/// allocates uninitialized memory (such as malloc).
bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI);
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index fe21ab45d85d..86e711884e2e 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -222,11 +222,6 @@ static Optional<AllocFnsTy> getAllocationSize(const Value *V,
return Result;
}
-static bool hasNoAliasAttr(const Value *V) {
- const auto *CB = dyn_cast<CallBase>(V);
- return CB && CB->hasRetAttr(Attribute::NoAlias);
-}
-
/// Tests if a value is a call or invoke to a library function that
/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
/// like).
@@ -238,15 +233,6 @@ bool llvm::isAllocationFn(
return getAllocationData(V, AnyAlloc, GetTLI).hasValue();
}
-/// Tests if a value is a call or invoke to a function that returns a
-/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
-bool llvm::isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI) {
- // it's safe to consider realloc as noalias since accessing the original
- // pointer is undefined behavior
- return isAllocationFn(V, TLI) ||
- hasNoAliasAttr(V);
-}
-
/// Tests if a value is a call or invoke to a library function that
/// allocates uninitialized memory (such as malloc).
bool llvm::isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
index da6bb4c49cba..36df462c7a66 100644
--- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -594,7 +594,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
// turn into undef. Note that we can bypass the allocation itself when
// looking for a clobber in many cases; that's an alias property and is
// handled by BasicAA.
- if (isa<AllocaInst>(Inst) || isNoAliasFn(Inst, &TLI)) {
+ if (isa<AllocaInst>(Inst) || isNoAliasCall(Inst)) {
const Value *AccessPtr = getUnderlyingObject(MemLoc.Ptr);
if (AccessPtr == Inst || BatchAA.isMustAlias(Inst, AccessPtr))
return MemDepResult::getDef(Inst);
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index a71c70b3fbca..12b8a0ef9d00 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -209,7 +209,6 @@ Constant *AA::getInitialValueForObj(Value &Obj, Type &Ty,
return UndefValue::get(&Ty);
if (isAllocationFn(&Obj, TLI))
return getInitialValueOfAllocation(&cast<CallBase>(Obj), TLI, &Ty);
-
auto *GV = dyn_cast<GlobalVariable>(&Obj);
if (!GV || !GV->hasLocalLinkage())
return nullptr;
@@ -305,8 +304,6 @@ bool AA::getPotentialCopiesOfStoredValue(
SmallVector<const AAPointerInfo *> PIs;
SmallVector<Value *> NewCopies;
- const auto *TLI =
- A.getInfoCache().getTargetLibraryInfoForFunction(*SI.getFunction());
for (Value *Obj : Objects) {
LLVM_DEBUG(dbgs() << "Visit underlying object " << *Obj << "\n");
if (isa<UndefValue>(Obj))
@@ -324,7 +321,7 @@ bool AA::getPotentialCopiesOfStoredValue(
return false;
}
if (!isa<AllocaInst>(Obj) && !isa<GlobalVariable>(Obj) &&
- !isNoAliasFn(Obj, TLI)) {
+ !isNoAliasCall(Obj)) {
LLVM_DEBUG(dbgs() << "Underlying object is not supported yet: " << *Obj
<< "\n";);
return false;
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 07c16c7d6b70..a78517425fd0 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -5274,9 +5274,6 @@ struct AAValueSimplifyImpl : AAValueSimplify {
continue;
return false;
}
- if (!isa<AllocaInst>(Obj) && !isa<GlobalVariable>(Obj) &&
- !isNoAliasFn(Obj, TLI))
- return false;
Constant *InitialVal = AA::getInitialValueForObj(*Obj, *L.getType(), TLI);
if (!InitialVal || !Union(*InitialVal))
return false;
diff --git a/llvm/test/Transforms/GVN/malloc-load-removal.ll b/llvm/test/Transforms/GVN/malloc-load-removal.ll
index bbb6f5ca7851..57fb89225efd 100644
--- a/llvm/test/Transforms/GVN/malloc-load-removal.ll
+++ b/llvm/test/Transforms/GVN/malloc-load-removal.ll
@@ -5,7 +5,7 @@
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"
-declare i8* @malloc(i64) nounwind
+declare noalias i8* @malloc(i64) nounwind
define noalias i8* @test1() nounwind uwtable ssp {
entry:
@@ -30,7 +30,7 @@ if.end: ; preds = %if.then, %entry
; CHECK_NO_LIBCALLS: icmp
}
-declare i8* @_Znwm(i64) nounwind
+declare noalias i8* @_Znwm(i64) nounwind
define noalias i8* @test2() nounwind uwtable ssp {
entry:
@@ -55,7 +55,7 @@ if.end: ; preds = %if.then, %entry
; CHECK_NO_LIBCALLS: icmp
}
-declare i8* @aligned_alloc(i64, i64) nounwind
+declare noalias i8* @aligned_alloc(i64, i64) nounwind
define noalias i8* @test3() nounwind uwtable ssp {
entry:
diff --git a/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp b/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp
index 575b7f320473..05f1a586f504 100644
--- a/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp
+++ b/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp
@@ -36,14 +36,12 @@ TEST(AllocSize, AllocationBuiltinsTest) {
CallInst::Create(AllocSizeFn, {ConstantInt::get(ArgTy, 100)}));
const TargetLibraryInfo *TLI = nullptr;
- EXPECT_FALSE(isNoAliasFn(Caller.get(), TLI));
EXPECT_FALSE(isMallocLikeFn(Caller.get(), TLI));
EXPECT_FALSE(isCallocLikeFn(Caller.get(), TLI));
EXPECT_FALSE(isAllocLikeFn(Caller.get(), TLI));
// FIXME: We might be able to treat allocsize functions as general allocation
- // functions. For the moment, being conservative seems better (and we'd have
- // to plumb stuff around `isNoAliasFn`).
+ // functions.
EXPECT_FALSE(isAllocationFn(Caller.get(), TLI));
}
}