[AST] Don't merge memory locations in AliasSetTracker (#65731)

This changes the AliasSetTracker to track memory locations instead of
pointers in its alias sets. The motivation for this is outlined in an RFC
posted on LLVM discourse:
https://discourse.llvm.org/t/rfc-dont-merge-memory-locations-in-aliassettracker/73336

In the data structures of the AST implementation, I made the choice to
replace the linked list of `PointerRec` entries (that had to go anyway)
with a simple flat vector of `MemoryLocation` objects, but for the
`AliasSet` objects referenced from a lookup table, I retained the
mechanism of a linked list, reference counting, forwarding, etc. The
data structures could be revised in a follow-up change.
This commit is contained in:
Bruno De Fraine 2024-01-17 15:59:13 +01:00 committed by GitHub
parent 8fb685fb7e
commit 656bf13004
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 486 additions and 686 deletions

View File

@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file defines two classes: AliasSetTracker and AliasSet. These interfaces // This file defines two classes: AliasSetTracker and AliasSet. These interfaces
// are used to classify a collection of pointer references into a maximal number // are used to classify a collection of memory locations into a maximal number
// of disjoint sets. Each AliasSet object constructed by the AliasSetTracker // of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
// object refers to memory disjoint from the other sets. // object refers to memory disjoint from the other sets.
// //
@ -19,7 +19,7 @@
#define LLVM_ANALYSIS_ALIASSETTRACKER_H #define LLVM_ANALYSIS_ALIASSETTRACKER_H
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ilist_node.h"
#include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/MemoryLocation.h"
@ -27,8 +27,6 @@
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueHandle.h"
#include <cassert> #include <cassert>
#include <cstddef>
#include <iterator>
#include <vector> #include <vector>
namespace llvm { namespace llvm {
@ -49,99 +47,12 @@ class Value;
class AliasSet : public ilist_node<AliasSet> { class AliasSet : public ilist_node<AliasSet> {
friend class AliasSetTracker; friend class AliasSetTracker;
class PointerRec {
Value *Val; // The pointer this record corresponds to.
PointerRec **PrevInList = nullptr;
PointerRec *NextInList = nullptr;
AliasSet *AS = nullptr;
LocationSize Size = LocationSize::mapEmpty();
AAMDNodes AAInfo;
// Whether the size for this record has been set at all. This makes no
// guarantees about the size being known.
bool isSizeSet() const { return Size != LocationSize::mapEmpty(); }
public:
PointerRec(Value *V)
: Val(V), AAInfo(DenseMapInfo<AAMDNodes>::getEmptyKey()) {}
Value *getValue() const { return Val; }
PointerRec *getNext() const { return NextInList; }
bool hasAliasSet() const { return AS != nullptr; }
PointerRec** setPrevInList(PointerRec **PIL) {
PrevInList = PIL;
return &NextInList;
}
bool updateSizeAndAAInfo(LocationSize NewSize, const AAMDNodes &NewAAInfo) {
bool SizeChanged = false;
if (NewSize != Size) {
LocationSize OldSize = Size;
Size = isSizeSet() ? Size.unionWith(NewSize) : NewSize;
SizeChanged = OldSize != Size;
}
if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey())
// We don't have a AAInfo yet. Set it to NewAAInfo.
AAInfo = NewAAInfo;
else {
AAMDNodes Intersection(AAInfo.intersect(NewAAInfo));
SizeChanged |= Intersection != AAInfo;
AAInfo = Intersection;
}
return SizeChanged;
}
LocationSize getSize() const {
assert(isSizeSet() && "Getting an unset size!");
return Size;
}
/// Return the AAInfo, or null if there is no information or conflicting
/// information.
AAMDNodes getAAInfo() const {
// If we have missing or conflicting AAInfo, return null.
if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey() ||
AAInfo == DenseMapInfo<AAMDNodes>::getTombstoneKey())
return AAMDNodes();
return AAInfo;
}
AliasSet *getAliasSet(AliasSetTracker &AST) {
assert(AS && "No AliasSet yet!");
if (AS->Forward) {
AliasSet *OldAS = AS;
AS = OldAS->getForwardedTarget(AST);
AS->addRef();
OldAS->dropRef(AST);
}
return AS;
}
void setAliasSet(AliasSet *as) {
assert(!AS && "Already have an alias set!");
AS = as;
}
void eraseFromList() {
if (NextInList) NextInList->PrevInList = PrevInList;
*PrevInList = NextInList;
if (AS->PtrListEnd == &NextInList) {
AS->PtrListEnd = PrevInList;
assert(*AS->PtrListEnd == nullptr && "List not terminated right!");
}
delete this;
}
};
// Doubly linked list of nodes.
PointerRec *PtrList = nullptr;
PointerRec **PtrListEnd;
// Forwarding pointer. // Forwarding pointer.
AliasSet *Forward = nullptr; AliasSet *Forward = nullptr;
/// Memory locations in this alias set.
SmallVector<MemoryLocation, 0> MemoryLocs;
/// All instructions without a specific address in this alias set. /// All instructions without a specific address in this alias set.
std::vector<AssertingVH<Instruction>> UnknownInsts; std::vector<AssertingVH<Instruction>> UnknownInsts;
@ -178,8 +89,6 @@ class AliasSet : public ilist_node<AliasSet> {
}; };
unsigned Alias : 1; unsigned Alias : 1;
unsigned SetSize = 0;
void addRef() { ++RefCount; } void addRef() { ++RefCount; }
void dropRef(AliasSetTracker &AST) { void dropRef(AliasSetTracker &AST) {
@ -205,95 +114,40 @@ public:
/// Merge the specified alias set into this alias set. /// Merge the specified alias set into this alias set.
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA); void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA);
// Alias Set iteration - Allow access to all of the pointers which are part of // Alias Set iteration - Allow access to all of the memory locations which are
// this alias set. // part of this alias set.
class iterator; using iterator = SmallVectorImpl<MemoryLocation>::const_iterator;
iterator begin() const { return iterator(PtrList); } iterator begin() const { return MemoryLocs.begin(); }
iterator end() const { return iterator(); } iterator end() const { return MemoryLocs.end(); }
bool empty() const { return PtrList == nullptr; }
// Unfortunately, ilist::size() is linear, so we have to add code to keep unsigned size() { return MemoryLocs.size(); }
// track of the list's exact size.
unsigned size() { return SetSize; } /// Retrieve the pointer values for the memory locations in this alias set.
/// The order matches that of the memory locations, but duplicate pointer
/// values are omitted.
using PointerVector = SmallVector<const Value *, 8>;
PointerVector getPointers() const;
void print(raw_ostream &OS) const; void print(raw_ostream &OS) const;
void dump() const; void dump() const;
/// Define an iterator for alias sets... this is just a forward iterator.
class iterator {
PointerRec *CurNode;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = PointerRec;
using difference_type = std::ptrdiff_t;
using pointer = value_type *;
using reference = value_type &;
explicit iterator(PointerRec *CN = nullptr) : CurNode(CN) {}
bool operator==(const iterator& x) const {
return CurNode == x.CurNode;
}
bool operator!=(const iterator& x) const { return !operator==(x); }
value_type &operator*() const {
assert(CurNode && "Dereferencing AliasSet.end()!");
return *CurNode;
}
value_type *operator->() const { return &operator*(); }
Value *getPointer() const { return CurNode->getValue(); }
LocationSize getSize() const { return CurNode->getSize(); }
AAMDNodes getAAInfo() const { return CurNode->getAAInfo(); }
iterator& operator++() { // Preincrement
assert(CurNode && "Advancing past AliasSet.end()!");
CurNode = CurNode->getNext();
return *this;
}
iterator operator++(int) { // Postincrement
iterator tmp = *this; ++*this; return tmp;
}
};
private: private:
// Can only be created by AliasSetTracker. // Can only be created by AliasSetTracker.
AliasSet() AliasSet()
: PtrListEnd(&PtrList), RefCount(0), AliasAny(false), Access(NoAccess), : RefCount(0), AliasAny(false), Access(NoAccess), Alias(SetMustAlias) {}
Alias(SetMustAlias) {}
PointerRec *getSomePointer() const {
return PtrList;
}
/// Return the real alias set this represents. If this has been merged with
/// another set and is forwarding, return the ultimate destination set. This
/// also implements the union-find collapsing as well.
AliasSet *getForwardedTarget(AliasSetTracker &AST) {
if (!Forward) return this;
AliasSet *Dest = Forward->getForwardedTarget(AST);
if (Dest != Forward) {
Dest->addRef();
Forward->dropRef(AST);
Forward = Dest;
}
return Dest;
}
void removeFromTracker(AliasSetTracker &AST); void removeFromTracker(AliasSetTracker &AST);
void addPointer(AliasSetTracker &AST, PointerRec &Entry, LocationSize Size, void addMemoryLocation(AliasSetTracker &AST, const MemoryLocation &MemLoc,
const AAMDNodes &AAInfo, bool KnownMustAlias = false, bool KnownMustAlias = false);
bool SkipSizeUpdate = false);
void addUnknownInst(Instruction *I, BatchAAResults &AA); void addUnknownInst(Instruction *I, BatchAAResults &AA);
public: public:
/// If the specified pointer "may" (or must) alias one of the members in the /// If the specified memory location "may" (or must) alias one of the members
/// set return the appropriate AliasResult. Otherwise return NoAlias. /// in the set return the appropriate AliasResult. Otherwise return NoAlias.
AliasResult aliasesPointer(const Value *Ptr, LocationSize Size, AliasResult aliasesMemoryLocation(const MemoryLocation &MemLoc,
const AAMDNodes &AAInfo, BatchAAResults &AA) const; BatchAAResults &AA) const;
ModRefInfo aliasesUnknownInst(const Instruction *Inst, ModRefInfo aliasesUnknownInst(const Instruction *Inst,
BatchAAResults &AA) const; BatchAAResults &AA) const;
}; };
@ -307,9 +161,10 @@ class AliasSetTracker {
BatchAAResults &AA; BatchAAResults &AA;
ilist<AliasSet> AliasSets; ilist<AliasSet> AliasSets;
using PointerMapType = DenseMap<AssertingVH<Value>, AliasSet::PointerRec *>; using PointerMapType = DenseMap<AssertingVH<const Value>, AliasSet *>;
// Map from pointers to their node // Map from pointer values to the alias set holding one or more memory
// locations with that pointer value.
PointerMapType PointerMap; PointerMapType PointerMap;
public: public:
@ -327,9 +182,6 @@ public:
/// 3. If the instruction aliases multiple sets, merge the sets, and add /// 3. If the instruction aliases multiple sets, merge the sets, and add
/// the instruction to the result. /// the instruction to the result.
/// ///
/// These methods return true if inserting the instruction resulted in the
/// addition of a new alias set (i.e., the pointer did not alias anything).
///
void add(const MemoryLocation &Loc); void add(const MemoryLocation &Loc);
void add(LoadInst *LI); void add(LoadInst *LI);
void add(StoreInst *SI); void add(StoreInst *SI);
@ -370,31 +222,39 @@ public:
private: private:
friend class AliasSet; friend class AliasSet;
// The total number of pointers contained in all "may" alias sets. // The total number of memory locations contained in all alias sets.
unsigned TotalMayAliasSetSize = 0; unsigned TotalAliasSetSize = 0;
// A non-null value signifies this AST is saturated. A saturated AST lumps // A non-null value signifies this AST is saturated. A saturated AST lumps
// all pointers into a single "May" set. // all elements into a single "May" set.
AliasSet *AliasAnyAS = nullptr; AliasSet *AliasAnyAS = nullptr;
void removeAliasSet(AliasSet *AS); void removeAliasSet(AliasSet *AS);
/// Just like operator[] on the map, except that it creates an entry for the // Update an alias set field to point to its real destination. If the field is
/// pointer if it doesn't already exist. // pointing to a set that has been merged with another set and is forwarding,
AliasSet::PointerRec &getEntryFor(Value *V) { // the field is updated to point to the set obtained by following the
AliasSet::PointerRec *&Entry = PointerMap[V]; // forwarding links. The Forward fields of intermediate alias sets are
if (!Entry) // collapsed as well, and alias set reference counts are updated to reflect
Entry = new AliasSet::PointerRec(V); // the new situation.
return *Entry; void collapseForwardingIn(AliasSet *&AS) {
if (AS->Forward) {
collapseForwardingIn(AS->Forward);
// Swap out AS for AS->Forward, while updating reference counts.
AliasSet *NewAS = AS->Forward;
NewAS->addRef();
AS->dropRef(*this);
AS = NewAS;
}
} }
AliasSet &addPointer(MemoryLocation Loc, AliasSet::AccessLattice E); AliasSet &addMemoryLocation(MemoryLocation Loc, AliasSet::AccessLattice E);
AliasSet *mergeAliasSetsForPointer(const Value *Ptr, LocationSize Size, AliasSet *mergeAliasSetsForMemoryLocation(const MemoryLocation &MemLoc,
const AAMDNodes &AAInfo, AliasSet *PtrAS,
bool &MustAliasAll); bool &MustAliasAll);
/// Merge all alias sets into a single set that is considered to alias any /// Merge all alias sets into a single set that is considered to alias
/// pointer. /// any memory location or instruction.
AliasSet &mergeAllAliasSets(); AliasSet &mergeAllAliasSets();
AliasSet *findAliasSetForUnknownInst(Instruction *Inst); AliasSet *findAliasSetForUnknownInst(Instruction *Inst);

View File

@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/GuardUtils.h" #include "llvm/Analysis/GuardUtils.h"
@ -34,11 +35,10 @@
using namespace llvm; using namespace llvm;
static cl::opt<unsigned> static cl::opt<unsigned> SaturationThreshold(
SaturationThreshold("alias-set-saturation-threshold", cl::Hidden, "alias-set-saturation-threshold", cl::Hidden, cl::init(250),
cl::init(250), cl::desc("The maximum total number of memory locations alias "
cl::desc("The maximum number of pointers may-alias " "sets may contain before degradation"));
"sets may contain before degradation"));
/// mergeSetIn - Merge the specified alias set into this alias set. /// mergeSetIn - Merge the specified alias set into this alias set.
void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST, void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
@ -46,30 +46,27 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
assert(!AS.Forward && "Alias set is already forwarding!"); assert(!AS.Forward && "Alias set is already forwarding!");
assert(!Forward && "This set is a forwarding set!!"); assert(!Forward && "This set is a forwarding set!!");
bool WasMustAlias = (Alias == SetMustAlias);
// Update the alias and access types of this set... // Update the alias and access types of this set...
Access |= AS.Access; Access |= AS.Access;
Alias |= AS.Alias; Alias |= AS.Alias;
if (Alias == SetMustAlias) { if (Alias == SetMustAlias) {
// Check that these two merged sets really are must aliases. Since both // Check that these two merged sets really are must aliases. If we cannot
// used to be must-alias sets, we can just check any pointer from each set // find a must-alias pair between them, this set becomes a may alias.
// for aliasing. if (!any_of(MemoryLocs, [&](const MemoryLocation &MemLoc) {
PointerRec *L = getSomePointer(); return any_of(AS.MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
PointerRec *R = AS.getSomePointer(); return BatchAA.isMustAlias(MemLoc, ASMemLoc);
});
// If the pointers are not a must-alias pair, this set becomes a may alias. }))
if (!BatchAA.isMustAlias(
MemoryLocation(L->getValue(), L->getSize(), L->getAAInfo()),
MemoryLocation(R->getValue(), R->getSize(), R->getAAInfo())))
Alias = SetMayAlias; Alias = SetMayAlias;
} }
if (Alias == SetMayAlias) { // Merge the list of constituent memory locations...
if (WasMustAlias) if (MemoryLocs.empty()) {
AST.TotalMayAliasSetSize += size(); std::swap(MemoryLocs, AS.MemoryLocs);
if (AS.Alias == SetMustAlias) } else {
AST.TotalMayAliasSetSize += AS.size(); append_range(MemoryLocs, AS.MemoryLocs);
AS.MemoryLocs.clear();
} }
bool ASHadUnknownInsts = !AS.UnknownInsts.empty(); bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
@ -86,18 +83,6 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
AS.Forward = this; // Forward across AS now... AS.Forward = this; // Forward across AS now...
addRef(); // AS is now pointing to us... addRef(); // AS is now pointing to us...
// Merge the list of constituent pointers...
if (AS.PtrList) {
SetSize += AS.size();
AS.SetSize = 0;
*PtrListEnd = AS.PtrList;
AS.PtrList->setPrevInList(PtrListEnd);
PtrListEnd = AS.PtrListEnd;
AS.PtrList = nullptr;
AS.PtrListEnd = &AS.PtrList;
assert(*AS.PtrListEnd == nullptr && "End of list is not null?");
}
if (ASHadUnknownInsts) if (ASHadUnknownInsts)
AS.dropRef(AST); AS.dropRef(AST);
} }
@ -106,9 +91,8 @@ void AliasSetTracker::removeAliasSet(AliasSet *AS) {
if (AliasSet *Fwd = AS->Forward) { if (AliasSet *Fwd = AS->Forward) {
Fwd->dropRef(*this); Fwd->dropRef(*this);
AS->Forward = nullptr; AS->Forward = nullptr;
} else // Update TotalMayAliasSetSize only if not forwarding. } else // Update TotalAliasSetSize only if not forwarding.
if (AS->Alias == AliasSet::SetMayAlias) TotalAliasSetSize -= AS->size();
TotalMayAliasSetSize -= AS->size();
AliasSets.erase(AS); AliasSets.erase(AS);
// If we've removed the saturated alias set, set saturated marker back to // If we've removed the saturated alias set, set saturated marker back to
@ -124,42 +108,22 @@ void AliasSet::removeFromTracker(AliasSetTracker &AST) {
AST.removeAliasSet(this); AST.removeAliasSet(this);
} }
void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry, void AliasSet::addMemoryLocation(AliasSetTracker &AST,
LocationSize Size, const AAMDNodes &AAInfo, const MemoryLocation &MemLoc,
bool KnownMustAlias, bool SkipSizeUpdate) { bool KnownMustAlias) {
assert(!Entry.hasAliasSet() && "Entry already in set!"); if (isMustAlias() && !KnownMustAlias) {
// If we cannot find a must-alias with any of the existing MemoryLocs, we
// Check to see if we have to downgrade to _may_ alias. // must downgrade to may-alias.
if (isMustAlias()) if (!any_of(MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
if (PointerRec *P = getSomePointer()) { return AST.getAliasAnalysis().isMustAlias(MemLoc, ASMemLoc);
if (!KnownMustAlias) { }))
BatchAAResults &AA = AST.getAliasAnalysis(); Alias = SetMayAlias;
AliasResult Result = AA.alias( }
MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()),
MemoryLocation(Entry.getValue(), Size, AAInfo));
if (Result != AliasResult::MustAlias) {
Alias = SetMayAlias;
AST.TotalMayAliasSetSize += size();
}
assert(Result != AliasResult::NoAlias && "Cannot be part of must set!");
} else if (!SkipSizeUpdate)
P->updateSizeAndAAInfo(Size, AAInfo);
}
Entry.setAliasSet(this);
Entry.updateSizeAndAAInfo(Size, AAInfo);
// Add it to the end of the list... // Add it to the end of the list...
++SetSize; MemoryLocs.push_back(MemLoc);
assert(*PtrListEnd == nullptr && "End of list is not null?");
*PtrListEnd = &Entry;
PtrListEnd = Entry.setPrevInList(PtrListEnd);
assert(*PtrListEnd == nullptr && "End of list is not null?");
// Entry points to alias set.
addRef();
if (Alias == SetMayAlias) AST.TotalAliasSetSize++;
AST.TotalMayAliasSetSize++;
} }
void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) { void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
@ -183,45 +147,26 @@ void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
Access = ModRefAccess; Access = ModRefAccess;
} }
/// aliasesPointer - If the specified pointer "may" (or must) alias one of the /// aliasesMemoryLocation - If the specified memory location "may" (or must)
/// members in the set return the appropriate AliasResult. Otherwise return /// alias one of the members in the set return the appropriate AliasResult.
/// NoAlias. /// Otherwise return NoAlias.
/// ///
AliasResult AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size, AliasResult AliasSet::aliasesMemoryLocation(const MemoryLocation &MemLoc,
const AAMDNodes &AAInfo, BatchAAResults &AA) const {
BatchAAResults &AA) const {
if (AliasAny) if (AliasAny)
return AliasResult::MayAlias; return AliasResult::MayAlias;
if (Alias == SetMustAlias) { // Check all of the memory locations in the set...
assert(UnknownInsts.empty() && "Illegal must alias set!"); for (const auto &ASMemLoc : MemoryLocs) {
AliasResult AR = AA.alias(MemLoc, ASMemLoc);
// If this is a set of MustAliases, only check to see if the pointer aliases
// SOME value in the set.
PointerRec *SomePtr = getSomePointer();
assert(SomePtr && "Empty must-alias set??");
return AA.alias(MemoryLocation(SomePtr->getValue(), SomePtr->getSize(),
SomePtr->getAAInfo()),
MemoryLocation(Ptr, Size, AAInfo));
}
// If this is a may-alias set, we have to check all of the pointers in the set
// to be sure it doesn't alias the set...
for (iterator I = begin(), E = end(); I != E; ++I) {
AliasResult AR =
AA.alias(MemoryLocation(Ptr, Size, AAInfo),
MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));
if (AR != AliasResult::NoAlias) if (AR != AliasResult::NoAlias)
return AR; return AR;
} }
// Check the unknown instructions... // Check the unknown instructions...
if (!UnknownInsts.empty()) { for (Instruction *Inst : UnknownInsts)
for (Instruction *Inst : UnknownInsts) if (isModOrRefSet(AA.getModRefInfo(Inst, MemLoc)))
if (isModOrRefSet( return AliasResult::MayAlias;
AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo))))
return AliasResult::MayAlias;
}
return AliasResult::NoAlias; return AliasResult::NoAlias;
} }
@ -246,9 +191,8 @@ ModRefInfo AliasSet::aliasesUnknownInst(const Instruction *Inst,
} }
ModRefInfo MR = ModRefInfo::NoModRef; ModRefInfo MR = ModRefInfo::NoModRef;
for (iterator I = begin(), E = end(); I != E; ++I) { for (const auto &ASMemLoc : MemoryLocs) {
MR |= AA.getModRefInfo( MR |= AA.getModRefInfo(Inst, ASMemLoc);
Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));
if (isModAndRefSet(MR)) if (isModAndRefSet(MR))
return MR; return MR;
} }
@ -256,37 +200,46 @@ ModRefInfo AliasSet::aliasesUnknownInst(const Instruction *Inst,
return MR; return MR;
} }
AliasSet::PointerVector AliasSet::getPointers() const {
SmallSetVector<const Value *, 8> Pointers;
for (const MemoryLocation &MemLoc : MemoryLocs)
Pointers.insert(MemLoc.Ptr);
return Pointers.takeVector();
}
void AliasSetTracker::clear() { void AliasSetTracker::clear() {
// Delete all the PointerRec entries.
for (auto &I : PointerMap)
I.second->eraseFromList();
PointerMap.clear(); PointerMap.clear();
// The alias sets should all be clear now.
AliasSets.clear(); AliasSets.clear();
} }
/// mergeAliasSetsForPointer - Given a pointer, merge all alias sets that may /// mergeAliasSetsForMemoryLocation - Given a memory location, merge all alias
/// alias the pointer. Return the unified set, or nullptr if no set that aliases /// sets that may alias it. Return the unified set, or nullptr if no aliasing
/// the pointer was found. MustAliasAll is updated to true/false if the pointer /// set was found. A known existing alias set for the pointer value of the
/// is found to MustAlias all the sets it merged. /// memory location can be passed in (or nullptr if not available). MustAliasAll
AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr, /// is updated to true/false if the memory location is found to MustAlias all
LocationSize Size, /// the sets it merged.
const AAMDNodes &AAInfo, AliasSet *AliasSetTracker::mergeAliasSetsForMemoryLocation(
bool &MustAliasAll) { const MemoryLocation &MemLoc, AliasSet *PtrAS, bool &MustAliasAll) {
AliasSet *FoundSet = nullptr; AliasSet *FoundSet = nullptr;
MustAliasAll = true; MustAliasAll = true;
for (AliasSet &AS : llvm::make_early_inc_range(*this)) { for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
if (AS.Forward) if (AS.Forward)
continue; continue;
AliasResult AR = AS.aliasesPointer(Ptr, Size, AAInfo, AA); // An alias set that already contains a memory location with the same
if (AR == AliasResult::NoAlias) // pointer value is directly assumed to MustAlias; we bypass the AA query in
continue; // this case.
// Note: it is not guaranteed that AA would always provide the same result;
// a known exception are undef pointer values, where alias(undef, undef) is
// NoAlias, while we treat it as MustAlias.
if (&AS != PtrAS) {
AliasResult AR = AS.aliasesMemoryLocation(MemLoc, AA);
if (AR == AliasResult::NoAlias)
continue;
if (AR != AliasResult::MustAlias) if (AR != AliasResult::MustAlias)
MustAliasAll = false; MustAliasAll = false;
}
if (!FoundSet) { if (!FoundSet) {
// If this is the first alias set ptr can go into, remember it. // If this is the first alias set ptr can go into, remember it.
@ -317,91 +270,77 @@ AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
} }
AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) { AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) {
// The alias sets are indexed with a map from the memory locations' pointer
// values. If the memory location is already registered, we can find it in the
// alias set associated with its pointer.
AliasSet *&MapEntry = PointerMap[MemLoc.Ptr];
if (MapEntry) {
collapseForwardingIn(MapEntry);
if (is_contained(MapEntry->MemoryLocs, MemLoc))
return *MapEntry;
}
Value * const Pointer = const_cast<Value*>(MemLoc.Ptr); AliasSet *AS;
const LocationSize Size = MemLoc.Size; bool MustAliasAll = false;
const AAMDNodes &AAInfo = MemLoc.AATags;
AliasSet::PointerRec &Entry = getEntryFor(Pointer);
if (AliasAnyAS) { if (AliasAnyAS) {
// At this point, the AST is saturated, so we only have one active alias // At this point, the AST is saturated, so we only have one active alias
// set. That means we already know which alias set we want to return, and // set. That means we already know which alias set we want to return, and
// just need to add the pointer to that set to keep the data structure // just need to add the memory location to that set to keep the data
// consistent. // structure consistent.
// This, of course, means that we will never need a merge here. // This, of course, means that we will never need a merge here.
if (Entry.hasAliasSet()) { AS = AliasAnyAS;
Entry.updateSizeAndAAInfo(Size, AAInfo); } else if (AliasSet *AliasAS = mergeAliasSetsForMemoryLocation(
assert(Entry.getAliasSet(*this) == AliasAnyAS && MemLoc, MapEntry, MustAliasAll)) {
"Entry in saturated AST must belong to only alias set");
} else {
AliasAnyAS->addPointer(*this, Entry, Size, AAInfo);
}
return *AliasAnyAS;
}
bool MustAliasAll = false;
// Check to see if the pointer is already known.
if (Entry.hasAliasSet()) {
// If the size changed, we may need to merge several alias sets.
// Note that we can *not* return the result of mergeAliasSetsForPointer
// due to a quirk of alias analysis behavior. Since alias(undef, undef)
// is NoAlias, mergeAliasSetsForPointer(undef, ...) will not find the
// the right set for undef, even if it exists.
if (Entry.updateSizeAndAAInfo(Size, AAInfo)) {
mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll);
// For MustAlias sets, also update Size/AAInfo of the representative
// pointer.
AliasSet &AS = *Entry.getAliasSet(*this);
if (AS.isMustAlias())
if (AliasSet::PointerRec *P = AS.getSomePointer())
P->updateSizeAndAAInfo(Size, AAInfo);
}
// Return the set!
return *Entry.getAliasSet(*this)->getForwardedTarget(*this);
}
if (AliasSet *AS =
mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll)) {
// Add it to the alias set it aliases. // Add it to the alias set it aliases.
AS->addPointer(*this, Entry, Size, AAInfo, MustAliasAll); AS = AliasAS;
return *AS; } else {
// Otherwise create a new alias set to hold the new memory location.
AliasSets.push_back(AS = new AliasSet());
MustAliasAll = true;
} }
// Otherwise create a new alias set to hold the loaded pointer. // Register memory location in selected alias set.
AliasSets.push_back(new AliasSet()); AS->addMemoryLocation(*this, MemLoc, MustAliasAll);
AliasSets.back().addPointer(*this, Entry, Size, AAInfo, true); // Register selected alias set in pointer map (or ensure it is consistent with
return AliasSets.back(); // earlier map entry after taking into account new merging).
if (MapEntry) {
collapseForwardingIn(MapEntry);
assert(MapEntry == AS && "Memory locations with same pointer value cannot "
"be in different alias sets");
} else {
AS->addRef();
MapEntry = AS;
}
return *AS;
} }
void AliasSetTracker::add(const MemoryLocation &Loc) { void AliasSetTracker::add(const MemoryLocation &Loc) {
addPointer(Loc, AliasSet::NoAccess); addMemoryLocation(Loc, AliasSet::NoAccess);
} }
void AliasSetTracker::add(LoadInst *LI) { void AliasSetTracker::add(LoadInst *LI) {
if (isStrongerThanMonotonic(LI->getOrdering())) if (isStrongerThanMonotonic(LI->getOrdering()))
return addUnknown(LI); return addUnknown(LI);
addPointer(MemoryLocation::get(LI), AliasSet::RefAccess); addMemoryLocation(MemoryLocation::get(LI), AliasSet::RefAccess);
} }
void AliasSetTracker::add(StoreInst *SI) { void AliasSetTracker::add(StoreInst *SI) {
if (isStrongerThanMonotonic(SI->getOrdering())) if (isStrongerThanMonotonic(SI->getOrdering()))
return addUnknown(SI); return addUnknown(SI);
addPointer(MemoryLocation::get(SI), AliasSet::ModAccess); addMemoryLocation(MemoryLocation::get(SI), AliasSet::ModAccess);
} }
void AliasSetTracker::add(VAArgInst *VAAI) { void AliasSetTracker::add(VAArgInst *VAAI) {
addPointer(MemoryLocation::get(VAAI), AliasSet::ModRefAccess); addMemoryLocation(MemoryLocation::get(VAAI), AliasSet::ModRefAccess);
} }
void AliasSetTracker::add(AnyMemSetInst *MSI) { void AliasSetTracker::add(AnyMemSetInst *MSI) {
addPointer(MemoryLocation::getForDest(MSI), AliasSet::ModAccess); addMemoryLocation(MemoryLocation::getForDest(MSI), AliasSet::ModAccess);
} }
void AliasSetTracker::add(AnyMemTransferInst *MTI) { void AliasSetTracker::add(AnyMemTransferInst *MTI) {
addPointer(MemoryLocation::getForDest(MTI), AliasSet::ModAccess); addMemoryLocation(MemoryLocation::getForDest(MTI), AliasSet::ModAccess);
addPointer(MemoryLocation::getForSource(MTI), AliasSet::RefAccess); addMemoryLocation(MemoryLocation::getForSource(MTI), AliasSet::RefAccess);
} }
void AliasSetTracker::addUnknown(Instruction *Inst) { void AliasSetTracker::addUnknown(Instruction *Inst) {
@ -480,7 +419,7 @@ void AliasSetTracker::add(Instruction *I) {
ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx); ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
ArgMask &= CallMask; ArgMask &= CallMask;
if (!isNoModRef(ArgMask)) if (!isNoModRef(ArgMask))
addPointer(ArgLoc, getAccessFromModRef(ArgMask)); addMemoryLocation(ArgLoc, getAccessFromModRef(ArgMask));
} }
return; return;
} }
@ -497,7 +436,7 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
assert(&AA == &AST.AA && assert(&AA == &AST.AA &&
"Merging AliasSetTracker objects with different Alias Analyses!"); "Merging AliasSetTracker objects with different Alias Analyses!");
// Loop over all of the alias sets in AST, adding the pointers contained // Loop over all of the alias sets in AST, adding the members contained
// therein into the current alias sets. This can cause alias sets to be // therein into the current alias sets. This can cause alias sets to be
// merged together in the current AST. // merged together in the current AST.
for (const AliasSet &AS : AST) { for (const AliasSet &AS : AST) {
@ -508,16 +447,14 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
for (Instruction *Inst : AS.UnknownInsts) for (Instruction *Inst : AS.UnknownInsts)
add(Inst); add(Inst);
// Loop over all of the pointers in this alias set. // Loop over all of the memory locations in this alias set.
for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) for (const MemoryLocation &ASMemLoc : AS.MemoryLocs)
addPointer( addMemoryLocation(ASMemLoc, (AliasSet::AccessLattice)AS.Access);
MemoryLocation(ASI.getPointer(), ASI.getSize(), ASI.getAAInfo()),
(AliasSet::AccessLattice)AS.Access);
} }
} }
AliasSet &AliasSetTracker::mergeAllAliasSets() { AliasSet &AliasSetTracker::mergeAllAliasSets() {
assert(!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold) && assert(!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold) &&
"Full merge should happen once, when the saturation threshold is " "Full merge should happen once, when the saturation threshold is "
"reached"); "reached");
@ -528,8 +465,8 @@ AliasSet &AliasSetTracker::mergeAllAliasSets() {
for (AliasSet &AS : *this) for (AliasSet &AS : *this)
ASVector.push_back(&AS); ASVector.push_back(&AS);
// Copy all instructions and pointers into a new set, and forward all other // Copy all instructions and memory locations into a new set, and forward all
// sets to it. // other sets to it.
AliasSets.push_back(new AliasSet()); AliasSets.push_back(new AliasSet());
AliasAnyAS = &AliasSets.back(); AliasAnyAS = &AliasSets.back();
AliasAnyAS->Alias = AliasSet::SetMayAlias; AliasAnyAS->Alias = AliasSet::SetMayAlias;
@ -553,14 +490,14 @@ AliasSet &AliasSetTracker::mergeAllAliasSets() {
return *AliasAnyAS; return *AliasAnyAS;
} }
AliasSet &AliasSetTracker::addPointer(MemoryLocation Loc, AliasSet &AliasSetTracker::addMemoryLocation(MemoryLocation Loc,
AliasSet::AccessLattice E) { AliasSet::AccessLattice E) {
AliasSet &AS = getAliasSetFor(Loc); AliasSet &AS = getAliasSetFor(Loc);
AS.Access |= E; AS.Access |= E;
if (!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold)) { if (!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold)) {
// The AST is now saturated. From here on, we conservatively consider all // The AST is now saturated. From here on, we conservatively consider all
// pointers to alias each-other. // elements to alias each-other.
return mergeAllAliasSets(); return mergeAllAliasSets();
} }
@ -584,17 +521,18 @@ void AliasSet::print(raw_ostream &OS) const {
if (Forward) if (Forward)
OS << " forwarding to " << (void*)Forward; OS << " forwarding to " << (void*)Forward;
if (!empty()) { if (!MemoryLocs.empty()) {
OS << "Pointers: "; ListSeparator LS;
for (iterator I = begin(), E = end(); I != E; ++I) { OS << "Memory locations: ";
if (I != begin()) OS << ", "; for (const MemoryLocation &MemLoc : MemoryLocs) {
I.getPointer()->printAsOperand(OS << "("); OS << LS;
if (I.getSize() == LocationSize::afterPointer()) MemLoc.Ptr->printAsOperand(OS << "(");
if (MemLoc.Size == LocationSize::afterPointer())
OS << ", unknown after)"; OS << ", unknown after)";
else if (I.getSize() == LocationSize::beforeOrAfterPointer()) else if (MemLoc.Size == LocationSize::beforeOrAfterPointer())
OS << ", unknown before-or-after)"; OS << ", unknown before-or-after)";
else else
OS << ", " << I.getSize() << ")"; OS << ", " << MemLoc.Size << ")";
} }
} }
if (!UnknownInsts.empty()) { if (!UnknownInsts.empty()) {

View File

@ -1115,6 +1115,7 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
int NumWritePtrChecks = 0; int NumWritePtrChecks = 0;
bool CanDoAliasSetRT = true; bool CanDoAliasSetRT = true;
++ASId; ++ASId;
auto ASPointers = AS.getPointers();
// We assign consecutive id to access from different dependence sets. // We assign consecutive id to access from different dependence sets.
// Accesses within the same set don't need a runtime check. // Accesses within the same set don't need a runtime check.
@ -1126,8 +1127,8 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
// First, count how many write and read accesses are in the alias set. Also // First, count how many write and read accesses are in the alias set. Also
// collect MemAccessInfos for later. // collect MemAccessInfos for later.
SmallVector<MemAccessInfo, 4> AccessInfos; SmallVector<MemAccessInfo, 4> AccessInfos;
for (const auto &A : AS) { for (const Value *Ptr_ : ASPointers) {
Value *Ptr = A.getValue(); Value *Ptr = const_cast<Value *>(Ptr_);
bool IsWrite = Accesses.count(MemAccessInfo(Ptr, true)); bool IsWrite = Accesses.count(MemAccessInfo(Ptr, true));
if (IsWrite) if (IsWrite)
++NumWritePtrChecks; ++NumWritePtrChecks;
@ -1140,10 +1141,11 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
// or a single write and no reads. // or a single write and no reads.
if (NumWritePtrChecks == 0 || if (NumWritePtrChecks == 0 ||
(NumWritePtrChecks == 1 && NumReadPtrChecks == 0)) { (NumWritePtrChecks == 1 && NumReadPtrChecks == 0)) {
assert((AS.size() <= 1 || assert((ASPointers.size() <= 1 ||
all_of(AS, all_of(ASPointers,
[this](auto AC) { [this](const Value *Ptr) {
MemAccessInfo AccessWrite(AC.getValue(), true); MemAccessInfo AccessWrite(const_cast<Value *>(Ptr),
true);
return DepCands.findValue(AccessWrite) == DepCands.end(); return DepCands.findValue(AccessWrite) == DepCands.end();
})) && })) &&
"Can only skip updating CanDoRT below, if all entries in AS " "Can only skip updating CanDoRT below, if all entries in AS "
@ -1271,8 +1273,9 @@ void AccessAnalysis::processMemAccesses() {
// set. // set.
for (const auto &AS : AST) { for (const auto &AS : AST) {
// Note that both the alias-set tracker and the alias sets themselves used // Note that both the alias-set tracker and the alias sets themselves used
// linked lists internally and so the iteration order here is deterministic // ordered collections internally and so the iteration order here is
// (matching the original instruction order within each set). // deterministic.
auto ASPointers = AS.getPointers();
bool SetHasWrite = false; bool SetHasWrite = false;
@ -1289,8 +1292,8 @@ void AccessAnalysis::processMemAccesses() {
bool UseDeferred = SetIteration > 0; bool UseDeferred = SetIteration > 0;
PtrAccessMap &S = UseDeferred ? DeferredAccesses : Accesses; PtrAccessMap &S = UseDeferred ? DeferredAccesses : Accesses;
for (const auto &AV : AS) { for (const Value *Ptr_ : ASPointers) {
Value *Ptr = AV.getValue(); Value *Ptr = const_cast<Value *>(Ptr_);
// For a single memory access in AliasSetTracker, Accesses may contain // For a single memory access in AliasSetTracker, Accesses may contain
// both read and write, and they both need to be handled for CheckDeps. // both read and write, and they both need to be handled for CheckDeps.

View File

@ -2323,8 +2323,8 @@ collectPromotionCandidates(MemorySSA *MSSA, AliasAnalysis *AA, Loop *L) {
SmallVector<std::pair<SmallSetVector<Value *, 8>, bool>, 0> Result; SmallVector<std::pair<SmallSetVector<Value *, 8>, bool>, 0> Result;
for (auto [Set, HasReadsOutsideSet] : Sets) { for (auto [Set, HasReadsOutsideSet] : Sets) {
SmallSetVector<Value *, 8> PointerMustAliases; SmallSetVector<Value *, 8> PointerMustAliases;
for (const auto &ASI : *Set) for (const auto &MemLoc : *Set)
PointerMustAliases.insert(ASI.getValue()); PointerMustAliases.insert(const_cast<Value *>(MemLoc.Ptr));
Result.emplace_back(std::move(PointerMustAliases), HasReadsOutsideSet); Result.emplace_back(std::move(PointerMustAliases), HasReadsOutsideSet);
} }

View File

@ -258,13 +258,13 @@ bool LoopVersioningLICM::legalLoopMemoryAccesses() {
// With MustAlias its not worth adding runtime bound check. // With MustAlias its not worth adding runtime bound check.
if (AS.isMustAlias()) if (AS.isMustAlias())
return false; return false;
Value *SomePtr = AS.begin()->getValue(); const Value *SomePtr = AS.begin()->Ptr;
bool TypeCheck = true; bool TypeCheck = true;
// Check for Mod & MayAlias // Check for Mod & MayAlias
HasMayAlias |= AS.isMayAlias(); HasMayAlias |= AS.isMayAlias();
HasMod |= AS.isMod(); HasMod |= AS.isMod();
for (const auto &A : AS) { for (const auto &MemLoc : AS) {
Value *Ptr = A.getValue(); const Value *Ptr = MemLoc.Ptr;
// Alias tracker should have pointers of same data type. // Alias tracker should have pointers of same data type.
// //
// FIXME: check no longer effective since opaque pointers? // FIXME: check no longer effective since opaque pointers?

View File

@ -5,8 +5,8 @@
; CHECK: Alias sets for function 'test_alloca_argmemonly': ; CHECK: Alias sets for function 'test_alloca_argmemonly':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values. ; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, unknown before-or-after), (ptr %s, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, unknown before-or-after), (ptr %s, unknown before-or-after)
define void @test_alloca_argmemonly(ptr %s, ptr %d) { define void @test_alloca_argmemonly(ptr %s, ptr %d) {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -17,8 +17,8 @@ entry:
; CHECK: Alias sets for function 'test_readonly_arg' ; CHECK: Alias sets for function 'test_readonly_arg'
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (ptr %s, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Memory locations: (ptr %s, unknown before-or-after), (ptr %s, LocationSize::precise(1))
define i8 @test_readonly_arg(ptr noalias %s, ptr noalias %d) { define i8 @test_readonly_arg(ptr noalias %s, ptr noalias %d) {
entry: entry:
call void @my_memcpy(ptr %d, ptr %s, i64 1) call void @my_memcpy(ptr %d, ptr %s, i64 1)
@ -28,8 +28,8 @@ entry:
; CHECK: Alias sets for function 'test_noalias_argmemonly': ; CHECK: Alias sets for function 'test_noalias_argmemonly':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values. ; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, unknown before-or-after), (ptr %s, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, unknown before-or-after), (ptr %s, unknown before-or-after)
define void @test_noalias_argmemonly(ptr noalias %a, ptr %s, ptr %d) { define void @test_noalias_argmemonly(ptr noalias %a, ptr %s, ptr %d) {
entry: entry:
store i8 1, ptr %a, align 1 store i8 1, ptr %a, align 1
@ -39,8 +39,8 @@ entry:
; CHECK: Alias sets for function 'test5': ; CHECK: Alias sets for function 'test5':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1)), (ptr %a, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, unknown before-or-after), (ptr %b, LocationSize::precise(1))
define void @test5(ptr noalias %a, ptr noalias %b) { define void @test5(ptr noalias %a, ptr noalias %b) {
entry: entry:
store i8 1, ptr %a, align 1 store i8 1, ptr %a, align 1
@ -51,8 +51,8 @@ entry:
; CHECK: Alias sets for function 'test_argcollapse': ; CHECK: Alias sets for function 'test_argcollapse':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1)), (ptr %a, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %b, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %b, unknown before-or-after), (ptr %b, LocationSize::precise(1))
define void @test_argcollapse(ptr noalias %a, ptr noalias %b) { define void @test_argcollapse(ptr noalias %a, ptr noalias %b) {
entry: entry:
store i8 1, ptr %a, align 1 store i8 1, ptr %a, align 1
@ -63,8 +63,8 @@ entry:
; CHECK: Alias sets for function 'test_memcpy1': ; CHECK: Alias sets for function 'test_memcpy1':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %b, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %b, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, unknown before-or-after)
define void @test_memcpy1(ptr noalias %a, ptr noalias %b) { define void @test_memcpy1(ptr noalias %a, ptr noalias %b) {
entry: entry:
call void @my_memcpy(ptr %b, ptr %a, i64 1) call void @my_memcpy(ptr %b, ptr %a, i64 1)
@ -74,7 +74,7 @@ entry:
; CHECK: Alias sets for function 'test_memset1': ; CHECK: Alias sets for function 'test_memset1':
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values. ; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, unknown before-or-after)
define void @test_memset1() { define void @test_memset1() {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -84,7 +84,7 @@ entry:
; CHECK: Alias sets for function 'test_memset2': ; CHECK: Alias sets for function 'test_memset2':
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values. ; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, unknown before-or-after)
define void @test_memset2(ptr %a) { define void @test_memset2(ptr %a) {
entry: entry:
call void @my_memset(ptr %a, i8 0, i64 1) call void @my_memset(ptr %a, i8 0, i64 1)
@ -93,7 +93,7 @@ entry:
; CHECK: Alias sets for function 'test_memset3': ; CHECK: Alias sets for function 'test_memset3':
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 2 pointer values. ; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod Pointers: (ptr %a, unknown before-or-after), (ptr %b, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod Memory locations: (ptr %a, unknown before-or-after), (ptr %b, unknown before-or-after)
define void @test_memset3(ptr %a, ptr %b) { define void @test_memset3(ptr %a, ptr %b) {
entry: entry:
call void @my_memset(ptr %a, i8 0, i64 1) call void @my_memset(ptr %a, i8 0, i64 1)
@ -105,8 +105,8 @@ entry:
; CHECK: Alias sets for function 'test_memset4': ; CHECK: Alias sets for function 'test_memset4':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, unknown before-or-after) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, unknown before-or-after)
define void @test_memset4(ptr noalias %a, ptr noalias %b) { define void @test_memset4(ptr noalias %a, ptr noalias %b) {
entry: entry:
call void @my_memset(ptr %a, i8 0, i64 1) call void @my_memset(ptr %a, i8 0, i64 1)
@ -121,7 +121,7 @@ declare void @my_memmove(ptr nocapture, ptr nocapture readonly, i64) argmemonly
; CHECK: Alias sets for function 'test_attribute_intersect': ; CHECK: Alias sets for function 'test_attribute_intersect':
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values. ; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Memory locations: (ptr %a, LocationSize::precise(1))
define i8 @test_attribute_intersect(ptr noalias %a) { define i8 @test_attribute_intersect(ptr noalias %a) {
entry: entry:
;; This call is effectively readnone since the argument is readonly ;; This call is effectively readnone since the argument is readonly

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,9 @@
; CHECK: Alias sets for function 'test1': ; CHECK: Alias sets for function 'test1':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NOT: 1 Unknown instruction ; CHECK-NOT: 1 Unknown instruction
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test1(i32 %c) { define void @test1(i32 %c) {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -18,10 +18,10 @@ entry:
; CHECK: Alias sets for function 'test2': ; CHECK: Alias sets for function 'test2':
; CHECK: Alias Set Tracker: 3 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 3 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] may alias, Ref ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] may alias, Ref
; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ] ; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test2(i32 %c) { define void @test2(i32 %c) {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -35,7 +35,7 @@ entry:
; CHECK: Alias sets for function 'test3': ; CHECK: Alias sets for function 'test3':
; CHECK: Alias Set Tracker: 1 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 1 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 3] may alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1)), (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 3] may alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1)), (ptr %b, LocationSize::precise(1))
; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ] ; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
define void @test3(i32 %c, ptr %a, ptr %b) { define void @test3(i32 %c, ptr %a, ptr %b) {
entry: entry:
@ -48,9 +48,9 @@ entry:
; CHECK: Alias sets for function 'test4': ; CHECK: Alias sets for function 'test4':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ] ; CHECK: 1 Unknown instructions: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test4(i32 %c, ptr %a) { define void @test4(i32 %c, ptr %a) {
entry: entry:
%b = alloca i8, align 1 %b = alloca i8, align 1
@ -63,9 +63,9 @@ entry:
; CHECK: Alias sets for function 'test5': ; CHECK: Alias sets for function 'test5':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NOT: 1 Unknown instruction ; CHECK-NOT: 1 Unknown instruction
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test5() { define void @test5() {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1

View File

@ -2,7 +2,7 @@
; RUN: opt -S < %s -passes=print-alias-sets 2>&1 | FileCheck %s ; RUN: opt -S < %s -passes=print-alias-sets 2>&1 | FileCheck %s
; CHECK-LABEL: Alias sets for function 'sn' ; CHECK-LABEL: Alias sets for function 'sn'
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %p, unknown after) ; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(8))
define void @sn(ptr %p) {; define void @sn(ptr %p) {;
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2 store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
store i64 0, ptr %p, align 2 store i64 0, ptr %p, align 2
@ -10,7 +10,7 @@ define void @sn(ptr %p) {;
} }
; CHECK-LABEL: Alias sets for function 'ns' ; CHECK-LABEL: Alias sets for function 'ns'
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %p, unknown after) ; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(8)), (ptr %p, LocationSize::precise(vscale x 16))
define void @ns(ptr %p) { define void @ns(ptr %p) {
store i64 0, ptr %p, align 2 store i64 0, ptr %p, align 2
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2 store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
@ -18,7 +18,7 @@ define void @ns(ptr %p) {
} }
; CHECK-LABEL: Alias sets for function 'ss': ; CHECK-LABEL: Alias sets for function 'ss':
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %p, LocationSize::precise(vscale x 16)) ; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(vscale x 16))
define void @ss(ptr %p) { define void @ss(ptr %p) {
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2 store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2 store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
@ -26,7 +26,7 @@ define void @ss(ptr %p) {
} }
; CHECK-LABEL: Alias sets for function 'ss2': ; CHECK-LABEL: Alias sets for function 'ss2':
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %p, unknown after) ; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %p, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(vscale x 32))
define void @ss2(ptr %p) { define void @ss2(ptr %p) {
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2 store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2 store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
@ -34,7 +34,7 @@ define void @ss2(ptr %p) {
ret void ret void
} }
; CHECK-LABEL: Alias sets for function 'son': ; CHECK-LABEL: Alias sets for function 'son':
; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %g, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(8)) ; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %g, LocationSize::precise(vscale x 16)), (ptr %p, LocationSize::precise(8))
define void @son(ptr %p) { define void @son(ptr %p) {
%g = getelementptr i8, ptr %p, i64 8 %g = getelementptr i8, ptr %p, i64 8
store <vscale x 2 x i64> zeroinitializer, ptr %g, align 2 store <vscale x 2 x i64> zeroinitializer, ptr %g, align 2
@ -43,7 +43,7 @@ define void @son(ptr %p) {
} }
; CHECK-LABEL: Alias sets for function 'sno': ; CHECK-LABEL: Alias sets for function 'sno':
; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %p, LocationSize::precise(vscale x 16)), (ptr %g, LocationSize::precise(8)) ; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %p, LocationSize::precise(vscale x 16)), (ptr %g, LocationSize::precise(8))
define void @sno(ptr %p) { define void @sno(ptr %p) {
%g = getelementptr i8, ptr %p, i64 8 %g = getelementptr i8, ptr %p, i64 8
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2 store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2

View File

@ -5,7 +5,7 @@
; CHECK: Alias sets for function 'test_known_size': ; CHECK: Alias sets for function 'test_known_size':
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values. ; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, LocationSize::precise(1))
define void @test_known_size(ptr noalias %d) { define void @test_known_size(ptr noalias %d) {
entry: entry:
call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 1, i1 false) call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 1, i1 false)
@ -14,7 +14,7 @@ entry:
; CHECK: Alias sets for function 'test_unknown_size': ; CHECK: Alias sets for function 'test_unknown_size':
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values. ; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, unknown after) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, unknown after)
define void @test_unknown_size(ptr noalias %d, i64 %len) { define void @test_unknown_size(ptr noalias %d, i64 %len) {
entry: entry:
call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 %len, i1 false) call void @llvm.memset.p0.i64(ptr align 1 %d, i8 0, i64 %len, i1 false)
@ -24,7 +24,7 @@ entry:
; CHECK: Alias sets for function 'test_atomic_known_size': ; CHECK: Alias sets for function 'test_atomic_known_size':
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values. ; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, LocationSize::precise(1))
define void @test_atomic_known_size(ptr noalias %d) { define void @test_atomic_known_size(ptr noalias %d) {
entry: entry:
call void @llvm.memset.element.unordered.atomic.p0.i32(ptr align 1 %d, i8 0, i64 1, i32 1) call void @llvm.memset.element.unordered.atomic.p0.i32(ptr align 1 %d, i8 0, i64 1, i32 1)
@ -33,7 +33,7 @@ entry:
; CHECK: Alias sets for function 'test_atomic_unknown_size': ; CHECK: Alias sets for function 'test_atomic_unknown_size':
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values. ; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, unknown after) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, unknown after)
define void @test_atomic_unknown_size(ptr noalias %d, i64 %len) { define void @test_atomic_unknown_size(ptr noalias %d, i64 %len) {
entry: entry:
call void @llvm.memset.element.unordered.atomic.p0.i32(ptr align 1 %d, i8 0, i64 %len, i32 1) call void @llvm.memset.element.unordered.atomic.p0.i32(ptr align 1 %d, i8 0, i64 %len, i32 1)

View File

@ -6,8 +6,8 @@
; CHECK: Alias sets for function 'test_known_size': ; CHECK: Alias sets for function 'test_known_size':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (ptr %s, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Memory locations: (ptr %s, LocationSize::precise(1))
define void @test_known_size(ptr noalias %s, ptr noalias %d) { define void @test_known_size(ptr noalias %s, ptr noalias %d) {
entry: entry:
call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 1, i1 false) call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 1, i1 false)
@ -16,8 +16,8 @@ entry:
; CHECK: Alias sets for function 'test_unknown_size': ; CHECK: Alias sets for function 'test_unknown_size':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %d, unknown after) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %d, unknown after)
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (ptr %s, unknown after) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Memory locations: (ptr %s, unknown after)
define void @test_unknown_size(ptr noalias %s, ptr noalias %d, i64 %len) { define void @test_unknown_size(ptr noalias %s, ptr noalias %d, i64 %len) {
entry: entry:
call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false) call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
@ -27,10 +27,10 @@ entry:
; CHECK: Alias sets for function 'test1': ; CHECK: Alias sets for function 'test1':
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. ; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NOT: 1 Unknown instructions ; CHECK-NOT: 1 Unknown instructions
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test1(ptr %s, ptr %d) { define void @test1(ptr %s, ptr %d) {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -43,10 +43,10 @@ entry:
; CHECK: Alias sets for function 'test1_atomic': ; CHECK: Alias sets for function 'test1_atomic':
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. ; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NOT: 1 Unknown instructions ; CHECK-NOT: 1 Unknown instructions
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test1_atomic(ptr %s, ptr %d) { define void @test1_atomic(ptr %s, ptr %d) {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -59,10 +59,10 @@ entry:
; CHECK: Alias sets for function 'test2': ; CHECK: Alias sets for function 'test2':
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. ; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NOT: 1 Unknown instructions ; CHECK-NOT: 1 Unknown instructions
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test2(ptr %s, ptr %d) { define void @test2(ptr %s, ptr %d) {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -75,10 +75,10 @@ entry:
; CHECK: Alias sets for function 'test3': ; CHECK: Alias sets for function 'test3':
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. ; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NOT: 1 Unknown instructions ; CHECK-NOT: 1 Unknown instructions
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test3(ptr %s, ptr %d) { define void @test3(ptr %s, ptr %d) {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -91,10 +91,10 @@ entry:
; CHECK: Alias sets for function 'test3_atomic': ; CHECK: Alias sets for function 'test3_atomic':
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. ; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NOT: 1 Unknown instructions ; CHECK-NOT: 1 Unknown instructions
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test3_atomic(ptr %s, ptr %d) { define void @test3_atomic(ptr %s, ptr %d) {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -107,10 +107,10 @@ entry:
; CHECK: Alias sets for function 'test4': ; CHECK: Alias sets for function 'test4':
; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. ; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK-NOT: 1 Unknown instructions ; CHECK-NOT: 1 Unknown instructions
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Memory locations: (ptr %d, LocationSize::precise(1)), (ptr %s, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test4(ptr %s, ptr %d) { define void @test4(ptr %s, ptr %d) {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -123,8 +123,8 @@ entry:
; CHECK: Alias sets for function 'test5': ; CHECK: Alias sets for function 'test5':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test5() { define void @test5() {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -137,8 +137,8 @@ entry:
; CHECK: Alias sets for function 'test5_atomic': ; CHECK: Alias sets for function 'test5_atomic':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test5_atomic() { define void @test5_atomic() {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -151,8 +151,8 @@ entry:
; CHECK: Alias sets for function 'test6': ; CHECK: Alias sets for function 'test6':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test6() { define void @test6() {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -165,8 +165,8 @@ entry:
; CHECK: Alias sets for function 'test6_atomic': ; CHECK: Alias sets for function 'test6_atomic':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(1))
define void @test6_atomic() { define void @test6_atomic() {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -179,8 +179,8 @@ entry:
; CHECK: Alias sets for function 'test7': ; CHECK: Alias sets for function 'test7':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %b, LocationSize::precise(1))
define void @test7() { define void @test7() {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1
@ -194,8 +194,8 @@ entry:
; CHECK: Alias sets for function 'test7_atomic': ; CHECK: Alias sets for function 'test7_atomic':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(1))
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (ptr %b, LocationSize::precise(1)) ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Memory locations: (ptr %b, LocationSize::precise(1))
define void @test7_atomic() { define void @test7_atomic() {
entry: entry:
%a = alloca i8, align 1 %a = alloca i8, align 1

View File

@ -1,47 +1,45 @@
; RUN: opt -passes=print-alias-sets -alias-set-saturation-threshold=2 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=NOSAT ; RUN: opt -passes=print-alias-sets -alias-set-saturation-threshold=4 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=NOSAT
; RUN: opt -passes=print-alias-sets -alias-set-saturation-threshold=1 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SAT ; RUN: opt -passes=print-alias-sets -alias-set-saturation-threshold=3 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SAT
; CHECK-LABEL: 'allmust' ; CHECK-LABEL: 'nomerge'
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(4)) ; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(4))
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(4)) ; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %b, LocationSize::precise(4)), (ptr %b1, LocationSize::precise(4))
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %c, LocationSize::precise(4)) define void @nomerge(i32 %k) {
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %d, LocationSize::precise(4))
define void @allmust() {
%a = alloca i32 %a = alloca i32
%b = alloca i32 %b = alloca [10 x i32]
%c = alloca i32
%d = alloca i32
store i32 1, ptr %a store i32 1, ptr %a
store i32 2, ptr %b store i32 2, ptr %b
store i32 3, ptr %c %b1 = getelementptr i32, ptr %b, i32 %k
store i32 4, ptr %d store i32 3, ptr %b1
ret void ret void
} }
; CHECK-LABEL: 'mergemay' ; CHECK-LABEL: 'mergemay'
; NOSAT: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4)) ; NOSAT: AliasSet[{{.*}}, 3] may alias, Mod Memory locations: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4)), (ptr %a2, LocationSize::precise(4))
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(4)) ; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(4))
; SAT: AliasSet[{{.*}}, 2] may alias, Mod forwarding to 0x[[FWD:[0-9a-f]*]] ; SAT: AliasSet[{{.*}}, 3] may alias, Mod forwarding to 0x[[FWD:[0-9a-f]*]]
; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD]] ; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD]]
; SAT: AliasSet[0x[[FWD]], 2] may alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4)), (ptr %b, LocationSize::precise(4)) ; SAT: AliasSet[0x[[FWD]], 2] may alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4)), (ptr %a2, LocationSize::precise(4)), (ptr %b, LocationSize::precise(4))
define void @mergemay(i32 %k) { define void @mergemay(i32 %k, i32 %l) {
%a = alloca i32 %a = alloca i32
%b = alloca i32 %b = alloca i32
store i32 1, ptr %a store i32 1, ptr %a
store i32 2, ptr %b store i32 2, ptr %b
%a1 = getelementptr i32, ptr %a, i32 %k %a1 = getelementptr i32, ptr %a, i32 %k
store i32 2, ptr %a1 store i32 2, ptr %a1
%a2 = getelementptr i32, ptr %a, i32 %l
store i32 2, ptr %a2
ret void ret void
} }
; CHECK-LABEL: 'mergemust' ; CHECK-LABEL: 'mergemust'
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(4)) ; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(4))
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(4)) ; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %b, LocationSize::precise(4))
; NOSAT: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %c, LocationSize::precise(4)), (ptr %d, LocationSize::precise(4)) ; NOSAT: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %c, LocationSize::precise(4)), (ptr %d, LocationSize::precise(4))
; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD:[0-9a-f]*]] ; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD:[0-9a-f]*]]
; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD]] ; SAT: AliasSet[{{.*}}, 1] must alias, Mod forwarding to 0x[[FWD]]
; SAT: AliasSet[{{.*}}, 2] may alias, Mod forwarding to 0x[[FWD]] ; SAT: AliasSet[{{.*}}, 2] may alias, Mod forwarding to 0x[[FWD]]
; SAT: AliasSet[0x[[FWD]], 3] may alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(4)), (ptr %b, LocationSize::precise(4)), (ptr %c, LocationSize::precise(4)), (ptr %d, LocationSize::precise(4)) ; SAT: AliasSet[0x[[FWD]], 3] may alias, Mod/Ref Memory locations: (ptr %a, LocationSize::precise(4)), (ptr %b, LocationSize::precise(4)), (ptr %c, LocationSize::precise(4)), (ptr %d, LocationSize::precise(4))
define void @mergemust(ptr %c, ptr %d) { define void @mergemust(ptr %c, ptr %d) {
%a = alloca i32 %a = alloca i32
%b = alloca i32 %b = alloca i32

View File

@ -9,15 +9,17 @@ define void @_Z4testP1S(ptr %s) {
; CHECK-LABEL: define void @_Z4testP1S( ; CHECK-LABEL: define void @_Z4testP1S(
; CHECK-SAME: ptr [[S:%.*]]) { ; CHECK-SAME: ptr [[S:%.*]]) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[S_PROMOTED:%.*]] = load ptr, ptr [[S]], align 4, !tbaa [[TBAA0:![0-9]+]]
; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.cond.cleanup: ; CHECK: for.cond.cleanup:
; CHECK-NEXT: [[ADD_PTR_I_LCSSA:%.*]] = phi ptr [ [[ADD_PTR_I:%.*]], [[FOR_BODY]] ]
; CHECK-NEXT: store ptr [[ADD_PTR_I_LCSSA]], ptr [[S]], align 4, !tbaa [[TBAA0]]
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; CHECK: for.body: ; CHECK: for.body:
; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] ; CHECK-NEXT: [[ADD_PTR_I1:%.*]] = phi ptr [ [[S_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD_PTR_I]], [[FOR_BODY]] ]
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S]], align 4, !tbaa [[TBAA0:![0-9]+]] ; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
; CHECK-NEXT: store i32 [[I_05]], ptr [[TMP0]], align 4, !tbaa [[TBAA5:![0-9]+]] ; CHECK-NEXT: store i32 [[I_05]], ptr [[ADD_PTR_I1]], align 4, !tbaa [[TBAA4:![0-9]+]]
; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i32 1 ; CHECK-NEXT: [[ADD_PTR_I]] = getelementptr inbounds i32, ptr [[ADD_PTR_I1]], i32 1
; CHECK-NEXT: store ptr [[ADD_PTR_I]], ptr [[S]], align 4, !tbaa [[TBAA7:![0-9]+]]
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_05]], 1 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_05]], 1
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], 100 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], 100
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
@ -48,12 +50,10 @@ for.body: ; preds = %entry, %for.body
!6 = !{!"int", !3, i64 0} !6 = !{!"int", !3, i64 0}
!7 = !{!2, !2, i64 0} !7 = !{!2, !2, i64 0}
;. ;.
; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META2:![0-9]+]], i64 0} ; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
; CHECK: [[META1]] = !{!"_ZTS1S", [[META2]], i64 0} ; CHECK: [[META1]] = !{!"any pointer", [[META2:![0-9]+]], i64 0}
; CHECK: [[META2]] = !{!"any pointer", [[META3:![0-9]+]], i64 0} ; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
; CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0} ; CHECK: [[META3]] = !{!"Simple C++ TBAA"}
; CHECK: [[META4]] = !{!"Simple C++ TBAA"} ; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
; CHECK: [[TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0} ; CHECK: [[META5]] = !{!"int", [[META2]], i64 0}
; CHECK: [[META6]] = !{!"int", [[META3]], i64 0}
; CHECK: [[TBAA7]] = !{[[META2]], [[META2]], i64 0}
;. ;.

View File

@ -3255,8 +3255,8 @@ ScopBuilder::buildAliasGroupsForAccesses() {
if (AS.isMustAlias() || AS.isForwardingAliasSet()) if (AS.isMustAlias() || AS.isForwardingAliasSet())
continue; continue;
AliasGroupTy AG; AliasGroupTy AG;
for (auto &PR : AS) for (const Value *Ptr : AS.getPointers())
AG.push_back(PtrToAcc[PR.getValue()]); AG.push_back(PtrToAcc[const_cast<Value *>(Ptr)]);
if (AG.size() < 2) if (AG.size() < 2)
continue; continue;
AliasGroups.push_back(std::move(AG)); AliasGroups.push_back(std::move(AG));

View File

@ -1149,6 +1149,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
// sure the base pointer is not an instruction defined inside the scop. // sure the base pointer is not an instruction defined inside the scop.
// However, we can ignore loads that will be hoisted. // However, we can ignore loads that will be hoisted.
auto ASPointers = AS.getPointers();
InvariantLoadsSetTy VariantLS, InvariantLS; InvariantLoadsSetTy VariantLS, InvariantLS;
// In order to detect loads which are dependent on other invariant loads // In order to detect loads which are dependent on other invariant loads
// as invariant, we use fixed-point iteration method here i.e we iterate // as invariant, we use fixed-point iteration method here i.e we iterate
@ -1158,8 +1160,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
const unsigned int VariantSize = VariantLS.size(), const unsigned int VariantSize = VariantLS.size(),
InvariantSize = InvariantLS.size(); InvariantSize = InvariantLS.size();
for (const auto &Ptr : AS) { for (const Value *Ptr : ASPointers) {
Instruction *Inst = dyn_cast<Instruction>(Ptr.getValue()); Instruction *Inst = dyn_cast<Instruction>(const_cast<Value *>(Ptr));
if (Inst && Context.CurRegion.contains(Inst)) { if (Inst && Context.CurRegion.contains(Inst)) {
auto *Load = dyn_cast<LoadInst>(Inst); auto *Load = dyn_cast<LoadInst>(Inst);
if (Load && InvariantLS.count(Load)) if (Load && InvariantLS.count(Load))

View File

@ -638,8 +638,7 @@ bool ReportNonSimpleMemoryAccess::classof(const RejectReason *RR) {
ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS) ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
: RejectReason(RejectReasonKind::Alias), Inst(Inst) { : RejectReason(RejectReasonKind::Alias), Inst(Inst) {
for (const auto &I : AS) append_range(Pointers, AS.getPointers());
Pointers.push_back(I.getValue());
} }
std::string ReportAlias::formatInvalidAlias(std::string Prefix, std::string ReportAlias::formatInvalidAlias(std::string Prefix,