[llvm] acd22b2 - [AAUnderlyingObjects] Introduce an AA for getting underlying objects of a pointer
Shilei Tian via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 8 13:45:55 PST 2023
Author: Shilei Tian
Date: 2023-01-08T16:45:50-05:00
New Revision: acd22b275131a965f4a6006dfa0b237ed6b6572e
URL: https://github.com/llvm/llvm-project/commit/acd22b275131a965f4a6006dfa0b237ed6b6572e
DIFF: https://github.com/llvm/llvm-project/commit/acd22b275131a965f4a6006dfa0b237ed6b6572e.diff
LOG: [AAUnderlyingObjects] Introduce an AA for getting underlying objects of a pointer
This patch introduces a new AA `AAUnderlyingObjects`. It is basically like a wrapper
AA of the function `AA::getAssumedUnderlyingObjects`, but it can recursively do
query if the underlying object is an indirect access, such as a phi node or a select
instruction.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D141164
Added:
Modified:
llvm/include/llvm/Transforms/IPO/Attributor.h
llvm/lib/Transforms/IPO/Attributor.cpp
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll
llvm/test/Transforms/Attributor/depgraph.ll
llvm/test/Transforms/Attributor/value-simplify-gpu.ll
llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 1d813cb8b3385..aec4fc846ce79 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -301,19 +301,6 @@ Constant *getInitialValueForObj(Value &Obj, Type &Ty,
const DataLayout &DL,
RangeTy *RangePtr = nullptr);
-/// Collect all potential underlying objects of \p Ptr at position \p CtxI in
-/// \p Objects. Assumed information is used and dependences onto \p QueryingAA
-/// are added appropriately.
-///
-/// \returns True if \p Objects contains all assumed underlying objects, and
-/// false if something went wrong and the objects could not be
-/// determined.
-bool getAssumedUnderlyingObjects(
- Attributor &A, const Value &Ptr, SmallSetVector<Value *, 8> &Objects,
- const AbstractAttribute &QueryingAA, const Instruction *CtxI,
- bool &UsedAssumedInformation, AA::ValueScope VS = AA::Interprocedural,
- SmallPtrSetImpl<Value *> *SeenObjects = nullptr);
-
/// Collect all potential values \p LI could read into \p PotentialValues. That
/// is, the only values read by \p LI are assumed to be known and all are in
/// \p PotentialValues. \p PotentialValueOrigins will contain all the
@@ -5445,6 +5432,38 @@ struct AAAssumptionInfo
static const char ID;
};
+/// An abstract attribute for getting all assumption underlying objects.
+struct AAUnderlyingObjects : AbstractAttribute {
+ AAUnderlyingObjects(const IRPosition &IRP) : AbstractAttribute(IRP) {}
+
+ /// Create an abstract attribute biew for the position \p IRP.
+ static AAUnderlyingObjects &createForPosition(const IRPosition &IRP,
+ Attributor &A);
+
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAUnderlyingObjects"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAUnderlyingObjects.
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
+ /// Unique ID (due to the unique address)
+ static const char ID;
+
+ /// Check \p Pred on all underlying objects in \p Scope collected so far.
+ ///
+ /// This method will evaluate \p Pred on all underlying objects in \p Scope
+ /// collected so far and return true if \p Pred holds on all of them.
+ virtual bool
+ forallUnderlyingObjects(function_ref<bool(Value &)> Pred,
+ AA::ValueScope Scope = AA::Interprocedural) const = 0;
+};
+
raw_ostream &operator<<(raw_ostream &, const AAPointerInfo::Access &);
/// Run options, used by the pass manager.
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index b017961d170df..70de4d50b477e 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -340,14 +340,6 @@ static bool getPotentialCopiesOfMemoryValue(
<< " (only exact: " << OnlyExact << ")\n";);
Value &Ptr = *I.getPointerOperand();
- SmallSetVector<Value *, 8> Objects;
- if (!AA::getAssumedUnderlyingObjects(A, Ptr, Objects, QueryingAA, &I,
- UsedAssumedInformation)) {
- LLVM_DEBUG(
- dbgs() << "Underlying objects stored into could not be determined\n";);
- return false;
- }
-
// Containers to remember the pointer infos and new copies while we are not
// sure that we can find all of them. If we abort we want to avoid spurious
// dependences and potential copies in the provided container.
@@ -357,36 +349,36 @@ static bool getPotentialCopiesOfMemoryValue(
const auto *TLI =
A.getInfoCache().getTargetLibraryInfoForFunction(*I.getFunction());
- LLVM_DEBUG(dbgs() << "Visit " << Objects.size() << " objects:\n");
- for (Value *Obj : Objects) {
- LLVM_DEBUG(dbgs() << "Visit underlying object " << *Obj << "\n");
- if (isa<UndefValue>(Obj))
- continue;
- if (isa<ConstantPointerNull>(Obj)) {
+
+ auto Pred = [&](Value &Obj) {
+ LLVM_DEBUG(dbgs() << "Visit underlying object " << Obj << "\n");
+ if (isa<UndefValue>(&Obj))
+ return true;
+ if (isa<ConstantPointerNull>(&Obj)) {
// A null pointer access can be undefined but any offset from null may
// be OK. We do not try to optimize the latter.
if (!NullPointerIsDefined(I.getFunction(),
Ptr.getType()->getPointerAddressSpace()) &&
A.getAssumedSimplified(Ptr, QueryingAA, UsedAssumedInformation,
- AA::Interprocedural) == Obj)
- continue;
+ AA::Interprocedural) == &Obj)
+ return true;
LLVM_DEBUG(
dbgs() << "Underlying object is a valid nullptr, giving up.\n";);
return false;
}
// TODO: Use assumed noalias return.
- if (!isa<AllocaInst>(Obj) && !isa<GlobalVariable>(Obj) &&
- !(IsLoad ? isAllocationFn(Obj, TLI) : isNoAliasCall(Obj))) {
- LLVM_DEBUG(dbgs() << "Underlying object is not supported yet: " << *Obj
+ if (!isa<AllocaInst>(&Obj) && !isa<GlobalVariable>(&Obj) &&
+ !(IsLoad ? isAllocationFn(&Obj, TLI) : isNoAliasCall(&Obj))) {
+ LLVM_DEBUG(dbgs() << "Underlying object is not supported yet: " << Obj
<< "\n";);
return false;
}
- if (auto *GV = dyn_cast<GlobalVariable>(Obj))
+ if (auto *GV = dyn_cast<GlobalVariable>(&Obj))
if (!GV->hasLocalLinkage() &&
!(GV->isConstant() && GV->hasInitializer())) {
LLVM_DEBUG(dbgs() << "Underlying object is global with external "
"linkage, not supported yet: "
- << *Obj << "\n";);
+ << Obj << "\n";);
return false;
}
@@ -457,21 +449,21 @@ static bool getPotentialCopiesOfMemoryValue(
bool HasBeenWrittenTo = false;
AA::RangeTy Range;
- auto &PI = A.getAAFor<AAPointerInfo>(QueryingAA, IRPosition::value(*Obj),
+ auto &PI = A.getAAFor<AAPointerInfo>(QueryingAA, IRPosition::value(Obj),
DepClassTy::NONE);
if (!PI.forallInterferingAccesses(A, QueryingAA, I, CheckAccess,
HasBeenWrittenTo, Range)) {
LLVM_DEBUG(
dbgs()
<< "Failed to verify all interfering accesses for underlying object: "
- << *Obj << "\n");
+ << Obj << "\n");
return false;
}
if (IsLoad && !HasBeenWrittenTo && !Range.isUnassigned()) {
const DataLayout &DL = A.getDataLayout();
Value *InitialValue =
- AA::getInitialValueForObj(*Obj, *I.getType(), TLI, DL, &Range);
+ AA::getInitialValueForObj(Obj, *I.getType(), TLI, DL, &Range);
if (!InitialValue) {
LLVM_DEBUG(dbgs() << "Could not determine required initial value of "
"underlying object, abort!\n");
@@ -489,6 +481,16 @@ static bool getPotentialCopiesOfMemoryValue(
}
PIs.push_back(&PI);
+
+ return true;
+ };
+
+ const auto &AAUO = A.getAAFor<AAUnderlyingObjects>(
+ QueryingAA, IRPosition::value(Ptr), DepClassTy::OPTIONAL);
+ if (!AAUO.forallUnderlyingObjects(Pred)) {
+ LLVM_DEBUG(
+ dbgs() << "Underlying objects stored into could not be determined\n";);
+ return false;
}
// Only if we were successful collection all potential copies we record
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 0af298bb58a3c..9c67a0015f86d 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -185,6 +185,7 @@ PIPE_OPERATOR(AACallEdges)
PIPE_OPERATOR(AAFunctionReachability)
PIPE_OPERATOR(AAPointerInfo)
PIPE_OPERATOR(AAAssumptionInfo)
+PIPE_OPERATOR(AAUnderlyingObjects)
#undef PIPE_OPERATOR
@@ -311,38 +312,6 @@ static Value *constructPointer(Type *ResTy, Type *PtrElemTy, Value *Ptr,
return Ptr;
}
-bool AA::getAssumedUnderlyingObjects(Attributor &A, const Value &Ptr,
- SmallSetVector<Value *, 8> &Objects,
- const AbstractAttribute &QueryingAA,
- const Instruction *CtxI,
- bool &UsedAssumedInformation,
- AA::ValueScope S,
- SmallPtrSetImpl<Value *> *SeenObjects) {
- SmallPtrSet<Value *, 8> LocalSeenObjects;
- if (!SeenObjects)
- SeenObjects = &LocalSeenObjects;
-
- SmallVector<AA::ValueAndContext> Values;
- if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), &QueryingAA, Values,
- S, UsedAssumedInformation)) {
- Objects.insert(const_cast<Value *>(&Ptr));
- return true;
- }
-
- for (auto &VAC : Values) {
- Value *UO = getUnderlyingObject(VAC.getValue());
- if (UO && UO != VAC.getValue() && SeenObjects->insert(UO).second) {
- if (!getAssumedUnderlyingObjects(A, *UO, Objects, QueryingAA,
- VAC.getCtxI(), UsedAssumedInformation, S,
- SeenObjects))
- return false;
- continue;
- }
- Objects.insert(VAC.getValue());
- }
- return true;
-}
-
static const Value *
stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA,
const Value *Val, const DataLayout &DL, APInt &Offset,
@@ -8193,24 +8162,12 @@ void AAMemoryLocationImpl::categorizePtrValue(
<< Ptr << " ["
<< getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
- SmallSetVector<Value *, 8> Objects;
- bool UsedAssumedInformation = false;
- if (!AA::getAssumedUnderlyingObjects(A, Ptr, Objects, *this, &I,
- UsedAssumedInformation,
- AA::Intraprocedural)) {
- LLVM_DEBUG(
- dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
- updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
- getAccessKindFromInst(&I));
- return;
- }
-
- for (Value *Obj : Objects) {
+ auto Pred = [&](Value &Obj) {
// TODO: recognize the TBAA used for constant accesses.
MemoryLocationsKind MLK = NO_LOCATIONS;
- if (isa<UndefValue>(Obj))
- continue;
- if (isa<Argument>(Obj)) {
+ if (isa<UndefValue>(&Obj))
+ return true;
+ if (isa<Argument>(&Obj)) {
// TODO: For now we do not treat byval arguments as local copies performed
// on the call edge, though, we should. To make that happen we need to
// teach various passes, e.g., DSE, about the copy effect of a byval. That
@@ -8218,25 +8175,25 @@ void AAMemoryLocationImpl::categorizePtrValue(
// readnone again, arguably their accesses have no effect outside of the
// function, like accesses to allocas.
MLK = NO_ARGUMENT_MEM;
- } else if (auto *GV = dyn_cast<GlobalValue>(Obj)) {
+ } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
// Reading constant memory is not treated as a read "effect" by the
// function attr pass so we won't neither. Constants defined by TBAA are
// similar. (We know we do not write it because it is constant.)
if (auto *GVar = dyn_cast<GlobalVariable>(GV))
if (GVar->isConstant())
- continue;
+ return true;
if (GV->hasLocalLinkage())
MLK = NO_GLOBAL_INTERNAL_MEM;
else
MLK = NO_GLOBAL_EXTERNAL_MEM;
- } else if (isa<ConstantPointerNull>(Obj) &&
+ } else if (isa<ConstantPointerNull>(&Obj) &&
!NullPointerIsDefined(getAssociatedFunction(),
Ptr.getType()->getPointerAddressSpace())) {
- continue;
- } else if (isa<AllocaInst>(Obj)) {
+ return true;
+ } else if (isa<AllocaInst>(&Obj)) {
MLK = NO_LOCAL_MEM;
- } else if (const auto *CB = dyn_cast<CallBase>(Obj)) {
+ } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
const auto &NoAliasAA = A.getAAFor<AANoAlias>(
*this, IRPosition::callsite_returned(*CB), DepClassTy::OPTIONAL);
if (NoAliasAA.isAssumedNoAlias())
@@ -8249,10 +8206,21 @@ void AAMemoryLocationImpl::categorizePtrValue(
assert(MLK != NO_LOCATIONS && "No location specified!");
LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
- << *Obj << " -> " << getMemoryLocationsAsStr(MLK)
- << "\n");
- updateStateAndAccessesMap(getState(), MLK, &I, Obj, Changed,
+ << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
+ updateStateAndAccessesMap(getState(), MLK, &I, &Obj, Changed,
getAccessKindFromInst(&I));
+
+ return true;
+ };
+
+ const auto &AA = A.getAAFor<AAUnderlyingObjects>(
+ *this, IRPosition::value(Ptr), DepClassTy::OPTIONAL);
+ if (!AA.forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
+ LLVM_DEBUG(
+ dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
+ updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
+ getAccessKindFromInst(&I));
+ return;
}
LLVM_DEBUG(
@@ -11231,6 +11199,159 @@ AACallGraphNode *AACallEdgeIterator::operator*() const {
void AttributorCallGraph::print() { llvm::WriteGraph(outs(), this); }
+/// ------------------------ UnderlyingObjects ---------------------------------
+
+namespace {
+struct AAUnderlyingObjectsImpl
+ : StateWrapper<BooleanState, AAUnderlyingObjects> {
+ using BaseTy = StateWrapper<BooleanState, AAUnderlyingObjects>;
+ AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
+
+ /// See AbstractAttribute::getAsStr().
+ const std::string getAsStr() const override {
+ return std::string("UnderlyingObjects ") +
+ (isValidState()
+ ? (std::string("inter #") +
+ std::to_string(InterAssumedUnderlyingObjects.size()) +
+ " objs" + std::string(", intra #") +
+ std::to_string(IntraAssumedUnderlyingObjects.size()) +
+ " objs")
+ : "<invalid>");
+ }
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override {}
+
+ /// See AbstractAttribute::updateImpl(...).
+ ChangeStatus updateImpl(Attributor &A) override {
+ auto &Ptr = getAssociatedValue();
+
+ auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
+ AA::ValueScope Scope) {
+ bool UsedAssumedInformation;
+ SmallPtrSet<Value *, 8> SeenObjects;
+ SmallVector<AA::ValueAndContext> Values;
+
+ if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
+ Scope, UsedAssumedInformation))
+ return UnderlyingObjects.insert(&Ptr);
+
+ bool Changed = false;
+
+ for (unsigned I = 0; I < Values.size(); ++I) {
+ auto &VAC = Values[I];
+ auto *Obj = VAC.getValue();
+ Value *UO = getUnderlyingObject(Obj);
+ if (UO && UO != VAC.getValue() && SeenObjects.insert(UO).second) {
+ const auto &OtherAA = A.getAAFor<AAUnderlyingObjects>(
+ *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
+ auto Pred = [&Values](Value &V) {
+ Values.emplace_back(V, nullptr);
+ return true;
+ };
+
+ if (!OtherAA.forallUnderlyingObjects(Pred, Scope))
+ llvm_unreachable(
+ "The forall call should not return false at this position");
+
+ continue;
+ }
+
+ if (isa<SelectInst>(Obj) || isa<PHINode>(Obj)) {
+ Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope);
+ continue;
+ }
+
+ Changed |= UnderlyingObjects.insert(Obj);
+ }
+
+ return Changed;
+ };
+
+ bool Changed = false;
+ Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
+ Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
+
+ return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
+ }
+
+ bool forallUnderlyingObjects(
+ function_ref<bool(Value &)> Pred,
+ AA::ValueScope Scope = AA::Interprocedural) const override {
+ if (!isValidState())
+ return Pred(getAssociatedValue());
+
+ auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
+ ? IntraAssumedUnderlyingObjects
+ : InterAssumedUnderlyingObjects;
+ for (Value *Obj : AssumedUnderlyingObjects)
+ if (!Pred(*Obj))
+ return false;
+
+ return true;
+ }
+
+private:
+ /// Handle the case where the value is not the actual underlying value, such
+ /// as a phi node or a select instruction.
+ bool handleIndirect(Attributor &A, Value &V,
+ SmallSetVector<Value *, 8> &UnderlyingObjects,
+ AA::ValueScope Scope) {
+ bool Changed = false;
+ const auto &AA = A.getAAFor<AAUnderlyingObjects>(
+ *this, IRPosition::value(V), DepClassTy::OPTIONAL);
+ auto Pred = [&](Value &V) {
+ Changed |= UnderlyingObjects.insert(&V);
+ return true;
+ };
+ if (!AA.forallUnderlyingObjects(Pred, Scope))
+ llvm_unreachable(
+ "The forall call should not return false at this position");
+ return Changed;
+ }
+
+ /// All the underlying objects collected so far via intra procedural scope.
+ SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
+ /// All the underlying objects collected so far via inter procedural scope.
+ SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
+};
+
+struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
+ AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
+ : AAUnderlyingObjectsImpl(IRP, A) {}
+};
+
+struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
+ AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
+ : AAUnderlyingObjectsImpl(IRP, A) {}
+};
+
+struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
+ AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
+ : AAUnderlyingObjectsImpl(IRP, A) {}
+};
+
+struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
+ AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
+ : AAUnderlyingObjectsImpl(IRP, A) {}
+};
+
+struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
+ AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
+ : AAUnderlyingObjectsImpl(IRP, A) {}
+};
+
+struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
+ AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
+ : AAUnderlyingObjectsImpl(IRP, A) {}
+};
+
+struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
+ AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
+ : AAUnderlyingObjectsImpl(IRP, A) {}
+};
+}
+
const char AAReturnedValues::ID = 0;
const char AANoUnwind::ID = 0;
const char AANoSync::ID = 0;
@@ -11260,6 +11381,7 @@ const char AACallEdges::ID = 0;
const char AAFunctionReachability::ID = 0;
const char AAPointerInfo::ID = 0;
const char AAAssumptionInfo::ID = 0;
+const char AAUnderlyingObjects::ID = 0;
// Macro magic to create the static generator function for attributes that
// follow the naming scheme.
@@ -11380,6 +11502,7 @@ CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPointerInfo)
CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
+CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUnderlyingObjects)
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
index 316060e5997b0..55c3f6b36de1c 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
@G1 = constant i32 0
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
index 89f418ff8eff1..2566fef63b0a4 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
%S = type { ptr }
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
index d623d81ae5630..1dc375dc82c6b 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=12 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll
index 8e2a3472cb381..91fcc135f21ba 100644
--- a/llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=TUNIT
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CGSCC
;
diff --git a/llvm/test/Transforms/Attributor/depgraph.ll b/llvm/test/Transforms/Attributor/depgraph.ll
index 12254def5abdc..fce4e246f580f 100644
--- a/llvm/test/Transforms/Attributor/depgraph.ll
+++ b/llvm/test/Transforms/Attributor/depgraph.ll
@@ -57,6 +57,8 @@ define ptr @checkAndAdvance(ptr align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAPotentialValues] for CtxI ' %2 = load i32, ptr %0, align 4' at position {flt: [@-1]} with state set-state(< { %2 = load i32, ptr %0, align 4[3], } >)
; GRAPH-EMPTY:
+; GRAPH-NEXT: [AAUnderlyingObjects] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state UnderlyingObjects inter #1 objs, intra #1 objs
+; GRAPH-EMPTY:
; GRAPH-NEXT: [AAPotentialValues] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state set-state(< {ptr %0[3], } >)
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAPotentialValues] for CtxI <<null inst>> at position {flt: [@-1]} with state set-state(< {i32 0[3], } >)
@@ -264,6 +266,8 @@ define ptr @checkAndAdvance(ptr align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoFree] for CtxI ' %6 = call ptr @checkAndAdvance(ptr %5)' at position {cs_arg: [@0]} with state nofree
; GRAPH-EMPTY:
+; GRAPH-NEXT: [AAUnderlyingObjects] for CtxI ' %5 = getelementptr inbounds i32, ptr %0, i64 4' at position {flt: [@-1]} with state UnderlyingObjects inter #1 objs, intra #1 objs
+; GRAPH-EMPTY:
; GRAPH-NEXT: [AADereferenceable] for CtxI ' %5 = getelementptr inbounds i32, ptr %0, i64 4' at position {flt: [@-1]} with state unknown-dereferenceable
; GRAPH-NOT: update
diff --git a/llvm/test/Transforms/Attributor/value-simplify-gpu.ll b/llvm/test/Transforms/Attributor/value-simplify-gpu.ll
index 0dbc6d3b9d85d..02700f2ebe7d8 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-gpu.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-gpu.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
target triple = "amdgcn-amd-amdhsa"
diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
index 76ebcc53a49b2..ace8a206427c7 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
@@ -2097,45 +2097,25 @@ define i32 @single_read_of_static_global() {
}
define i8 @phi_store() {
-; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn
-; TUNIT-LABEL: define {{[^@]+}}@phi_store
-; TUNIT-SAME: () #[[ATTR3]] {
-; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[A:%.*]] = alloca i16, align 2
-; TUNIT-NEXT: [[B:%.*]] = bitcast i16* [[A]] to i8*
-; TUNIT-NEXT: br label [[LOOP:%.*]]
-; TUNIT: loop:
-; TUNIT-NEXT: [[P:%.*]] = phi i8* [ [[B]], [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
-; TUNIT-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
-; TUNIT-NEXT: store i8 1, i8* [[P]], align 1
-; TUNIT-NEXT: [[G]] = getelementptr i8, i8* [[P]], i64 1
-; TUNIT-NEXT: [[O]] = add nsw i8 [[I]], 1
-; TUNIT-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 2
-; TUNIT-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
-; TUNIT: end:
-; TUNIT-NEXT: [[S:%.*]] = getelementptr i8, i8* [[B]], i64 1
-; TUNIT-NEXT: [[L:%.*]] = load i8, i8* [[S]], align 1
-; TUNIT-NEXT: ret i8 [[L]]
-;
-; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn
-; CGSCC-LABEL: define {{[^@]+}}@phi_store
-; CGSCC-SAME: () #[[ATTR5]] {
-; CGSCC-NEXT: entry:
-; CGSCC-NEXT: [[A:%.*]] = alloca i16, align 2
-; CGSCC-NEXT: [[B:%.*]] = bitcast i16* [[A]] to i8*
-; CGSCC-NEXT: br label [[LOOP:%.*]]
-; CGSCC: loop:
-; CGSCC-NEXT: [[P:%.*]] = phi i8* [ [[B]], [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
-; CGSCC-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
-; CGSCC-NEXT: store i8 1, i8* [[P]], align 1
-; CGSCC-NEXT: [[G]] = getelementptr i8, i8* [[P]], i64 1
-; CGSCC-NEXT: [[O]] = add nsw i8 [[I]], 1
-; CGSCC-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 2
-; CGSCC-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
-; CGSCC: end:
-; CGSCC-NEXT: [[S:%.*]] = getelementptr i8, i8* [[B]], i64 1
-; CGSCC-NEXT: [[L:%.*]] = load i8, i8* [[S]], align 1
-; CGSCC-NEXT: ret i8 [[L]]
+; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
+; CHECK-LABEL: define {{[^@]+}}@phi_store
+; CHECK-SAME: () #[[ATTR4]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[A:%.*]] = alloca i16, align 2
+; CHECK-NEXT: [[B:%.*]] = bitcast i16* [[A]] to i8*
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[B]], [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
+; CHECK-NEXT: store i8 1, i8* [[P]], align 1
+; CHECK-NEXT: [[G]] = getelementptr i8, i8* [[P]], i64 1
+; CHECK-NEXT: [[O]] = add nsw i8 [[I]], 1
+; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 2
+; CHECK-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
+; CHECK: end:
+; CHECK-NEXT: [[S:%.*]] = getelementptr i8, i8* [[B]], i64 1
+; CHECK-NEXT: [[L:%.*]] = load i8, i8* [[S]], align 1
+; CHECK-NEXT: ret i8 [[L]]
;
entry:
%a = alloca i16
More information about the llvm-commits
mailing list