summaryrefslogtreecommitdiffstats
path: root/build/build-clang/revert-llvmorg-16-init-9324-g01859da84bad.patch
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /build/build-clang/revert-llvmorg-16-init-9324-g01859da84bad.patch
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'build/build-clang/revert-llvmorg-16-init-9324-g01859da84bad.patch')
-rw-r--r--build/build-clang/revert-llvmorg-16-init-9324-g01859da84bad.patch869
1 files changed, 869 insertions, 0 deletions
diff --git a/build/build-clang/revert-llvmorg-16-init-9324-g01859da84bad.patch b/build/build-clang/revert-llvmorg-16-init-9324-g01859da84bad.patch
new file mode 100644
index 0000000000..c5166b636e
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-16-init-9324-g01859da84bad.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 953e15e358f1..1b15d130967a 100644
+--- a/llvm/include/llvm/Analysis/AliasAnalysis.h
++++ b/llvm/include/llvm/Analysis/AliasAnalysis.h
+@@ -375,9 +375,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.
+@@ -390,22 +388,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
+@@ -555,8 +537,6 @@ public:
+
+ 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,
+@@ -624,10 +604,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 std::optional<MemoryLocation> &OptLoc) {
+ return AA.getModRefInfo(I, OptLoc, AAQI);
+@@ -690,19 +666,16 @@ public:
+ const MemoryLocation &LocB, AAQueryInfo &AAQI,
+ const Instruction *CtxI) = 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
+@@ -751,9 +724,9 @@ public:
+ return Result.alias(LocA, LocB, AAQI, CtxI);
+ }
+
+- 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 {
+@@ -806,9 +779,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 a2735f039a01..397692694322 100644
+--- a/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
++++ b/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
+@@ -73,15 +73,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 1a154c648fe6..ef162ece8a32 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, const Instruction *CtxI);
+- 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 36dd39c033aa..84a2a6a2fdac 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, const Instruction *CtxI);
+- 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);
+diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp
+index 9e24f6b87bdb..5e27808cfdb3 100644
+--- a/llvm/lib/Analysis/AliasAnalysis.cpp
++++ b/llvm/lib/Analysis/AliasAnalysis.cpp
+@@ -146,25 +146,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) {
+@@ -253,11 +247,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;
+ }
+@@ -495,11 +488,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;
+ }
+
+@@ -510,11 +501,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;
+ }
+
+@@ -528,9 +518,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.
+@@ -541,9 +532,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.
+@@ -554,9 +546,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 1ea1d4196f80..edf46664139e 100644
+--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
++++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+@@ -678,46 +678,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;
+ }
+
+@@ -733,20 +720,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 2340015d6517..6a0b123f0b8f 100644
+--- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
++++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
+@@ -524,7 +524,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 0e6a12261e23..c2e2c8d9ec0f 100644
+--- a/llvm/lib/Analysis/MemorySSA.cpp
++++ b/llvm/lib/Analysis/MemorySSA.cpp
+@@ -375,10 +375,9 @@ static bool isUseTriviallyOptimizableToLiveOnEntry(BatchAAResults &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 1ccf792d2f8c..dd9eae428b0a 100644
+--- a/llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp
++++ b/llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp
+@@ -69,29 +69,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 529f3a76d23e..077fbdbe821c 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 8155c895e366..1dd91f2b0be8 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, nullptr);
+ }
+
+-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 8ce7000222fa..140ed12a8f6d 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, const Instruction *CtxI);
+- 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 3f61dbe3354e..cfbceebf66d4 100644
+--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
++++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+@@ -138,14 +138,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 bd3db4534a85..8fad7e8195c8 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;
+@@ -253,7 +253,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 c8226ce2816a..8d58241895b5 100644
+--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
++++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+@@ -36,20 +36,20 @@ static cl::opt<unsigned> MaxCopiedFromConstantUsers(
+ cl::desc("Maximum users to visit in copy from constant transform"),
+ cl::Hidden);
+
+-/// 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.
+
+ using ValueAndIsOffset = PointerIntPair<Value *, 1, bool>;
+ SmallVector<ValueAndIsOffset, 32> Worklist;
+@@ -150,8 +150,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.
+@@ -161,10 +161,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,
+@@ -420,11 +419,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();
+@@ -1401,7 +1400,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 d3739f31bc57..11b96af0a30e 100644
+--- a/llvm/lib/Transforms/Scalar/LICM.cpp
++++ b/llvm/lib/Transforms/Scalar/LICM.cpp
+@@ -1160,7 +1160,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 0492ed5cdb1c..8dd9f0144941 100644
+--- a/llvm/lib/Transforms/Scalar/LoopPredication.cpp
++++ b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
+@@ -570,7 +570,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
+