mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-22 21:30:10 +00:00
[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:
parent
8fb685fb7e
commit
656bf13004
@ -7,7 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// object refers to memory disjoint from the other sets.
|
||||
//
|
||||
@ -19,7 +19,7 @@
|
||||
#define LLVM_ANALYSIS_ALIASSETTRACKER_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_node.h"
|
||||
#include "llvm/Analysis/MemoryLocation.h"
|
||||
@ -27,8 +27,6 @@
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
@ -49,99 +47,12 @@ class Value;
|
||||
class AliasSet : public ilist_node<AliasSet> {
|
||||
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.
|
||||
AliasSet *Forward = nullptr;
|
||||
|
||||
/// Memory locations in this alias set.
|
||||
SmallVector<MemoryLocation, 0> MemoryLocs;
|
||||
|
||||
/// All instructions without a specific address in this alias set.
|
||||
std::vector<AssertingVH<Instruction>> UnknownInsts;
|
||||
|
||||
@ -178,8 +89,6 @@ class AliasSet : public ilist_node<AliasSet> {
|
||||
};
|
||||
unsigned Alias : 1;
|
||||
|
||||
unsigned SetSize = 0;
|
||||
|
||||
void addRef() { ++RefCount; }
|
||||
|
||||
void dropRef(AliasSetTracker &AST) {
|
||||
@ -205,95 +114,40 @@ public:
|
||||
/// Merge the specified alias set into this alias set.
|
||||
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA);
|
||||
|
||||
// Alias Set iteration - Allow access to all of the pointers which are part of
|
||||
// this alias set.
|
||||
class iterator;
|
||||
iterator begin() const { return iterator(PtrList); }
|
||||
iterator end() const { return iterator(); }
|
||||
bool empty() const { return PtrList == nullptr; }
|
||||
// Alias Set iteration - Allow access to all of the memory locations which are
|
||||
// part of this alias set.
|
||||
using iterator = SmallVectorImpl<MemoryLocation>::const_iterator;
|
||||
iterator begin() const { return MemoryLocs.begin(); }
|
||||
iterator end() const { return MemoryLocs.end(); }
|
||||
|
||||
// Unfortunately, ilist::size() is linear, so we have to add code to keep
|
||||
// track of the list's exact size.
|
||||
unsigned size() { return SetSize; }
|
||||
unsigned size() { return MemoryLocs.size(); }
|
||||
|
||||
/// 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 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:
|
||||
// Can only be created by AliasSetTracker.
|
||||
AliasSet()
|
||||
: PtrListEnd(&PtrList), RefCount(0), AliasAny(false), Access(NoAccess),
|
||||
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;
|
||||
}
|
||||
: RefCount(0), AliasAny(false), Access(NoAccess), Alias(SetMustAlias) {}
|
||||
|
||||
void removeFromTracker(AliasSetTracker &AST);
|
||||
|
||||
void addPointer(AliasSetTracker &AST, PointerRec &Entry, LocationSize Size,
|
||||
const AAMDNodes &AAInfo, bool KnownMustAlias = false,
|
||||
bool SkipSizeUpdate = false);
|
||||
void addMemoryLocation(AliasSetTracker &AST, const MemoryLocation &MemLoc,
|
||||
bool KnownMustAlias = false);
|
||||
void addUnknownInst(Instruction *I, BatchAAResults &AA);
|
||||
|
||||
public:
|
||||
/// If the specified pointer "may" (or must) alias one of the members in the
|
||||
/// set return the appropriate AliasResult. Otherwise return NoAlias.
|
||||
AliasResult aliasesPointer(const Value *Ptr, LocationSize Size,
|
||||
const AAMDNodes &AAInfo, BatchAAResults &AA) const;
|
||||
/// If the specified memory location "may" (or must) alias one of the members
|
||||
/// in the set return the appropriate AliasResult. Otherwise return NoAlias.
|
||||
AliasResult aliasesMemoryLocation(const MemoryLocation &MemLoc,
|
||||
BatchAAResults &AA) const;
|
||||
|
||||
ModRefInfo aliasesUnknownInst(const Instruction *Inst,
|
||||
BatchAAResults &AA) const;
|
||||
};
|
||||
@ -307,9 +161,10 @@ class AliasSetTracker {
|
||||
BatchAAResults &AA;
|
||||
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;
|
||||
|
||||
public:
|
||||
@ -327,9 +182,6 @@ public:
|
||||
/// 3. If the instruction aliases multiple sets, merge the sets, and add
|
||||
/// 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(LoadInst *LI);
|
||||
void add(StoreInst *SI);
|
||||
@ -370,31 +222,39 @@ public:
|
||||
private:
|
||||
friend class AliasSet;
|
||||
|
||||
// The total number of pointers contained in all "may" alias sets.
|
||||
unsigned TotalMayAliasSetSize = 0;
|
||||
// The total number of memory locations contained in all alias sets.
|
||||
unsigned TotalAliasSetSize = 0;
|
||||
|
||||
// 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;
|
||||
|
||||
void removeAliasSet(AliasSet *AS);
|
||||
|
||||
/// Just like operator[] on the map, except that it creates an entry for the
|
||||
/// pointer if it doesn't already exist.
|
||||
AliasSet::PointerRec &getEntryFor(Value *V) {
|
||||
AliasSet::PointerRec *&Entry = PointerMap[V];
|
||||
if (!Entry)
|
||||
Entry = new AliasSet::PointerRec(V);
|
||||
return *Entry;
|
||||
// Update an alias set field to point to its real destination. If the field is
|
||||
// pointing to a set that has been merged with another set and is forwarding,
|
||||
// the field is updated to point to the set obtained by following the
|
||||
// forwarding links. The Forward fields of intermediate alias sets are
|
||||
// collapsed as well, and alias set reference counts are updated to reflect
|
||||
// the new situation.
|
||||
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 *mergeAliasSetsForPointer(const Value *Ptr, LocationSize Size,
|
||||
const AAMDNodes &AAInfo,
|
||||
bool &MustAliasAll);
|
||||
AliasSet &addMemoryLocation(MemoryLocation Loc, AliasSet::AccessLattice E);
|
||||
AliasSet *mergeAliasSetsForMemoryLocation(const MemoryLocation &MemLoc,
|
||||
AliasSet *PtrAS,
|
||||
bool &MustAliasAll);
|
||||
|
||||
/// Merge all alias sets into a single set that is considered to alias any
|
||||
/// pointer.
|
||||
/// Merge all alias sets into a single set that is considered to alias
|
||||
/// any memory location or instruction.
|
||||
AliasSet &mergeAllAliasSets();
|
||||
|
||||
AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
|
||||
|
@ -11,6 +11,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Analysis/AliasSetTracker.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/GuardUtils.h"
|
||||
@ -34,11 +35,10 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<unsigned>
|
||||
SaturationThreshold("alias-set-saturation-threshold", cl::Hidden,
|
||||
cl::init(250),
|
||||
cl::desc("The maximum number of pointers may-alias "
|
||||
"sets may contain before degradation"));
|
||||
static cl::opt<unsigned> SaturationThreshold(
|
||||
"alias-set-saturation-threshold", cl::Hidden, cl::init(250),
|
||||
cl::desc("The maximum total number of memory locations alias "
|
||||
"sets may contain before degradation"));
|
||||
|
||||
/// mergeSetIn - Merge the specified alias set into this alias set.
|
||||
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(!Forward && "This set is a forwarding set!!");
|
||||
|
||||
bool WasMustAlias = (Alias == SetMustAlias);
|
||||
// Update the alias and access types of this set...
|
||||
Access |= AS.Access;
|
||||
Alias |= AS.Alias;
|
||||
|
||||
if (Alias == SetMustAlias) {
|
||||
// Check that these two merged sets really are must aliases. Since both
|
||||
// used to be must-alias sets, we can just check any pointer from each set
|
||||
// for aliasing.
|
||||
PointerRec *L = getSomePointer();
|
||||
PointerRec *R = AS.getSomePointer();
|
||||
|
||||
// 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())))
|
||||
// Check that these two merged sets really are must aliases. If we cannot
|
||||
// find a must-alias pair between them, this set becomes a may alias.
|
||||
if (!any_of(MemoryLocs, [&](const MemoryLocation &MemLoc) {
|
||||
return any_of(AS.MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
|
||||
return BatchAA.isMustAlias(MemLoc, ASMemLoc);
|
||||
});
|
||||
}))
|
||||
Alias = SetMayAlias;
|
||||
}
|
||||
|
||||
if (Alias == SetMayAlias) {
|
||||
if (WasMustAlias)
|
||||
AST.TotalMayAliasSetSize += size();
|
||||
if (AS.Alias == SetMustAlias)
|
||||
AST.TotalMayAliasSetSize += AS.size();
|
||||
// Merge the list of constituent memory locations...
|
||||
if (MemoryLocs.empty()) {
|
||||
std::swap(MemoryLocs, AS.MemoryLocs);
|
||||
} else {
|
||||
append_range(MemoryLocs, AS.MemoryLocs);
|
||||
AS.MemoryLocs.clear();
|
||||
}
|
||||
|
||||
bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
|
||||
@ -86,18 +83,6 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
|
||||
AS.Forward = this; // Forward across AS now...
|
||||
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)
|
||||
AS.dropRef(AST);
|
||||
}
|
||||
@ -106,9 +91,8 @@ void AliasSetTracker::removeAliasSet(AliasSet *AS) {
|
||||
if (AliasSet *Fwd = AS->Forward) {
|
||||
Fwd->dropRef(*this);
|
||||
AS->Forward = nullptr;
|
||||
} else // Update TotalMayAliasSetSize only if not forwarding.
|
||||
if (AS->Alias == AliasSet::SetMayAlias)
|
||||
TotalMayAliasSetSize -= AS->size();
|
||||
} else // Update TotalAliasSetSize only if not forwarding.
|
||||
TotalAliasSetSize -= AS->size();
|
||||
|
||||
AliasSets.erase(AS);
|
||||
// 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);
|
||||
}
|
||||
|
||||
void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
|
||||
LocationSize Size, const AAMDNodes &AAInfo,
|
||||
bool KnownMustAlias, bool SkipSizeUpdate) {
|
||||
assert(!Entry.hasAliasSet() && "Entry already in set!");
|
||||
|
||||
// Check to see if we have to downgrade to _may_ alias.
|
||||
if (isMustAlias())
|
||||
if (PointerRec *P = getSomePointer()) {
|
||||
if (!KnownMustAlias) {
|
||||
BatchAAResults &AA = AST.getAliasAnalysis();
|
||||
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);
|
||||
void AliasSet::addMemoryLocation(AliasSetTracker &AST,
|
||||
const MemoryLocation &MemLoc,
|
||||
bool KnownMustAlias) {
|
||||
if (isMustAlias() && !KnownMustAlias) {
|
||||
// If we cannot find a must-alias with any of the existing MemoryLocs, we
|
||||
// must downgrade to may-alias.
|
||||
if (!any_of(MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
|
||||
return AST.getAliasAnalysis().isMustAlias(MemLoc, ASMemLoc);
|
||||
}))
|
||||
Alias = SetMayAlias;
|
||||
}
|
||||
|
||||
// Add it to the end of the list...
|
||||
++SetSize;
|
||||
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();
|
||||
MemoryLocs.push_back(MemLoc);
|
||||
|
||||
if (Alias == SetMayAlias)
|
||||
AST.TotalMayAliasSetSize++;
|
||||
AST.TotalAliasSetSize++;
|
||||
}
|
||||
|
||||
void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
|
||||
@ -183,45 +147,26 @@ void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
|
||||
Access = ModRefAccess;
|
||||
}
|
||||
|
||||
/// aliasesPointer - If the specified pointer "may" (or must) alias one of the
|
||||
/// members in the set return the appropriate AliasResult. Otherwise return
|
||||
/// NoAlias.
|
||||
/// aliasesMemoryLocation - If the specified memory location "may" (or must)
|
||||
/// alias one of the members in the set return the appropriate AliasResult.
|
||||
/// Otherwise return NoAlias.
|
||||
///
|
||||
AliasResult AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size,
|
||||
const AAMDNodes &AAInfo,
|
||||
BatchAAResults &AA) const {
|
||||
AliasResult AliasSet::aliasesMemoryLocation(const MemoryLocation &MemLoc,
|
||||
BatchAAResults &AA) const {
|
||||
if (AliasAny)
|
||||
return AliasResult::MayAlias;
|
||||
|
||||
if (Alias == SetMustAlias) {
|
||||
assert(UnknownInsts.empty() && "Illegal must alias set!");
|
||||
|
||||
// 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()));
|
||||
// Check all of the memory locations in the set...
|
||||
for (const auto &ASMemLoc : MemoryLocs) {
|
||||
AliasResult AR = AA.alias(MemLoc, ASMemLoc);
|
||||
if (AR != AliasResult::NoAlias)
|
||||
return AR;
|
||||
}
|
||||
|
||||
// Check the unknown instructions...
|
||||
if (!UnknownInsts.empty()) {
|
||||
for (Instruction *Inst : UnknownInsts)
|
||||
if (isModOrRefSet(
|
||||
AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo))))
|
||||
return AliasResult::MayAlias;
|
||||
}
|
||||
for (Instruction *Inst : UnknownInsts)
|
||||
if (isModOrRefSet(AA.getModRefInfo(Inst, MemLoc)))
|
||||
return AliasResult::MayAlias;
|
||||
|
||||
return AliasResult::NoAlias;
|
||||
}
|
||||
@ -246,9 +191,8 @@ ModRefInfo AliasSet::aliasesUnknownInst(const Instruction *Inst,
|
||||
}
|
||||
|
||||
ModRefInfo MR = ModRefInfo::NoModRef;
|
||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
||||
MR |= AA.getModRefInfo(
|
||||
Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));
|
||||
for (const auto &ASMemLoc : MemoryLocs) {
|
||||
MR |= AA.getModRefInfo(Inst, ASMemLoc);
|
||||
if (isModAndRefSet(MR))
|
||||
return MR;
|
||||
}
|
||||
@ -256,37 +200,46 @@ ModRefInfo AliasSet::aliasesUnknownInst(const Instruction *Inst,
|
||||
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() {
|
||||
// Delete all the PointerRec entries.
|
||||
for (auto &I : PointerMap)
|
||||
I.second->eraseFromList();
|
||||
|
||||
PointerMap.clear();
|
||||
|
||||
// The alias sets should all be clear now.
|
||||
AliasSets.clear();
|
||||
}
|
||||
|
||||
/// mergeAliasSetsForPointer - Given a pointer, merge all alias sets that may
|
||||
/// alias the pointer. Return the unified set, or nullptr if no set that aliases
|
||||
/// the pointer was found. MustAliasAll is updated to true/false if the pointer
|
||||
/// is found to MustAlias all the sets it merged.
|
||||
AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr,
|
||||
LocationSize Size,
|
||||
const AAMDNodes &AAInfo,
|
||||
bool &MustAliasAll) {
|
||||
/// mergeAliasSetsForMemoryLocation - Given a memory location, merge all alias
|
||||
/// sets that may alias it. Return the unified set, or nullptr if no aliasing
|
||||
/// set was found. A known existing alias set for the pointer value of the
|
||||
/// memory location can be passed in (or nullptr if not available). MustAliasAll
|
||||
/// is updated to true/false if the memory location is found to MustAlias all
|
||||
/// the sets it merged.
|
||||
AliasSet *AliasSetTracker::mergeAliasSetsForMemoryLocation(
|
||||
const MemoryLocation &MemLoc, AliasSet *PtrAS, bool &MustAliasAll) {
|
||||
AliasSet *FoundSet = nullptr;
|
||||
MustAliasAll = true;
|
||||
for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
|
||||
if (AS.Forward)
|
||||
continue;
|
||||
|
||||
AliasResult AR = AS.aliasesPointer(Ptr, Size, AAInfo, AA);
|
||||
if (AR == AliasResult::NoAlias)
|
||||
continue;
|
||||
// An alias set that already contains a memory location with the same
|
||||
// pointer value is directly assumed to MustAlias; we bypass the AA query in
|
||||
// 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)
|
||||
MustAliasAll = false;
|
||||
if (AR != AliasResult::MustAlias)
|
||||
MustAliasAll = false;
|
||||
}
|
||||
|
||||
if (!FoundSet) {
|
||||
// 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) {
|
||||
// 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);
|
||||
const LocationSize Size = MemLoc.Size;
|
||||
const AAMDNodes &AAInfo = MemLoc.AATags;
|
||||
|
||||
AliasSet::PointerRec &Entry = getEntryFor(Pointer);
|
||||
|
||||
AliasSet *AS;
|
||||
bool MustAliasAll = false;
|
||||
if (AliasAnyAS) {
|
||||
// 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
|
||||
// just need to add the pointer to that set to keep the data structure
|
||||
// consistent.
|
||||
// just need to add the memory location to that set to keep the data
|
||||
// structure consistent.
|
||||
// This, of course, means that we will never need a merge here.
|
||||
if (Entry.hasAliasSet()) {
|
||||
Entry.updateSizeAndAAInfo(Size, AAInfo);
|
||||
assert(Entry.getAliasSet(*this) == AliasAnyAS &&
|
||||
"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)) {
|
||||
AS = AliasAnyAS;
|
||||
} else if (AliasSet *AliasAS = mergeAliasSetsForMemoryLocation(
|
||||
MemLoc, MapEntry, MustAliasAll)) {
|
||||
// Add it to the alias set it aliases.
|
||||
AS->addPointer(*this, Entry, Size, AAInfo, MustAliasAll);
|
||||
return *AS;
|
||||
AS = AliasAS;
|
||||
} 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.
|
||||
AliasSets.push_back(new AliasSet());
|
||||
AliasSets.back().addPointer(*this, Entry, Size, AAInfo, true);
|
||||
return AliasSets.back();
|
||||
// Register memory location in selected alias set.
|
||||
AS->addMemoryLocation(*this, MemLoc, MustAliasAll);
|
||||
// Register selected alias set in pointer map (or ensure it is consistent with
|
||||
// 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) {
|
||||
addPointer(Loc, AliasSet::NoAccess);
|
||||
addMemoryLocation(Loc, AliasSet::NoAccess);
|
||||
}
|
||||
|
||||
void AliasSetTracker::add(LoadInst *LI) {
|
||||
if (isStrongerThanMonotonic(LI->getOrdering()))
|
||||
return addUnknown(LI);
|
||||
addPointer(MemoryLocation::get(LI), AliasSet::RefAccess);
|
||||
addMemoryLocation(MemoryLocation::get(LI), AliasSet::RefAccess);
|
||||
}
|
||||
|
||||
void AliasSetTracker::add(StoreInst *SI) {
|
||||
if (isStrongerThanMonotonic(SI->getOrdering()))
|
||||
return addUnknown(SI);
|
||||
addPointer(MemoryLocation::get(SI), AliasSet::ModAccess);
|
||||
addMemoryLocation(MemoryLocation::get(SI), AliasSet::ModAccess);
|
||||
}
|
||||
|
||||
void AliasSetTracker::add(VAArgInst *VAAI) {
|
||||
addPointer(MemoryLocation::get(VAAI), AliasSet::ModRefAccess);
|
||||
addMemoryLocation(MemoryLocation::get(VAAI), AliasSet::ModRefAccess);
|
||||
}
|
||||
|
||||
void AliasSetTracker::add(AnyMemSetInst *MSI) {
|
||||
addPointer(MemoryLocation::getForDest(MSI), AliasSet::ModAccess);
|
||||
addMemoryLocation(MemoryLocation::getForDest(MSI), AliasSet::ModAccess);
|
||||
}
|
||||
|
||||
void AliasSetTracker::add(AnyMemTransferInst *MTI) {
|
||||
addPointer(MemoryLocation::getForDest(MTI), AliasSet::ModAccess);
|
||||
addPointer(MemoryLocation::getForSource(MTI), AliasSet::RefAccess);
|
||||
addMemoryLocation(MemoryLocation::getForDest(MTI), AliasSet::ModAccess);
|
||||
addMemoryLocation(MemoryLocation::getForSource(MTI), AliasSet::RefAccess);
|
||||
}
|
||||
|
||||
void AliasSetTracker::addUnknown(Instruction *Inst) {
|
||||
@ -480,7 +419,7 @@ void AliasSetTracker::add(Instruction *I) {
|
||||
ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
|
||||
ArgMask &= CallMask;
|
||||
if (!isNoModRef(ArgMask))
|
||||
addPointer(ArgLoc, getAccessFromModRef(ArgMask));
|
||||
addMemoryLocation(ArgLoc, getAccessFromModRef(ArgMask));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -497,7 +436,7 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
|
||||
assert(&AA == &AST.AA &&
|
||||
"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
|
||||
// merged together in the current AST.
|
||||
for (const AliasSet &AS : AST) {
|
||||
@ -508,16 +447,14 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
|
||||
for (Instruction *Inst : AS.UnknownInsts)
|
||||
add(Inst);
|
||||
|
||||
// Loop over all of the pointers in this alias set.
|
||||
for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI)
|
||||
addPointer(
|
||||
MemoryLocation(ASI.getPointer(), ASI.getSize(), ASI.getAAInfo()),
|
||||
(AliasSet::AccessLattice)AS.Access);
|
||||
// Loop over all of the memory locations in this alias set.
|
||||
for (const MemoryLocation &ASMemLoc : AS.MemoryLocs)
|
||||
addMemoryLocation(ASMemLoc, (AliasSet::AccessLattice)AS.Access);
|
||||
}
|
||||
}
|
||||
|
||||
AliasSet &AliasSetTracker::mergeAllAliasSets() {
|
||||
assert(!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold) &&
|
||||
assert(!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold) &&
|
||||
"Full merge should happen once, when the saturation threshold is "
|
||||
"reached");
|
||||
|
||||
@ -528,8 +465,8 @@ AliasSet &AliasSetTracker::mergeAllAliasSets() {
|
||||
for (AliasSet &AS : *this)
|
||||
ASVector.push_back(&AS);
|
||||
|
||||
// Copy all instructions and pointers into a new set, and forward all other
|
||||
// sets to it.
|
||||
// Copy all instructions and memory locations into a new set, and forward all
|
||||
// other sets to it.
|
||||
AliasSets.push_back(new AliasSet());
|
||||
AliasAnyAS = &AliasSets.back();
|
||||
AliasAnyAS->Alias = AliasSet::SetMayAlias;
|
||||
@ -553,14 +490,14 @@ AliasSet &AliasSetTracker::mergeAllAliasSets() {
|
||||
return *AliasAnyAS;
|
||||
}
|
||||
|
||||
AliasSet &AliasSetTracker::addPointer(MemoryLocation Loc,
|
||||
AliasSet::AccessLattice E) {
|
||||
AliasSet &AliasSetTracker::addMemoryLocation(MemoryLocation Loc,
|
||||
AliasSet::AccessLattice E) {
|
||||
AliasSet &AS = getAliasSetFor(Loc);
|
||||
AS.Access |= E;
|
||||
|
||||
if (!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold)) {
|
||||
if (!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold)) {
|
||||
// The AST is now saturated. From here on, we conservatively consider all
|
||||
// pointers to alias each-other.
|
||||
// elements to alias each-other.
|
||||
return mergeAllAliasSets();
|
||||
}
|
||||
|
||||
@ -584,17 +521,18 @@ void AliasSet::print(raw_ostream &OS) const {
|
||||
if (Forward)
|
||||
OS << " forwarding to " << (void*)Forward;
|
||||
|
||||
if (!empty()) {
|
||||
OS << "Pointers: ";
|
||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
||||
if (I != begin()) OS << ", ";
|
||||
I.getPointer()->printAsOperand(OS << "(");
|
||||
if (I.getSize() == LocationSize::afterPointer())
|
||||
if (!MemoryLocs.empty()) {
|
||||
ListSeparator LS;
|
||||
OS << "Memory locations: ";
|
||||
for (const MemoryLocation &MemLoc : MemoryLocs) {
|
||||
OS << LS;
|
||||
MemLoc.Ptr->printAsOperand(OS << "(");
|
||||
if (MemLoc.Size == LocationSize::afterPointer())
|
||||
OS << ", unknown after)";
|
||||
else if (I.getSize() == LocationSize::beforeOrAfterPointer())
|
||||
else if (MemLoc.Size == LocationSize::beforeOrAfterPointer())
|
||||
OS << ", unknown before-or-after)";
|
||||
else
|
||||
OS << ", " << I.getSize() << ")";
|
||||
OS << ", " << MemLoc.Size << ")";
|
||||
}
|
||||
}
|
||||
if (!UnknownInsts.empty()) {
|
||||
|
@ -1115,6 +1115,7 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
|
||||
int NumWritePtrChecks = 0;
|
||||
bool CanDoAliasSetRT = true;
|
||||
++ASId;
|
||||
auto ASPointers = AS.getPointers();
|
||||
|
||||
// We assign consecutive id to access from different dependence sets.
|
||||
// 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
|
||||
// collect MemAccessInfos for later.
|
||||
SmallVector<MemAccessInfo, 4> AccessInfos;
|
||||
for (const auto &A : AS) {
|
||||
Value *Ptr = A.getValue();
|
||||
for (const Value *Ptr_ : ASPointers) {
|
||||
Value *Ptr = const_cast<Value *>(Ptr_);
|
||||
bool IsWrite = Accesses.count(MemAccessInfo(Ptr, true));
|
||||
if (IsWrite)
|
||||
++NumWritePtrChecks;
|
||||
@ -1140,10 +1141,11 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
|
||||
// or a single write and no reads.
|
||||
if (NumWritePtrChecks == 0 ||
|
||||
(NumWritePtrChecks == 1 && NumReadPtrChecks == 0)) {
|
||||
assert((AS.size() <= 1 ||
|
||||
all_of(AS,
|
||||
[this](auto AC) {
|
||||
MemAccessInfo AccessWrite(AC.getValue(), true);
|
||||
assert((ASPointers.size() <= 1 ||
|
||||
all_of(ASPointers,
|
||||
[this](const Value *Ptr) {
|
||||
MemAccessInfo AccessWrite(const_cast<Value *>(Ptr),
|
||||
true);
|
||||
return DepCands.findValue(AccessWrite) == DepCands.end();
|
||||
})) &&
|
||||
"Can only skip updating CanDoRT below, if all entries in AS "
|
||||
@ -1271,8 +1273,9 @@ void AccessAnalysis::processMemAccesses() {
|
||||
// set.
|
||||
for (const auto &AS : AST) {
|
||||
// Note that both the alias-set tracker and the alias sets themselves used
|
||||
// linked lists internally and so the iteration order here is deterministic
|
||||
// (matching the original instruction order within each set).
|
||||
// ordered collections internally and so the iteration order here is
|
||||
// deterministic.
|
||||
auto ASPointers = AS.getPointers();
|
||||
|
||||
bool SetHasWrite = false;
|
||||
|
||||
@ -1289,8 +1292,8 @@ void AccessAnalysis::processMemAccesses() {
|
||||
bool UseDeferred = SetIteration > 0;
|
||||
PtrAccessMap &S = UseDeferred ? DeferredAccesses : Accesses;
|
||||
|
||||
for (const auto &AV : AS) {
|
||||
Value *Ptr = AV.getValue();
|
||||
for (const Value *Ptr_ : ASPointers) {
|
||||
Value *Ptr = const_cast<Value *>(Ptr_);
|
||||
|
||||
// For a single memory access in AliasSetTracker, Accesses may contain
|
||||
// both read and write, and they both need to be handled for CheckDeps.
|
||||
|
@ -2323,8 +2323,8 @@ collectPromotionCandidates(MemorySSA *MSSA, AliasAnalysis *AA, Loop *L) {
|
||||
SmallVector<std::pair<SmallSetVector<Value *, 8>, bool>, 0> Result;
|
||||
for (auto [Set, HasReadsOutsideSet] : Sets) {
|
||||
SmallSetVector<Value *, 8> PointerMustAliases;
|
||||
for (const auto &ASI : *Set)
|
||||
PointerMustAliases.insert(ASI.getValue());
|
||||
for (const auto &MemLoc : *Set)
|
||||
PointerMustAliases.insert(const_cast<Value *>(MemLoc.Ptr));
|
||||
Result.emplace_back(std::move(PointerMustAliases), HasReadsOutsideSet);
|
||||
}
|
||||
|
||||
|
@ -258,13 +258,13 @@ bool LoopVersioningLICM::legalLoopMemoryAccesses() {
|
||||
// With MustAlias its not worth adding runtime bound check.
|
||||
if (AS.isMustAlias())
|
||||
return false;
|
||||
Value *SomePtr = AS.begin()->getValue();
|
||||
const Value *SomePtr = AS.begin()->Ptr;
|
||||
bool TypeCheck = true;
|
||||
// Check for Mod & MayAlias
|
||||
HasMayAlias |= AS.isMayAlias();
|
||||
HasMod |= AS.isMod();
|
||||
for (const auto &A : AS) {
|
||||
Value *Ptr = A.getValue();
|
||||
for (const auto &MemLoc : AS) {
|
||||
const Value *Ptr = MemLoc.Ptr;
|
||||
// Alias tracker should have pointers of same data type.
|
||||
//
|
||||
// FIXME: check no longer effective since opaque pointers?
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
; CHECK: Alias sets for function 'test_alloca_argmemonly':
|
||||
; 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]+}}, 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]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||
; 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) {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -17,8 +17,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test_readonly_arg'
|
||||
; 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, Ref Pointers: (ptr %s, 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 Memory locations: (ptr %s, unknown before-or-after), (ptr %s, LocationSize::precise(1))
|
||||
define i8 @test_readonly_arg(ptr noalias %s, ptr noalias %d) {
|
||||
entry:
|
||||
call void @my_memcpy(ptr %d, ptr %s, i64 1)
|
||||
@ -28,8 +28,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test_noalias_argmemonly':
|
||||
; 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]+}}, 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]+}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(1))
|
||||
; 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) {
|
||||
entry:
|
||||
store i8 1, ptr %a, align 1
|
||||
@ -39,8 +39,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test5':
|
||||
; 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 Pointers: (ptr %b, 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 Memory locations: (ptr %b, unknown before-or-after), (ptr %b, LocationSize::precise(1))
|
||||
define void @test5(ptr noalias %a, ptr noalias %b) {
|
||||
entry:
|
||||
store i8 1, ptr %a, align 1
|
||||
@ -51,8 +51,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test_argcollapse':
|
||||
; 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 Pointers: (ptr %b, 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 Memory locations: (ptr %b, unknown before-or-after), (ptr %b, LocationSize::precise(1))
|
||||
define void @test_argcollapse(ptr noalias %a, ptr noalias %b) {
|
||||
entry:
|
||||
store i8 1, ptr %a, align 1
|
||||
@ -63,8 +63,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test_memcpy1':
|
||||
; 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 Pointers: (ptr %a, 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 Memory locations: (ptr %a, unknown before-or-after)
|
||||
define void @test_memcpy1(ptr noalias %a, ptr noalias %b) {
|
||||
entry:
|
||||
call void @my_memcpy(ptr %b, ptr %a, i64 1)
|
||||
@ -74,7 +74,7 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test_memset1':
|
||||
; 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() {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -84,7 +84,7 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test_memset2':
|
||||
; 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) {
|
||||
entry:
|
||||
call void @my_memset(ptr %a, i8 0, i64 1)
|
||||
@ -93,7 +93,7 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test_memset3':
|
||||
; 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) {
|
||||
entry:
|
||||
call void @my_memset(ptr %a, i8 0, i64 1)
|
||||
@ -105,8 +105,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test_memset4':
|
||||
; 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 Pointers: (ptr %b, 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 Memory locations: (ptr %b, unknown before-or-after)
|
||||
define void @test_memset4(ptr noalias %a, ptr noalias %b) {
|
||||
entry:
|
||||
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-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) {
|
||||
entry:
|
||||
;; This call is effectively readnone since the argument is readonly
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,9 +2,9 @@
|
||||
|
||||
; CHECK: Alias sets for function 'test1':
|
||||
; 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: 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) {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -18,10 +18,10 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test2':
|
||||
; 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: 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) {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -35,7 +35,7 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test3':
|
||||
; 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"() ]
|
||||
define void @test3(i32 %c, ptr %a, ptr %b) {
|
||||
entry:
|
||||
@ -48,9 +48,9 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test4':
|
||||
; 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: 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) {
|
||||
entry:
|
||||
%b = alloca i8, align 1
|
||||
@ -63,9 +63,9 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test5':
|
||||
; 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: 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() {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
|
@ -2,7 +2,7 @@
|
||||
; RUN: opt -S < %s -passes=print-alias-sets 2>&1 | FileCheck %s
|
||||
|
||||
; 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) {;
|
||||
store <vscale x 2 x i64> zeroinitializer, 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: 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) {
|
||||
store i64 0, 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: 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) {
|
||||
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: 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) {
|
||||
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
|
||||
}
|
||||
; 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) {
|
||||
%g = getelementptr i8, ptr %p, i64 8
|
||||
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: 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) {
|
||||
%g = getelementptr i8, ptr %p, i64 8
|
||||
store <vscale x 2 x i64> zeroinitializer, ptr %p, align 2
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
; CHECK: Alias sets for function 'test_known_size':
|
||||
; 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) {
|
||||
entry:
|
||||
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 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) {
|
||||
entry:
|
||||
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 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) {
|
||||
entry:
|
||||
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 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) {
|
||||
entry:
|
||||
call void @llvm.memset.element.unordered.atomic.p0.i32(ptr align 1 %d, i8 0, i64 %len, i32 1)
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
; CHECK: Alias sets for function 'test_known_size':
|
||||
; 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, Ref Pointers: (ptr %s, 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 Memory locations: (ptr %s, LocationSize::precise(1))
|
||||
define void @test_known_size(ptr noalias %s, ptr noalias %d) {
|
||||
entry:
|
||||
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 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, Ref Pointers: (ptr %s, 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 Memory locations: (ptr %s, unknown after)
|
||||
define void @test_unknown_size(ptr noalias %s, ptr noalias %d, i64 %len) {
|
||||
entry:
|
||||
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 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: 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]+}}, 1] must alias, Mod Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test1(ptr %s, ptr %d) {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -43,10 +43,10 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test1_atomic':
|
||||
; 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: 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]+}}, 1] must alias, Mod Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test1_atomic(ptr %s, ptr %d) {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -59,10 +59,10 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test2':
|
||||
; 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: 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]+}}, 1] must alias, Mod Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test2(ptr %s, ptr %d) {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -75,10 +75,10 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test3':
|
||||
; 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: 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]+}}, 1] must alias, Mod Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test3(ptr %s, ptr %d) {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -91,10 +91,10 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test3_atomic':
|
||||
; 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: 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]+}}, 1] must alias, Mod Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test3_atomic(ptr %s, ptr %d) {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -107,10 +107,10 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test4':
|
||||
; 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: 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]+}}, 1] must alias, Mod Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test4(ptr %s, ptr %d) {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -123,8 +123,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test5':
|
||||
; 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 Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test5() {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -137,8 +137,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test5_atomic':
|
||||
; 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 Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test5_atomic() {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -151,8 +151,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test6':
|
||||
; 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 Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test6() {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -165,8 +165,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test6_atomic':
|
||||
; 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 Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test6_atomic() {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -179,8 +179,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test7':
|
||||
; 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 Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test7() {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
@ -194,8 +194,8 @@ entry:
|
||||
|
||||
; CHECK: Alias sets for function 'test7_atomic':
|
||||
; 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 Pointers: (ptr %b, 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 Memory locations: (ptr %b, LocationSize::precise(1))
|
||||
define void @test7_atomic() {
|
||||
entry:
|
||||
%a = alloca i8, align 1
|
||||
|
@ -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=1 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SAT
|
||||
; 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=3 -S -o - < %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SAT
|
||||
|
||||
; CHECK-LABEL: 'allmust'
|
||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(4))
|
||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(4))
|
||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %c, LocationSize::precise(4))
|
||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %d, LocationSize::precise(4))
|
||||
define void @allmust() {
|
||||
; CHECK-LABEL: 'nomerge'
|
||||
; CHECK: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(4))
|
||||
; CHECK: AliasSet[{{.*}}, 2] may alias, Mod Memory locations: (ptr %b, LocationSize::precise(4)), (ptr %b1, LocationSize::precise(4))
|
||||
define void @nomerge(i32 %k) {
|
||||
%a = alloca i32
|
||||
%b = alloca i32
|
||||
%c = alloca i32
|
||||
%d = alloca i32
|
||||
%b = alloca [10 x i32]
|
||||
store i32 1, ptr %a
|
||||
store i32 2, ptr %b
|
||||
store i32 3, ptr %c
|
||||
store i32 4, ptr %d
|
||||
%b1 = getelementptr i32, ptr %b, i32 %k
|
||||
store i32 3, ptr %b1
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: 'mergemay'
|
||||
; NOSAT: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4))
|
||||
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(4))
|
||||
; SAT: AliasSet[{{.*}}, 2] may alias, Mod forwarding to 0x[[FWD:[0-9a-f]*]]
|
||||
; 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 Memory locations: (ptr %b, LocationSize::precise(4))
|
||||
; 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[0x[[FWD]], 2] may alias, Mod/Ref Pointers: (ptr %a, LocationSize::precise(4)), (ptr %a1, LocationSize::precise(4)), (ptr %b, LocationSize::precise(4))
|
||||
define void @mergemay(i32 %k) {
|
||||
; 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, i32 %l) {
|
||||
%a = alloca i32
|
||||
%b = alloca i32
|
||||
store i32 1, ptr %a
|
||||
store i32 2, ptr %b
|
||||
%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
|
||||
}
|
||||
|
||||
; CHECK-LABEL: 'mergemust'
|
||||
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %a, LocationSize::precise(4))
|
||||
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Pointers: (ptr %b, LocationSize::precise(4))
|
||||
; NOSAT: AliasSet[{{.*}}, 2] may alias, Mod Pointers: (ptr %c, LocationSize::precise(4)), (ptr %d, LocationSize::precise(4))
|
||||
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %a, LocationSize::precise(4))
|
||||
; NOSAT: AliasSet[{{.*}}, 1] must alias, Mod Memory locations: (ptr %b, 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]]
|
||||
; 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) {
|
||||
%a = alloca i32
|
||||
%b = alloca i32
|
||||
|
@ -9,15 +9,17 @@ define void @_Z4testP1S(ptr %s) {
|
||||
; CHECK-LABEL: define void @_Z4testP1S(
|
||||
; CHECK-SAME: ptr [[S:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[S_PROMOTED:%.*]] = load ptr, ptr [[S]], align 4, !tbaa [[TBAA0:![0-9]+]]
|
||||
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
||||
; 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: for.body:
|
||||
; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S]], align 4, !tbaa [[TBAA0:![0-9]+]]
|
||||
; CHECK-NEXT: store i32 [[I_05]], ptr [[TMP0]], align 4, !tbaa [[TBAA5:![0-9]+]]
|
||||
; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i32 1
|
||||
; CHECK-NEXT: store ptr [[ADD_PTR_I]], ptr [[S]], align 4, !tbaa [[TBAA7:![0-9]+]]
|
||||
; CHECK-NEXT: [[ADD_PTR_I1:%.*]] = phi ptr [ [[S_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD_PTR_I]], [[FOR_BODY]] ]
|
||||
; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
|
||||
; 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 [[ADD_PTR_I1]], i32 1
|
||||
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_05]], 1
|
||||
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], 100
|
||||
; 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}
|
||||
!7 = !{!2, !2, i64 0}
|
||||
;.
|
||||
; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META2:![0-9]+]], i64 0}
|
||||
; CHECK: [[META1]] = !{!"_ZTS1S", [[META2]], i64 0}
|
||||
; CHECK: [[META2]] = !{!"any pointer", [[META3:![0-9]+]], i64 0}
|
||||
; CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
|
||||
; CHECK: [[META4]] = !{!"Simple C++ TBAA"}
|
||||
; CHECK: [[TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0}
|
||||
; CHECK: [[META6]] = !{!"int", [[META3]], i64 0}
|
||||
; CHECK: [[TBAA7]] = !{[[META2]], [[META2]], i64 0}
|
||||
; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
|
||||
; CHECK: [[META1]] = !{!"any pointer", [[META2:![0-9]+]], i64 0}
|
||||
; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
|
||||
; CHECK: [[META3]] = !{!"Simple C++ TBAA"}
|
||||
; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
|
||||
; CHECK: [[META5]] = !{!"int", [[META2]], i64 0}
|
||||
;.
|
||||
|
@ -3255,8 +3255,8 @@ ScopBuilder::buildAliasGroupsForAccesses() {
|
||||
if (AS.isMustAlias() || AS.isForwardingAliasSet())
|
||||
continue;
|
||||
AliasGroupTy AG;
|
||||
for (auto &PR : AS)
|
||||
AG.push_back(PtrToAcc[PR.getValue()]);
|
||||
for (const Value *Ptr : AS.getPointers())
|
||||
AG.push_back(PtrToAcc[const_cast<Value *>(Ptr)]);
|
||||
if (AG.size() < 2)
|
||||
continue;
|
||||
AliasGroups.push_back(std::move(AG));
|
||||
|
@ -1149,6 +1149,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
|
||||
// sure the base pointer is not an instruction defined inside the scop.
|
||||
// However, we can ignore loads that will be hoisted.
|
||||
|
||||
auto ASPointers = AS.getPointers();
|
||||
|
||||
InvariantLoadsSetTy VariantLS, InvariantLS;
|
||||
// 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
|
||||
@ -1158,8 +1160,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
|
||||
const unsigned int VariantSize = VariantLS.size(),
|
||||
InvariantSize = InvariantLS.size();
|
||||
|
||||
for (const auto &Ptr : AS) {
|
||||
Instruction *Inst = dyn_cast<Instruction>(Ptr.getValue());
|
||||
for (const Value *Ptr : ASPointers) {
|
||||
Instruction *Inst = dyn_cast<Instruction>(const_cast<Value *>(Ptr));
|
||||
if (Inst && Context.CurRegion.contains(Inst)) {
|
||||
auto *Load = dyn_cast<LoadInst>(Inst);
|
||||
if (Load && InvariantLS.count(Load))
|
||||
|
@ -638,8 +638,7 @@ bool ReportNonSimpleMemoryAccess::classof(const RejectReason *RR) {
|
||||
|
||||
ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
|
||||
: RejectReason(RejectReasonKind::Alias), Inst(Inst) {
|
||||
for (const auto &I : AS)
|
||||
Pointers.push_back(I.getValue());
|
||||
append_range(Pointers, AS.getPointers());
|
||||
}
|
||||
|
||||
std::string ReportAlias::formatInvalidAlias(std::string Prefix,
|
||||
|
Loading…
Reference in New Issue
Block a user