зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1798840 - Revert clang trunk change that heavily breaks Firefox.
Differential Revision: https://phabricator.services.mozilla.com/D161112
This commit is contained in:
Родитель
5fb5ca9039
Коммит
eddb810ffd
|
@ -7,6 +7,7 @@
|
|||
"bug47258-extract-symbols-mbcs.patch",
|
||||
"fuzzing_ccov_build_clang_12.patch",
|
||||
"win64-no-symlink_clang_16.patch",
|
||||
"revert-llvmorg-16-init-9324-g01859da84bad.patch",
|
||||
"revert-llvmorg-16-init-8201-ge0fb01e97b6b.patch",
|
||||
"revert-llvmorg-16-init-7694-g19e984ef8f49.patch",
|
||||
"revert-llvmorg-16-init-7598-g54bfd0484615.patch",
|
||||
|
|
|
@ -0,0 +1,869 @@
|
|||
From 4ebea86ddf20d3f9be3cb363eed3f313591bee66 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Hommey <mh@glandium.org>
|
||||
Date: Thu, 3 Nov 2022 13:54:08 +0900
|
||||
Subject: [PATCH] Revert "[AliasAnalysis] Introduce getModRefInfoMask() as a
|
||||
generalization of pointsToConstantMemory()."
|
||||
|
||||
This reverts commit 01859da84bad95fd51d6a03b08b60c660e642a4f
|
||||
for causing https://github.com/llvm/llvm-project/issues/58776
|
||||
---
|
||||
llvm/docs/AliasAnalysis.rst | 26 +++-----
|
||||
llvm/include/llvm/Analysis/AliasAnalysis.h | 51 ++++-----------
|
||||
.../llvm/Analysis/BasicAliasAnalysis.h | 12 +---
|
||||
.../llvm/Analysis/ObjCARCAliasAnalysis.h | 4 +-
|
||||
.../llvm/Analysis/TypeBasedAliasAnalysis.h | 4 +-
|
||||
llvm/lib/Analysis/AliasAnalysis.cpp | 63 +++++++++----------
|
||||
llvm/lib/Analysis/BasicAliasAnalysis.cpp | 43 ++++---------
|
||||
.../lib/Analysis/MemoryDependenceAnalysis.cpp | 2 +-
|
||||
llvm/lib/Analysis/MemorySSA.cpp | 5 +-
|
||||
llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp | 19 +++---
|
||||
llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp | 14 ++---
|
||||
.../lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp | 47 ++++++++++++--
|
||||
llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h | 4 +-
|
||||
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 7 +--
|
||||
.../InstCombine/InstCombineCalls.cpp | 4 +-
|
||||
.../InstCombineLoadStoreAlloca.cpp | 33 +++++-----
|
||||
llvm/lib/Transforms/Scalar/LICM.cpp | 2 +-
|
||||
.../lib/Transforms/Scalar/LoopPredication.cpp | 2 +-
|
||||
llvm/test/Analysis/BasicAA/constant-memory.ll | 14 +++--
|
||||
.../InstCombine/memcpy-from-global.ll | 6 +-
|
||||
llvm/test/Transforms/InstCombine/store.ll | 4 +-
|
||||
21 files changed, 168 insertions(+), 198 deletions(-)
|
||||
|
||||
diff --git a/llvm/docs/AliasAnalysis.rst b/llvm/docs/AliasAnalysis.rst
|
||||
index 046dd24d7332..b9a8a3a4eb52 100644
|
||||
--- a/llvm/docs/AliasAnalysis.rst
|
||||
+++ b/llvm/docs/AliasAnalysis.rst
|
||||
@@ -161,24 +161,14 @@ Other useful ``AliasAnalysis`` methods
|
||||
Several other tidbits of information are often collected by various alias
|
||||
analysis implementations and can be put to good use by various clients.
|
||||
|
||||
-The ``getModRefInfoMask`` method
|
||||
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
-
|
||||
-The ``getModRefInfoMask`` method returns a bound on Mod/Ref information for
|
||||
-the supplied pointer, based on knowledge about whether the pointer points to
|
||||
-globally-constant memory (for which it returns ``NoModRef``) or
|
||||
-locally-invariant memory (for which it returns ``Ref``). Globally-constant
|
||||
-memory includes functions, constant global variables, and the null pointer.
|
||||
-Locally-invariant memory is memory that we know is invariant for the lifetime
|
||||
-of its SSA value, but not necessarily for the life of the program: for example,
|
||||
-the memory pointed to by ``readonly`` ``noalias`` parameters is known-invariant
|
||||
-for the duration of the corresponding function call. Given Mod/Ref information
|
||||
-``MRI`` for a memory location ``Loc``, ``MRI`` can be refined with a statement
|
||||
-like ``MRI &= AA.getModRefInfoMask(Loc);``. Another useful idiom is
|
||||
-``isModSet(AA.getModRefInfoMask(Loc))``; this checks to see if the given
|
||||
-location can be modified at all. For convenience, there is also a method
|
||||
-``pointsToConstantMemory(Loc)``; this is synonymous with
|
||||
-``isNoModRef(AA.getModRefInfoMask(Loc))``.
|
||||
+The ``pointsToConstantMemory`` method
|
||||
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
+
|
||||
+The ``pointsToConstantMemory`` method returns true if and only if the analysis
|
||||
+can prove that the pointer only points to unchanging memory locations
|
||||
+(functions, constant global variables, and the null pointer). This information
|
||||
+can be used to refine mod/ref information: it is impossible for an unchanging
|
||||
+memory location to be modified.
|
||||
|
||||
.. _never access memory or only read memory:
|
||||
|
||||
diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h
|
||||
index a6c7da910121..a2d65e53810a 100644
|
||||
--- a/llvm/include/llvm/Analysis/AliasAnalysis.h
|
||||
+++ b/llvm/include/llvm/Analysis/AliasAnalysis.h
|
||||
@@ -359,9 +359,7 @@ public:
|
||||
|
||||
/// Checks whether the given location points to constant memory, or if
|
||||
/// \p OrLocal is true whether it points to a local alloca.
|
||||
- bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false) {
|
||||
- return isNoModRef(getModRefInfoMask(Loc, OrLocal));
|
||||
- }
|
||||
+ bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false);
|
||||
|
||||
/// A convenience wrapper around the primary \c pointsToConstantMemory
|
||||
/// interface.
|
||||
@@ -374,22 +372,6 @@ public:
|
||||
/// \name Simple mod/ref information
|
||||
/// @{
|
||||
|
||||
- /// Returns a bitmask that should be unconditionally applied to the ModRef
|
||||
- /// info of a memory location. This allows us to eliminate Mod and/or Ref
|
||||
- /// from the ModRef info based on the knowledge that the memory location
|
||||
- /// points to constant and/or locally-invariant memory.
|
||||
- ///
|
||||
- /// If IgnoreLocals is true, then this method returns NoModRef for memory
|
||||
- /// that points to a local alloca.
|
||||
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
|
||||
- bool IgnoreLocals = false);
|
||||
-
|
||||
- /// A convenience wrapper around the primary \c getModRefInfoMask
|
||||
- /// interface.
|
||||
- ModRefInfo getModRefInfoMask(const Value *P, bool IgnoreLocals = false) {
|
||||
- return getModRefInfoMask(MemoryLocation::getBeforeOrAfter(P), IgnoreLocals);
|
||||
- }
|
||||
-
|
||||
/// Get the ModRef info associated with a pointer argument of a call. The
|
||||
/// result's bits are set to indicate the allowed aliasing ModRef kinds. Note
|
||||
/// that these bits do not necessarily account for the overall behavior of
|
||||
@@ -536,8 +518,6 @@ public:
|
||||
AAQueryInfo &AAQI);
|
||||
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
bool OrLocal = false);
|
||||
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals = false);
|
||||
ModRefInfo getModRefInfo(const Instruction *I, const CallBase *Call2,
|
||||
AAQueryInfo &AAQIP);
|
||||
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
|
||||
@@ -605,10 +585,6 @@ public:
|
||||
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false) {
|
||||
return AA.pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
}
|
||||
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
|
||||
- bool IgnoreLocals = false) {
|
||||
- return AA.getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
- }
|
||||
ModRefInfo getModRefInfo(const Instruction *I,
|
||||
const Optional<MemoryLocation> &OptLoc) {
|
||||
return AA.getModRefInfo(I, OptLoc, AAQI);
|
||||
@@ -665,19 +641,16 @@ public:
|
||||
virtual AliasResult alias(const MemoryLocation &LocA,
|
||||
const MemoryLocation &LocB, AAQueryInfo &AAQI) = 0;
|
||||
|
||||
+ /// Checks whether the given location points to constant memory, or if
|
||||
+ /// \p OrLocal is true whether it points to a local alloca.
|
||||
+ virtual bool pointsToConstantMemory(const MemoryLocation &Loc,
|
||||
+ AAQueryInfo &AAQI, bool OrLocal) = 0;
|
||||
+
|
||||
/// @}
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// \name Simple mod/ref information
|
||||
/// @{
|
||||
|
||||
- /// Returns a bitmask that should be unconditionally applied to the ModRef
|
||||
- /// info of a memory location. This allows us to eliminate Mod and/or Ref from
|
||||
- /// the ModRef info based on the knowledge that the memory location points to
|
||||
- /// constant and/or locally-invariant memory.
|
||||
- virtual ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
|
||||
- AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals) = 0;
|
||||
-
|
||||
/// Get the ModRef info associated with a pointer argument of a callsite. The
|
||||
/// result's bits are set to indicate the allowed aliasing ModRef kinds. Note
|
||||
/// that these bits do not necessarily account for the overall behavior of
|
||||
@@ -726,9 +699,9 @@ public:
|
||||
return Result.alias(LocA, LocB, AAQI);
|
||||
}
|
||||
|
||||
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals) override {
|
||||
- return Result.getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
+ bool OrLocal) override {
|
||||
+ return Result.pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
}
|
||||
|
||||
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) override {
|
||||
@@ -781,9 +754,9 @@ public:
|
||||
return AliasResult::MayAlias;
|
||||
}
|
||||
|
||||
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals) {
|
||||
- return ModRefInfo::ModRef;
|
||||
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
+ bool OrLocal) {
|
||||
+ return false;
|
||||
}
|
||||
|
||||
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
|
||||
diff --git a/llvm/include/llvm/Analysis/BasicAliasAnalysis.h b/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
|
||||
index a2909f46e3ba..8f4a8d4a8d8b 100644
|
||||
--- a/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
|
||||
+++ b/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
|
||||
@@ -75,15 +75,9 @@ public:
|
||||
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
|
||||
AAQueryInfo &AAQI);
|
||||
|
||||
- /// Returns a bitmask that should be unconditionally applied to the ModRef
|
||||
- /// info of a memory location. This allows us to eliminate Mod and/or Ref
|
||||
- /// from the ModRef info based on the knowledge that the memory location
|
||||
- /// points to constant and/or locally-invariant memory.
|
||||
- ///
|
||||
- /// If IgnoreLocals is true, then this method returns NoModRef for memory
|
||||
- /// that points to a local alloca.
|
||||
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals = false);
|
||||
+ /// Chases pointers until we find a (constant global) or not.
|
||||
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
+ bool OrLocal);
|
||||
|
||||
/// Get the location associated with a pointer argument of a callsite.
|
||||
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
|
||||
diff --git a/llvm/include/llvm/Analysis/ObjCARCAliasAnalysis.h b/llvm/include/llvm/Analysis/ObjCARCAliasAnalysis.h
|
||||
index 790fbaf07e7f..ba8b28a5adda 100644
|
||||
--- a/llvm/include/llvm/Analysis/ObjCARCAliasAnalysis.h
|
||||
+++ b/llvm/include/llvm/Analysis/ObjCARCAliasAnalysis.h
|
||||
@@ -52,8 +52,8 @@ public:
|
||||
|
||||
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
|
||||
AAQueryInfo &AAQI);
|
||||
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals);
|
||||
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
+ bool OrLocal);
|
||||
|
||||
using AAResultBase::getMemoryEffects;
|
||||
MemoryEffects getMemoryEffects(const Function *F);
|
||||
diff --git a/llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h b/llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h
|
||||
index 791ec65990e2..2e7af99ed495 100644
|
||||
--- a/llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h
|
||||
+++ b/llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h
|
||||
@@ -40,8 +40,8 @@ public:
|
||||
|
||||
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
|
||||
AAQueryInfo &AAQI);
|
||||
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals);
|
||||
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
+ bool OrLocal);
|
||||
MemoryEffects getMemoryEffects(const CallBase *Call, AAQueryInfo &AAQI);
|
||||
MemoryEffects getMemoryEffects(const Function *F);
|
||||
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
|
||||
diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp
|
||||
index 4f27acade05a..6b8ad367b54e 100644
|
||||
--- a/llvm/lib/Analysis/AliasAnalysis.cpp
|
||||
+++ b/llvm/lib/Analysis/AliasAnalysis.cpp
|
||||
@@ -147,25 +147,19 @@ AliasResult AAResults::alias(const MemoryLocation &LocA,
|
||||
return Result;
|
||||
}
|
||||
|
||||
-ModRefInfo AAResults::getModRefInfoMask(const MemoryLocation &Loc,
|
||||
- bool IgnoreLocals) {
|
||||
+bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
|
||||
+ bool OrLocal) {
|
||||
SimpleAAQueryInfo AAQIP(*this);
|
||||
- return getModRefInfoMask(Loc, AAQIP, IgnoreLocals);
|
||||
+ return pointsToConstantMemory(Loc, AAQIP, OrLocal);
|
||||
}
|
||||
|
||||
-ModRefInfo AAResults::getModRefInfoMask(const MemoryLocation &Loc,
|
||||
- AAQueryInfo &AAQI, bool IgnoreLocals) {
|
||||
- ModRefInfo Result = ModRefInfo::ModRef;
|
||||
-
|
||||
- for (const auto &AA : AAs) {
|
||||
- Result &= AA->getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
-
|
||||
- // Early-exit the moment we reach the bottom of the lattice.
|
||||
- if (isNoModRef(Result))
|
||||
- return ModRefInfo::NoModRef;
|
||||
- }
|
||||
+bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
|
||||
+ AAQueryInfo &AAQI, bool OrLocal) {
|
||||
+ for (const auto &AA : AAs)
|
||||
+ if (AA->pointsToConstantMemory(Loc, AAQI, OrLocal))
|
||||
+ return true;
|
||||
|
||||
- return Result;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
ModRefInfo AAResults::getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
|
||||
@@ -254,11 +248,10 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
|
||||
|
||||
Result &= ArgMR | OtherMR;
|
||||
|
||||
- // Apply the ModRef mask. This ensures that if Loc is a constant memory
|
||||
- // location, we take into account the fact that the call definitely could not
|
||||
+ // If Loc is a constant memory location, the call definitely could not
|
||||
// modify the memory location.
|
||||
- if (!isNoModRef(Result))
|
||||
- Result &= getModRefInfoMask(Loc);
|
||||
+ if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false))
|
||||
+ Result &= ModRefInfo::Ref;
|
||||
|
||||
return Result;
|
||||
}
|
||||
@@ -496,11 +489,9 @@ ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
|
||||
if (AR == AliasResult::NoAlias)
|
||||
return ModRefInfo::NoModRef;
|
||||
|
||||
- // Examine the ModRef mask. If Mod isn't present, then return NoModRef.
|
||||
- // This ensures that if Loc is a constant memory location, we take into
|
||||
- // account the fact that the store definitely could not modify the memory
|
||||
- // location.
|
||||
- if (!isModSet(getModRefInfoMask(Loc)))
|
||||
+ // If the pointer is a pointer to constant memory, then it could not have
|
||||
+ // been modified by this store.
|
||||
+ if (pointsToConstantMemory(Loc, AAQI))
|
||||
return ModRefInfo::NoModRef;
|
||||
}
|
||||
|
||||
@@ -511,11 +502,10 @@ ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
|
||||
ModRefInfo AAResults::getModRefInfo(const FenceInst *S,
|
||||
const MemoryLocation &Loc,
|
||||
AAQueryInfo &AAQI) {
|
||||
- // All we know about a fence instruction is what we get from the ModRef
|
||||
- // mask: if Loc is a constant memory location, the fence definitely could
|
||||
- // not modify it.
|
||||
- if (Loc.Ptr)
|
||||
- return getModRefInfoMask(Loc);
|
||||
+ // If we know that the location is a constant memory location, the fence
|
||||
+ // cannot modify this location.
|
||||
+ if (Loc.Ptr && pointsToConstantMemory(Loc, AAQI))
|
||||
+ return ModRefInfo::Ref;
|
||||
return ModRefInfo::ModRef;
|
||||
}
|
||||
|
||||
@@ -529,9 +519,10 @@ ModRefInfo AAResults::getModRefInfo(const VAArgInst *V,
|
||||
if (AR == AliasResult::NoAlias)
|
||||
return ModRefInfo::NoModRef;
|
||||
|
||||
- // If the pointer is a pointer to invariant memory, then it could not have
|
||||
+ // If the pointer is a pointer to constant memory, then it could not have
|
||||
// been modified by this va_arg.
|
||||
- return getModRefInfoMask(Loc, AAQI);
|
||||
+ if (pointsToConstantMemory(Loc, AAQI))
|
||||
+ return ModRefInfo::NoModRef;
|
||||
}
|
||||
|
||||
// Otherwise, a va_arg reads and writes.
|
||||
@@ -542,9 +533,10 @@ ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad,
|
||||
const MemoryLocation &Loc,
|
||||
AAQueryInfo &AAQI) {
|
||||
if (Loc.Ptr) {
|
||||
- // If the pointer is a pointer to invariant memory,
|
||||
+ // If the pointer is a pointer to constant memory,
|
||||
// then it could not have been modified by this catchpad.
|
||||
- return getModRefInfoMask(Loc, AAQI);
|
||||
+ if (pointsToConstantMemory(Loc, AAQI))
|
||||
+ return ModRefInfo::NoModRef;
|
||||
}
|
||||
|
||||
// Otherwise, a catchpad reads and writes.
|
||||
@@ -555,9 +547,10 @@ ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet,
|
||||
const MemoryLocation &Loc,
|
||||
AAQueryInfo &AAQI) {
|
||||
if (Loc.Ptr) {
|
||||
- // If the pointer is a pointer to invariant memory,
|
||||
+ // If the pointer is a pointer to constant memory,
|
||||
// then it could not have been modified by this catchpad.
|
||||
- return getModRefInfoMask(Loc, AAQI);
|
||||
+ if (pointsToConstantMemory(Loc, AAQI))
|
||||
+ return ModRefInfo::NoModRef;
|
||||
}
|
||||
|
||||
// Otherwise, a catchret reads and writes.
|
||||
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
|
||||
index 2bbc2486fec0..fa03a82f78b2 100644
|
||||
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
|
||||
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
|
||||
@@ -676,46 +676,33 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
|
||||
return Decomposed;
|
||||
}
|
||||
|
||||
-ModRefInfo BasicAAResult::getModRefInfoMask(const MemoryLocation &Loc,
|
||||
- AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals) {
|
||||
+/// Returns whether the given pointer value points to memory that is local to
|
||||
+/// the function, with global constants being considered local to all
|
||||
+/// functions.
|
||||
+bool BasicAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
|
||||
+ AAQueryInfo &AAQI, bool OrLocal) {
|
||||
assert(Visited.empty() && "Visited must be cleared after use!");
|
||||
- auto _ = make_scope_exit([&] { Visited.clear(); });
|
||||
+ auto _ = make_scope_exit([&]{ Visited.clear(); });
|
||||
|
||||
unsigned MaxLookup = 8;
|
||||
SmallVector<const Value *, 16> Worklist;
|
||||
Worklist.push_back(Loc.Ptr);
|
||||
- ModRefInfo Result = ModRefInfo::NoModRef;
|
||||
-
|
||||
do {
|
||||
const Value *V = getUnderlyingObject(Worklist.pop_back_val());
|
||||
if (!Visited.insert(V).second)
|
||||
continue;
|
||||
|
||||
- // Ignore allocas if we were instructed to do so.
|
||||
- if (IgnoreLocals && isa<AllocaInst>(V))
|
||||
+ // An alloca instruction defines local memory.
|
||||
+ if (OrLocal && isa<AllocaInst>(V))
|
||||
continue;
|
||||
|
||||
- // If the location points to memory that is known to be invariant for
|
||||
- // the life of the underlying SSA value, then we can exclude Mod from
|
||||
- // the set of valid memory effects.
|
||||
- //
|
||||
- // An argument that is marked readonly and noalias is known to be
|
||||
- // invariant while that function is executing.
|
||||
- if (const Argument *Arg = dyn_cast<Argument>(V)) {
|
||||
- if (Arg->hasNoAliasAttr() && Arg->onlyReadsMemory()) {
|
||||
- Result |= ModRefInfo::Ref;
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- // A global constant can't be mutated.
|
||||
+ // A global constant counts as local memory for our purposes.
|
||||
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
|
||||
// Note: this doesn't require GV to be "ODR" because it isn't legal for a
|
||||
// global to be marked constant in some modules and non-constant in
|
||||
// others. GV may even be a declaration, not a definition.
|
||||
if (!GV->isConstant())
|
||||
- return AAResultBase::getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
+ return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -731,20 +718,16 @@ ModRefInfo BasicAAResult::getModRefInfoMask(const MemoryLocation &Loc,
|
||||
if (const PHINode *PN = dyn_cast<PHINode>(V)) {
|
||||
// Don't bother inspecting phi nodes with many operands.
|
||||
if (PN->getNumIncomingValues() > MaxLookup)
|
||||
- return AAResultBase::getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
+ return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
append_range(Worklist, PN->incoming_values());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise be conservative.
|
||||
- return AAResultBase::getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
+ return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
} while (!Worklist.empty() && --MaxLookup);
|
||||
|
||||
- // If we hit the maximum number of instructions to examine, be conservative.
|
||||
- if (!Worklist.empty())
|
||||
- return AAResultBase::getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
-
|
||||
- return Result;
|
||||
+ return Worklist.empty();
|
||||
}
|
||||
|
||||
static bool isIntrinsicCall(const CallBase *Call, Intrinsic::ID IID) {
|
||||
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
|
||||
index f0446b21e288..d9bae54b05be 100644
|
||||
--- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
|
||||
+++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
|
||||
@@ -525,7 +525,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
|
||||
}
|
||||
|
||||
// Stores don't alias loads from read-only memory.
|
||||
- if (!isModSet(BatchAA.getModRefInfoMask(LoadLoc)))
|
||||
+ if (BatchAA.pointsToConstantMemory(LoadLoc))
|
||||
continue;
|
||||
|
||||
// Stores depend on may/must aliased loads.
|
||||
diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp
|
||||
index 1660321990bf..461886650261 100644
|
||||
--- a/llvm/lib/Analysis/MemorySSA.cpp
|
||||
+++ b/llvm/lib/Analysis/MemorySSA.cpp
|
||||
@@ -378,10 +378,9 @@ static bool isUseTriviallyOptimizableToLiveOnEntry(AliasAnalysisType &AA,
|
||||
const Instruction *I) {
|
||||
// If the memory can't be changed, then loads of the memory can't be
|
||||
// clobbered.
|
||||
- if (auto *LI = dyn_cast<LoadInst>(I)) {
|
||||
+ if (auto *LI = dyn_cast<LoadInst>(I))
|
||||
return I->hasMetadata(LLVMContext::MD_invariant_load) ||
|
||||
- !isModSet(AA.getModRefInfoMask(MemoryLocation::get(LI)));
|
||||
- }
|
||||
+ AA.pointsToConstantMemory(MemoryLocation::get(LI));
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp b/llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp
|
||||
index 93d56931d01c..76f6a74384b4 100644
|
||||
--- a/llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp
|
||||
+++ b/llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp
|
||||
@@ -68,29 +68,28 @@ AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA,
|
||||
return AliasResult::MayAlias;
|
||||
}
|
||||
|
||||
-ModRefInfo ObjCARCAAResult::getModRefInfoMask(const MemoryLocation &Loc,
|
||||
- AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals) {
|
||||
+bool ObjCARCAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
|
||||
+ AAQueryInfo &AAQI, bool OrLocal) {
|
||||
if (!EnableARCOpts)
|
||||
- return AAResultBase::getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
+ return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
|
||||
// First, strip off no-ops, including ObjC-specific no-ops, and try making
|
||||
// a precise alias query.
|
||||
const Value *S = GetRCIdentityRoot(Loc.Ptr);
|
||||
- if (isNoModRef(AAResultBase::getModRefInfoMask(
|
||||
- MemoryLocation(S, Loc.Size, Loc.AATags), AAQI, IgnoreLocals)))
|
||||
- return ModRefInfo::NoModRef;
|
||||
+ if (AAResultBase::pointsToConstantMemory(
|
||||
+ MemoryLocation(S, Loc.Size, Loc.AATags), AAQI, OrLocal))
|
||||
+ return true;
|
||||
|
||||
// If that failed, climb to the underlying object, including climbing through
|
||||
// ObjC-specific no-ops, and try making an imprecise alias query.
|
||||
const Value *U = GetUnderlyingObjCPtr(S);
|
||||
if (U != S)
|
||||
- return AAResultBase::getModRefInfoMask(MemoryLocation::getBeforeOrAfter(U),
|
||||
- AAQI, IgnoreLocals);
|
||||
+ return AAResultBase::pointsToConstantMemory(
|
||||
+ MemoryLocation::getBeforeOrAfter(U), AAQI, OrLocal);
|
||||
|
||||
// If that failed, fail. We don't need to chain here, since that's covered
|
||||
// by the earlier precise query.
|
||||
- return ModRefInfo::ModRef;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
MemoryEffects ObjCARCAAResult::getMemoryEffects(const Function *F) {
|
||||
diff --git a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp
|
||||
index b7121ea8326b..8360246915e4 100644
|
||||
--- a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp
|
||||
+++ b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp
|
||||
@@ -385,23 +385,23 @@ AliasResult TypeBasedAAResult::alias(const MemoryLocation &LocA,
|
||||
return AliasResult::NoAlias;
|
||||
}
|
||||
|
||||
-ModRefInfo TypeBasedAAResult::getModRefInfoMask(const MemoryLocation &Loc,
|
||||
- AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals) {
|
||||
+bool TypeBasedAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
|
||||
+ AAQueryInfo &AAQI,
|
||||
+ bool OrLocal) {
|
||||
if (!EnableTBAA)
|
||||
- return AAResultBase::getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
+ return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
|
||||
const MDNode *M = Loc.AATags.TBAA;
|
||||
if (!M)
|
||||
- return AAResultBase::getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
+ return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
|
||||
// If this is an "immutable" type, we can assume the pointer is pointing
|
||||
// to constant memory.
|
||||
if ((!isStructPathTBAA(M) && TBAANode(M).isTypeImmutable()) ||
|
||||
(isStructPathTBAA(M) && TBAAStructTagNode(M).isTypeImmutable()))
|
||||
- return ModRefInfo::NoModRef;
|
||||
+ return true;
|
||||
|
||||
- return AAResultBase::getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
+ return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
}
|
||||
|
||||
MemoryEffects TypeBasedAAResult::getMemoryEffects(const CallBase *Call,
|
||||
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp
|
||||
index e97c993f4b25..dd3eb3849eac 100644
|
||||
--- a/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp
|
||||
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp
|
||||
@@ -124,19 +124,54 @@ AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
|
||||
return AAResultBase::alias(LocA, LocB, AAQI);
|
||||
}
|
||||
|
||||
-ModRefInfo AMDGPUAAResult::getModRefInfoMask(const MemoryLocation &Loc,
|
||||
- AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals) {
|
||||
+bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
|
||||
+ AAQueryInfo &AAQI, bool OrLocal) {
|
||||
unsigned AS = Loc.Ptr->getType()->getPointerAddressSpace();
|
||||
if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
|
||||
AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT)
|
||||
- return ModRefInfo::NoModRef;
|
||||
+ return true;
|
||||
|
||||
const Value *Base = getUnderlyingObject(Loc.Ptr);
|
||||
AS = Base->getType()->getPointerAddressSpace();
|
||||
if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
|
||||
AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT)
|
||||
- return ModRefInfo::NoModRef;
|
||||
+ return true;
|
||||
+
|
||||
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
|
||||
+ if (GV->isConstant())
|
||||
+ return true;
|
||||
+ } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
|
||||
+ const Function *F = Arg->getParent();
|
||||
+
|
||||
+ // Only assume constant memory for arguments on kernels.
|
||||
+ switch (F->getCallingConv()) {
|
||||
+ default:
|
||||
+ return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
+ case CallingConv::AMDGPU_LS:
|
||||
+ case CallingConv::AMDGPU_HS:
|
||||
+ case CallingConv::AMDGPU_ES:
|
||||
+ case CallingConv::AMDGPU_GS:
|
||||
+ case CallingConv::AMDGPU_VS:
|
||||
+ case CallingConv::AMDGPU_PS:
|
||||
+ case CallingConv::AMDGPU_CS:
|
||||
+ case CallingConv::AMDGPU_KERNEL:
|
||||
+ case CallingConv::SPIR_KERNEL:
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- return AAResultBase::getModRefInfoMask(Loc, AAQI, IgnoreLocals);
|
||||
+ unsigned ArgNo = Arg->getArgNo();
|
||||
+ /* On an argument, ReadOnly attribute indicates that the function does
|
||||
+ not write through this pointer argument, even though it may write
|
||||
+ to the memory that the pointer points to.
|
||||
+ On an argument, ReadNone attribute indicates that the function does
|
||||
+ not dereference that pointer argument, even though it may read or write
|
||||
+ the memory that the pointer points to if accessed through other pointers.
|
||||
+ */
|
||||
+ if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
|
||||
+ (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
|
||||
+ F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
|
||||
}
|
||||
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h
|
||||
index acd437e8987c..db2372d911b1 100644
|
||||
--- a/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h
|
||||
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h
|
||||
@@ -38,8 +38,8 @@ public:
|
||||
|
||||
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
|
||||
AAQueryInfo &AAQI);
|
||||
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
- bool IgnoreLocals);
|
||||
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
|
||||
+ bool OrLocal);
|
||||
};
|
||||
|
||||
/// Analysis pass providing a never-invalidated alias analysis result.
|
||||
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
|
||||
index a187cb1e4790..932feea044b3 100644
|
||||
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
|
||||
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
|
||||
@@ -140,14 +140,13 @@ static MemoryEffects checkFunctionMemoryAccess(Function &F, bool ThisBody,
|
||||
ME |= MemoryEffects::argMemOnly(ModRefInfo::ModRef);
|
||||
|
||||
auto AddLocAccess = [&](const MemoryLocation &Loc, ModRefInfo MR) {
|
||||
- // Ignore accesses to known-invariant or local memory.
|
||||
- MR &= AAR.getModRefInfoMask(Loc, /*IgnoreLocal=*/true);
|
||||
- if (isNoModRef(MR))
|
||||
+ // Ignore accesses to local memory.
|
||||
+ if (AAR.pointsToConstantMemory(Loc, /*OrLocal=*/true))
|
||||
return;
|
||||
|
||||
const Value *UO = getUnderlyingObject(Loc.Ptr);
|
||||
assert(!isa<AllocaInst>(UO) &&
|
||||
- "Should have been handled by getModRefInfoMask()");
|
||||
+ "Should have been handled by pointsToConstantMemory()");
|
||||
if (isa<Argument>(UO)) {
|
||||
ME |= MemoryEffects::argMemOnly(MR);
|
||||
return;
|
||||
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
|
||||
index 3df5af6ac517..5adb898f2607 100644
|
||||
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
|
||||
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
|
||||
@@ -135,7 +135,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) {
|
||||
// If we have a store to a location which is known constant, we can conclude
|
||||
// that the store must be storing the constant value (else the memory
|
||||
// wouldn't be constant), and this must be a noop.
|
||||
- if (!isModSet(AA->getModRefInfoMask(MI->getDest()))) {
|
||||
+ if (AA->pointsToConstantMemory(MI->getDest())) {
|
||||
// Set the size of the copy to 0, it will be deleted on the next iteration.
|
||||
MI->setLength(Constant::getNullValue(MI->getLength()->getType()));
|
||||
return MI;
|
||||
@@ -252,7 +252,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
|
||||
// If we have a store to a location which is known constant, we can conclude
|
||||
// that the store must be storing the constant value (else the memory
|
||||
// wouldn't be constant), and this must be a noop.
|
||||
- if (!isModSet(AA->getModRefInfoMask(MI->getDest()))) {
|
||||
+ if (AA->pointsToConstantMemory(MI->getDest())) {
|
||||
// Set the size of the copy to 0, it will be deleted on the next iteration.
|
||||
MI->setLength(Constant::getNullValue(MI->getLength()->getType()));
|
||||
return MI;
|
||||
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
|
||||
index c4efd0301711..9acfa612bc27 100644
|
||||
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
|
||||
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
|
||||
@@ -31,20 +31,20 @@ using namespace PatternMatch;
|
||||
STATISTIC(NumDeadStore, "Number of dead stores eliminated");
|
||||
STATISTIC(NumGlobalCopies, "Number of allocas copied from constant global");
|
||||
|
||||
-/// isOnlyCopiedFromConstantMemory - Recursively walk the uses of a (derived)
|
||||
+/// isOnlyCopiedFromConstantGlobal - Recursively walk the uses of a (derived)
|
||||
/// pointer to an alloca. Ignore any reads of the pointer, return false if we
|
||||
/// see any stores or other unknown uses. If we see pointer arithmetic, keep
|
||||
/// track of whether it moves the pointer (with IsOffset) but otherwise traverse
|
||||
/// the uses. If we see a memcpy/memmove that targets an unoffseted pointer to
|
||||
-/// the alloca, and if the source pointer is a pointer to a constant memory
|
||||
-/// location, we can optimize this.
|
||||
+/// the alloca, and if the source pointer is a pointer to a constant global, we
|
||||
+/// can optimize this.
|
||||
static bool
|
||||
isOnlyCopiedFromConstantMemory(AAResults *AA, AllocaInst *V,
|
||||
MemTransferInst *&TheCopy,
|
||||
SmallVectorImpl<Instruction *> &ToDelete) {
|
||||
// We track lifetime intrinsics as we encounter them. If we decide to go
|
||||
- // ahead and replace the value with the memory location, this lets the caller
|
||||
- // quickly eliminate the markers.
|
||||
+ // ahead and replace the value with the global, this lets the caller quickly
|
||||
+ // eliminate the markers.
|
||||
|
||||
SmallVector<std::pair<Value *, bool>, 35> ValuesToInspect;
|
||||
ValuesToInspect.emplace_back(V, false);
|
||||
@@ -131,8 +131,8 @@ isOnlyCopiedFromConstantMemory(AAResults *AA, AllocaInst *V,
|
||||
// If the memintrinsic isn't using the alloca as the dest, reject it.
|
||||
if (U.getOperandNo() != 0) return false;
|
||||
|
||||
- // If the source of the memcpy/move is not constant, reject it.
|
||||
- if (isModSet(AA->getModRefInfoMask(MI->getSource())))
|
||||
+ // If the source of the memcpy/move is not a constant global, reject it.
|
||||
+ if (!AA->pointsToConstantMemory(MI->getSource()))
|
||||
return false;
|
||||
|
||||
// Otherwise, the transform is safe. Remember the copy instruction.
|
||||
@@ -142,10 +142,9 @@ isOnlyCopiedFromConstantMemory(AAResults *AA, AllocaInst *V,
|
||||
return true;
|
||||
}
|
||||
|
||||
-/// isOnlyCopiedFromConstantMemory - Return true if the specified alloca is only
|
||||
-/// modified by a copy from a constant memory location. If we can prove this, we
|
||||
-/// can replace any uses of the alloca with uses of the memory location
|
||||
-/// directly.
|
||||
+/// isOnlyCopiedFromConstantGlobal - Return true if the specified alloca is only
|
||||
+/// modified by a copy from a constant global. If we can prove this, we can
|
||||
+/// replace any uses of the alloca with uses of the global directly.
|
||||
static MemTransferInst *
|
||||
isOnlyCopiedFromConstantMemory(AAResults *AA,
|
||||
AllocaInst *AI,
|
||||
@@ -399,11 +398,11 @@ Instruction *InstCombinerImpl::visitAllocaInst(AllocaInst &AI) {
|
||||
}
|
||||
|
||||
// Check to see if this allocation is only modified by a memcpy/memmove from
|
||||
- // a memory location whose alignment is equal to or exceeds that of the
|
||||
- // allocation. If this is the case, we can change all users to use the
|
||||
- // constant memory location instead. This is commonly produced by the CFE by
|
||||
- // constructs like "void foo() { int A[] = {1,2,3,4,5,6,7,8,9...}; }" if 'A'
|
||||
- // is only subsequently read.
|
||||
+ // a constant whose alignment is equal to or exceeds that of the allocation.
|
||||
+ // If this is the case, we can change all users to use the constant global
|
||||
+ // instead. This is commonly produced by the CFE by constructs like "void
|
||||
+ // foo() { int A[] = {1,2,3,4,5,6,7,8,9...}; }" if 'A' is only subsequently
|
||||
+ // read.
|
||||
SmallVector<Instruction *, 4> ToDelete;
|
||||
if (MemTransferInst *Copy = isOnlyCopiedFromConstantMemory(AA, &AI, ToDelete)) {
|
||||
Value *TheSrc = Copy->getSource();
|
||||
@@ -1379,7 +1378,7 @@ Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) {
|
||||
// If we have a store to a location which is known constant, we can conclude
|
||||
// that the store must be storing the constant value (else the memory
|
||||
// wouldn't be constant), and this must be a noop.
|
||||
- if (!isModSet(AA->getModRefInfoMask(Ptr)))
|
||||
+ if (AA->pointsToConstantMemory(Ptr))
|
||||
return eraseInstFromFunction(SI);
|
||||
|
||||
// Do really simple DSE, to catch cases where there are several consecutive
|
||||
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
|
||||
index 001937cc1670..cddee7d3eb07 100644
|
||||
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
|
||||
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
|
||||
@@ -1161,7 +1161,7 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
|
||||
|
||||
// Loads from constant memory are always safe to move, even if they end up
|
||||
// in the same alias set as something that ends up being modified.
|
||||
- if (!isModSet(AA->getModRefInfoMask(LI->getOperand(0))))
|
||||
+ if (AA->pointsToConstantMemory(LI->getOperand(0)))
|
||||
return true;
|
||||
if (LI->hasMetadata(LLVMContext::MD_invariant_load))
|
||||
return true;
|
||||
diff --git a/llvm/lib/Transforms/Scalar/LoopPredication.cpp b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
|
||||
index 1e4060abeb88..36b0020b9ce9 100644
|
||||
--- a/llvm/lib/Transforms/Scalar/LoopPredication.cpp
|
||||
+++ b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
|
||||
@@ -569,7 +569,7 @@ bool LoopPredication::isLoopInvariantValue(const SCEV* S) {
|
||||
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S))
|
||||
if (const auto *LI = dyn_cast<LoadInst>(U->getValue()))
|
||||
if (LI->isUnordered() && L->hasLoopInvariantOperands(LI))
|
||||
- if (!isModSet(AA->getModRefInfoMask(LI->getOperand(0))) ||
|
||||
+ if (AA->pointsToConstantMemory(LI->getOperand(0)) ||
|
||||
LI->hasMetadata(LLVMContext::MD_invariant_load))
|
||||
return true;
|
||||
return false;
|
||||
diff --git a/llvm/test/Analysis/BasicAA/constant-memory.ll b/llvm/test/Analysis/BasicAA/constant-memory.ll
|
||||
index 2b197d6dbc71..6ef875d9358e 100644
|
||||
--- a/llvm/test/Analysis/BasicAA/constant-memory.ll
|
||||
+++ b/llvm/test/Analysis/BasicAA/constant-memory.ll
|
||||
@@ -6,16 +6,18 @@ declare void @dummy()
|
||||
|
||||
declare void @foo(ptr)
|
||||
|
||||
+; FIXME: This could be NoModRef
|
||||
; CHECK-LABEL: Function: basic
|
||||
-; CHECK: NoModRef: Ptr: i32* @c <-> call void @dummy()
|
||||
+; CHECK: Just Ref: Ptr: i32* @c <-> call void @dummy()
|
||||
define void @basic(ptr %p) {
|
||||
call void @dummy()
|
||||
load i32, ptr @c
|
||||
ret void
|
||||
}
|
||||
|
||||
+; FIXME: This could be NoModRef
|
||||
; CHECK-LABEL: Function: recphi
|
||||
-; CHECK: NoModRef: Ptr: i32* %p <-> call void @dummy()
|
||||
+; CHECK: Just Ref: Ptr: i32* %p <-> call void @dummy()
|
||||
define void @recphi() {
|
||||
entry:
|
||||
br label %loop
|
||||
@@ -32,20 +34,20 @@ exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
-; Tests that readonly noalias implies !Mod.
|
||||
+; Tests that readonly noalias doesn't imply !Mod yet.
|
||||
;
|
||||
; CHECK-LABEL: Function: readonly_noalias
|
||||
-; CHECK: Just Ref: Ptr: i32* %p <-> call void @foo(ptr %p)
|
||||
+; CHECK: Both ModRef: Ptr: i32* %p <-> call void @foo(ptr %p)
|
||||
define void @readonly_noalias(ptr readonly noalias %p) {
|
||||
call void @foo(ptr %p)
|
||||
load i32, ptr %p
|
||||
ret void
|
||||
}
|
||||
|
||||
-; Tests that readnone noalias implies !Mod.
|
||||
+; Tests that readnone noalias doesn't imply !Mod yet.
|
||||
;
|
||||
; CHECK-LABEL: Function: readnone_noalias
|
||||
-; CHECK: Just Ref: Ptr: i32* %p <-> call void @foo(ptr %p)
|
||||
+; CHECK: Both ModRef: Ptr: i32* %p <-> call void @foo(ptr %p)
|
||||
define void @readnone_noalias(ptr readnone noalias %p) {
|
||||
call void @foo(ptr %p)
|
||||
load i32, ptr %p
|
||||
diff --git a/llvm/test/Transforms/InstCombine/memcpy-from-global.ll b/llvm/test/Transforms/InstCombine/memcpy-from-global.ll
|
||||
index b230c1488f75..cd6dfc4561b9 100644
|
||||
--- a/llvm/test/Transforms/InstCombine/memcpy-from-global.ll
|
||||
+++ b/llvm/test/Transforms/InstCombine/memcpy-from-global.ll
|
||||
@@ -338,10 +338,12 @@ entry:
|
||||
ret float %r
|
||||
}
|
||||
|
||||
-; Tests that we can eliminate allocas copied from readonly noalias pointers.
|
||||
+; Tests that we can't eliminate allocas copied from readonly noalias pointers yet.
|
||||
define void @memcpy_from_readonly_noalias(ptr readonly noalias align 8 dereferenceable(124) %arg) {
|
||||
; CHECK-LABEL: @memcpy_from_readonly_noalias(
|
||||
-; CHECK-NEXT: call void @bar(ptr nonnull [[ARG:%.*]]) #[[ATTR3]]
|
||||
+; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [[T:%.*]], align 8
|
||||
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(124) [[ALLOCA]], ptr noundef nonnull align 8 dereferenceable(124) [[ARG:%.*]], i64 124, i1 false)
|
||||
+; CHECK-NEXT: call void @bar(ptr nonnull [[ALLOCA]]) #[[ATTR3]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%alloca = alloca %T, align 8
|
||||
diff --git a/llvm/test/Transforms/InstCombine/store.ll b/llvm/test/Transforms/InstCombine/store.ll
|
||||
index 95ba64c9e640..7cbe91b44beb 100644
|
||||
--- a/llvm/test/Transforms/InstCombine/store.ll
|
||||
+++ b/llvm/test/Transforms/InstCombine/store.ll
|
||||
@@ -336,10 +336,12 @@ define void @store_to_constant() {
|
||||
ret void
|
||||
}
|
||||
|
||||
-; Delete stores to readonly noalias pointers.
|
||||
+; We can't delete stores to readonly noalias pointers yet.
|
||||
define void @store_to_readonly_noalias(ptr readonly noalias %0) {
|
||||
; CHECK-LABEL: @store_to_readonly_noalias(
|
||||
+; CHECK-NEXT: store i32 3, ptr [[TMP0:%.*]], align 4
|
||||
; CHECK-NEXT: ret void
|
||||
+;
|
||||
store i32 3, ptr %0, align 4
|
||||
ret void
|
||||
}
|
||||
--
|
||||
2.38.1.1.g6d9df9d320
|
||||
|
Загрузка…
Ссылка в новой задаче