205 changes: 79 additions & 126 deletions llvm/include/llvm/Transforms/IPO/Attributor.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Transforms/Utils/CallGraphUpdater.h"

#include <limits>
#include <map>
#include <optional>

Expand All @@ -152,7 +151,6 @@ class Function;

/// Abstract Attribute helper functions.
namespace AA {
using InstExclusionSetTy = SmallPtrSet<Instruction *, 4>;

/// Flags to distinguish intra-procedural queries from *potentially*
/// inter-procedural queries. Not that information can be valid for both and
Expand Down Expand Up @@ -276,13 +274,11 @@ struct RangeTy {
}

/// Constants used to represent special offsets or sizes.
/// - We cannot assume that Offsets and Size are non-negative.
/// - This assumes that Offset and Size are non-negative.
/// - The constants should not clash with DenseMapInfo, such as EmptyKey
/// (INT64_MAX) and TombstoneKey (INT64_MIN).
/// We use values "in the middle" of the 64 bit range to represent these
/// special cases.
static constexpr int64_t Unassigned = std::numeric_limits<int32_t>::min();
static constexpr int64_t Unknown = std::numeric_limits<int32_t>::max();
static constexpr int64_t Unassigned = -1;
static constexpr int64_t Unknown = -2;
};

inline raw_ostream &operator<<(raw_ostream &OS, const RangeTy &R) {
Expand Down Expand Up @@ -356,26 +352,23 @@ bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP,
bool isAssumedReadNone(Attributor &A, const IRPosition &IRP,
const AbstractAttribute &QueryingAA, bool &IsKnown);

/// Return true if \p ToI is potentially reachable from \p FromI without running
/// into any instruction in \p ExclusionSet The two instructions do not need to
/// be in the same function. \p GoBackwardsCB can be provided to convey domain
/// knowledge about the "lifespan" the user is interested in. By default, the
/// callers of \p FromI are checked as well to determine if \p ToI can be
/// reached. If the query is not interested in callers beyond a certain point,
/// e.g., a GPU kernel entry or the function containing an alloca, the
/// \p GoBackwardsCB should return false.
/// Return true if \p ToI is potentially reachable from \p FromI. The two
/// instructions do not need to be in the same function. \p GoBackwardsCB
/// can be provided to convey domain knowledge about the "lifespan" the user is
/// interested in. By default, the callers of \p FromI are checked as well to
/// determine if \p ToI can be reached. If the query is not interested in
/// callers beyond a certain point, e.g., a GPU kernel entry or the function
/// containing an alloca, the \p GoBackwardsCB should return false.
bool isPotentiallyReachable(
Attributor &A, const Instruction &FromI, const Instruction &ToI,
const AbstractAttribute &QueryingAA,
const AA::InstExclusionSetTy *ExclusionSet = nullptr,
std::function<bool(const Function &F)> GoBackwardsCB = nullptr);

/// Same as above but it is sufficient to reach any instruction in \p ToFn.
bool isPotentiallyReachable(
Attributor &A, const Instruction &FromI, const Function &ToFn,
const AbstractAttribute &QueryingAA,
const AA::InstExclusionSetTy *ExclusionSet = nullptr,
std::function<bool(const Function &F)> GoBackwardsCB = nullptr);
std::function<bool(const Function &F)> GoBackwardsCB);

} // namespace AA

Expand Down Expand Up @@ -417,39 +410,6 @@ struct DenseMapInfo<AA::ValueScope> : public DenseMapInfo<unsigned char> {
}
};

template <>
struct DenseMapInfo<const AA::InstExclusionSetTy *>
: public DenseMapInfo<void *> {
using super = DenseMapInfo<void *>;
static inline const AA::InstExclusionSetTy *getEmptyKey() {
return static_cast<const AA::InstExclusionSetTy *>(super::getEmptyKey());
}
static inline const AA::InstExclusionSetTy *getTombstoneKey() {
return static_cast<const AA::InstExclusionSetTy *>(
super::getTombstoneKey());
}
static unsigned getHashValue(const AA::InstExclusionSetTy *BES) {
unsigned H = 0;
if (BES)
for (const auto *II : *BES)
H += DenseMapInfo<const Instruction *>::getHashValue(II);
return H;
}
static bool isEqual(const AA::InstExclusionSetTy *LHS,
const AA::InstExclusionSetTy *RHS) {
if (LHS == RHS)
return true;
if (LHS == getEmptyKey() || RHS == getEmptyKey() ||
LHS == getTombstoneKey() || RHS == getTombstoneKey())
return false;
if (!LHS || !RHS)
return ((LHS && LHS->empty()) || (RHS && RHS->empty()));
if (LHS->size() != RHS->size())
return false;
return llvm::set_is_subset(*LHS, *RHS);
}
};

/// The value passed to the line option that defines the maximal initialization
/// chain length.
extern unsigned MaxInitializationChainLength;
Expand Down Expand Up @@ -1090,47 +1050,22 @@ class SubsumingPositionIterator {
iterator end() { return IRPositions.end(); }
};

/// Wrapper for FunctionAnalysisManager.
/// Wrapper for FunctoinAnalysisManager.
struct AnalysisGetter {
// The client may be running the old pass manager, in which case, we need to
// map the requested Analysis to its equivalent wrapper in the old pass
// manager. The scheme implemented here does not require every Analysis to be
// updated. Only those new analyses that the client cares about in the old
// pass manager need to expose a LegacyWrapper type, and that wrapper should
// support a getResult() method that matches the new Analysis.
//
// We need SFINAE to check for the LegacyWrapper, but function templates don't
// allow partial specialization, which is needed in this case. So instead, we
// use a constexpr bool to perform the SFINAE, and then use this information
// inside the function template.
template <typename, typename = void> static constexpr bool HasLegacyWrapper = false;

template <typename Analysis>
typename Analysis::Result *getAnalysis(const Function &F) {
if (FAM)
return &FAM->getResult<Analysis>(const_cast<Function &>(F));
if constexpr (HasLegacyWrapper<Analysis>)
if (LegacyPass)
return &LegacyPass
->getAnalysis<typename Analysis::LegacyWrapper>(
const_cast<Function &>(F))
.getResult();
return nullptr;
if (!FAM || !F.getParent())
return nullptr;
return &FAM->getResult<Analysis>(const_cast<Function &>(F));
}

AnalysisGetter(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
AnalysisGetter(Pass *P) : LegacyPass(P) {}
AnalysisGetter() = default;

private:
FunctionAnalysisManager *FAM = nullptr;
Pass *LegacyPass = nullptr;
};

template <typename Analysis>
constexpr bool AnalysisGetter::HasLegacyWrapper<
Analysis, std::void_t<typename Analysis::LegacyWrapper>> = true;

/// Data structure to hold cached (LLVM-IR) information.
///
/// All attributes are given an InformationCache object at creation time to
Expand Down Expand Up @@ -1170,10 +1105,6 @@ struct InformationCache {
// the destructor manually.
for (auto &It : FuncInfoMap)
It.getSecond()->~FunctionInfo();
// Same is true for the instruction exclusions sets.
using AA::InstExclusionSetTy;
for (auto *BES : BESets)
BES->~InstExclusionSetTy();
}

/// Apply \p CB to all uses of \p F. If \p LookThroughConstantExprUses is
Expand Down Expand Up @@ -1291,16 +1222,21 @@ struct InformationCache {
/// Return the map conaining all the knowledge we have from `llvm.assume`s.
const RetainedKnowledgeMap &getKnowledgeMap() const { return KnowledgeMap; }

/// Given \p BES, return a uniqued version. \p BES is destroyed in the
/// process.
const AA::InstExclusionSetTy *
getOrCreateUniqueBlockExecutionSet(const AA::InstExclusionSetTy *BES) {
auto It = BESets.find(BES);
if (It != BESets.end())
return *It;
auto *UniqueBES = new (Allocator) AA::InstExclusionSetTy(*BES);
BESets.insert(UniqueBES);
return UniqueBES;
/// Return if \p To is potentially reachable form \p From or not
/// If the same query was answered, return cached result
bool getPotentiallyReachable(const Instruction &From, const Instruction &To) {
auto KeyPair = std::make_pair(&From, &To);
auto Iter = PotentiallyReachableMap.find(KeyPair);
if (Iter != PotentiallyReachableMap.end())
return Iter->second;
const Function &F = *From.getFunction();
bool Result = true;
if (From.getFunction() == To.getFunction())
Result = isPotentiallyReachable(&From, &To, nullptr,
AG.getAnalysis<DominatorTreeAnalysis>(F),
AG.getAnalysis<LoopAnalysis>(F));
PotentiallyReachableMap.insert(std::make_pair(KeyPair, Result));
return Result;
}

/// Check whether \p F is part of module slice.
Expand Down Expand Up @@ -1369,15 +1305,16 @@ struct InformationCache {
/// A container for all instructions that are only used by `llvm.assume`.
SetVector<const Instruction *> AssumeOnlyValues;

/// Cache for block sets to allow reuse.
DenseSet<AA::InstExclusionSetTy *> BESets;

/// Getters for analysis.
AnalysisGetter &AG;

/// Set of inlineable functions
SmallPtrSet<const Function *, 8> InlineableFunctions;

/// A map for caching results of queries for isPotentiallyReachable
DenseMap<std::pair<const Instruction *, const Instruction *>, bool>
PotentiallyReachableMap;

/// The triple describing the target machine.
Triple TargetTriple;

Expand Down Expand Up @@ -1547,16 +1484,14 @@ struct Attributor {
// Use the static create method.
auto &AA = AAType::createForPosition(IRP, *this);

// Always register a new attribute to make sure we clean up the allocated
// memory properly.
registerAA(AA);

// If we are currenty seeding attributes, enforce seeding rules.
if (Phase == AttributorPhase::SEEDING && !shouldSeedAttribute(AA)) {
AA.getState().indicatePessimisticFixpoint();
return AA;
}

registerAA(AA);

// For now we ignore naked and optnone functions.
bool Invalidate =
Configuration.Allowed && !Configuration.Allowed->count(&AAType::ID);
Expand Down Expand Up @@ -3457,30 +3392,42 @@ struct AAUndefinedBehavior
};

/// An abstract interface to determine reachability of point A to B.
struct AAIntraFnReachability
: public StateWrapper<BooleanState, AbstractAttribute> {
struct AAReachability : public StateWrapper<BooleanState, AbstractAttribute> {
using Base = StateWrapper<BooleanState, AbstractAttribute>;
AAIntraFnReachability(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
AAReachability(const IRPosition &IRP, Attributor &A) : Base(IRP) {}

/// Returns true if 'From' instruction is assumed to reach, 'To' instruction.
/// Users should provide two positions they are interested in, and the class
/// determines (and caches) reachability.
virtual bool isAssumedReachable(
Attributor &A, const Instruction &From, const Instruction &To,
const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
bool isAssumedReachable(Attributor &A, const Instruction &From,
const Instruction &To) const {
if (!getState().isValidState())
return true;
return A.getInfoCache().getPotentiallyReachable(From, To);
}

/// Returns true if 'From' instruction is known to reach, 'To' instruction.
/// Users should provide two positions they are interested in, and the class
/// determines (and caches) reachability.
bool isKnownReachable(Attributor &A, const Instruction &From,
const Instruction &To) const {
if (!getState().isValidState())
return false;
return A.getInfoCache().getPotentiallyReachable(From, To);
}

/// Create an abstract attribute view for the position \p IRP.
static AAIntraFnReachability &createForPosition(const IRPosition &IRP,
Attributor &A);
static AAReachability &createForPosition(const IRPosition &IRP,
Attributor &A);

/// See AbstractAttribute::getName()
const std::string getName() const override { return "AAIntraFnReachability"; }
const std::string getName() const override { return "AAReachability"; }

/// See AbstractAttribute::getIdAddr()
const char *getIdAddr() const override { return &ID; }

/// This function should return true if the type of the \p AA is
/// AAIntraFnReachability
/// AAReachability
static bool classof(const AbstractAttribute *AA) {
return (AA->getIdAddr() == &ID);
}
Expand Down Expand Up @@ -5001,33 +4948,35 @@ struct AAExecutionDomain
};

/// An abstract Attribute for computing reachability between functions.
struct AAInterFnReachability
struct AAFunctionReachability
: public StateWrapper<BooleanState, AbstractAttribute> {
using Base = StateWrapper<BooleanState, AbstractAttribute>;

AAInterFnReachability(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
AAFunctionReachability(const IRPosition &IRP, Attributor &A) : Base(IRP) {}

/// See AbstractAttribute::isQueryAA.
bool isQueryAA() const override { return true; }

/// If the function represented by this possition can reach \p Fn.
bool canReach(Attributor &A, const Function &Fn) const {
Function *Scope = getAnchorScope();
if (!Scope || Scope->isDeclaration())
return true;
return instructionCanReach(A, Scope->getEntryBlock().front(), Fn);
}
virtual bool canReach(Attributor &A, const Function &Fn) const = 0;

/// Can \p CB reach \p Fn.
virtual bool canReach(Attributor &A, CallBase &CB,
const Function &Fn) const = 0;

/// Can \p Inst reach \p Fn.
/// See also AA::isPotentiallyReachable.
virtual bool instructionCanReach(
Attributor &A, const Instruction &Inst, const Function &Fn,
const AA::InstExclusionSetTy *ExclusionSet = nullptr,
SmallPtrSet<const Function *, 16> *Visited = nullptr) const = 0;
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst,
const Function &Fn) const = 0;

/// Create an abstract attribute view for the position \p IRP.
static AAInterFnReachability &createForPosition(const IRPosition &IRP,
Attributor &A);
static AAFunctionReachability &createForPosition(const IRPosition &IRP,
Attributor &A);

/// See AbstractAttribute::getName()
const std::string getName() const override { return "AAInterFnReachability"; }
const std::string getName() const override {
return "AAFunctionReachability";
}

/// See AbstractAttribute::getIdAddr()
const char *getIdAddr() const override { return &ID; }
Expand All @@ -5039,6 +4988,10 @@ struct AAInterFnReachability

/// Unique ID (due to the unique address)
static const char ID;

private:
/// Can this function reach a call with unknown calee.
virtual bool canReachUnknownCallee() const = 0;
};

/// An abstract interface for struct information.
Expand Down
17 changes: 2 additions & 15 deletions llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "AMDGPU.h"
#include "GCNSubtarget.h"
#include "Utils/AMDGPUBaseInfo.h"
#include "llvm/Analysis/CycleAnalysis.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsR600.h"
Expand All @@ -22,10 +21,6 @@

#define DEBUG_TYPE "amdgpu-attributor"

namespace llvm {
void initializeCycleInfoWrapperPassPass(PassRegistry &);
}

using namespace llvm;

#define AMDGPU_ATTRIBUTE(Name, Str) Name##_POS,
Expand Down Expand Up @@ -752,7 +747,7 @@ class AMDGPUAttributor : public ModulePass {

bool runOnModule(Module &M) override {
SetVector<Function *> Functions;
AnalysisGetter AG(this);
AnalysisGetter AG;
for (Function &F : M) {
if (!F.isIntrinsic())
Functions.insert(&F);
Expand Down Expand Up @@ -787,10 +782,6 @@ class AMDGPUAttributor : public ModulePass {
return Change == ChangeStatus::CHANGED;
}

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<CycleInfoWrapperPass>();
}

StringRef getPassName() const override { return "AMDGPU Attributor"; }
TargetMachine *TM;
static char ID;
Expand All @@ -800,8 +791,4 @@ class AMDGPUAttributor : public ModulePass {
char AMDGPUAttributor::ID = 0;

Pass *llvm::createAMDGPUAttributorPass() { return new AMDGPUAttributor(); }
INITIALIZE_PASS_BEGIN(AMDGPUAttributor, DEBUG_TYPE, "AMDGPU Attributor", false,
false)
INITIALIZE_PASS_DEPENDENCY(CycleInfoWrapperPass);
INITIALIZE_PASS_END(AMDGPUAttributor, DEBUG_TYPE, "AMDGPU Attributor", false,
false)
INITIALIZE_PASS(AMDGPUAttributor, DEBUG_TYPE, "AMDGPU Attributor", false, false)
100 changes: 25 additions & 75 deletions llvm/lib/Transforms/IPO/Attributor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,27 +570,19 @@ static bool
isPotentiallyReachable(Attributor &A, const Instruction &FromI,
const Instruction *ToI, const Function &ToFn,
const AbstractAttribute &QueryingAA,
const AA::InstExclusionSetTy *ExclusionSet,
std::function<bool(const Function &F)> GoBackwardsCB) {
LLVM_DEBUG({
dbgs() << "[AA] isPotentiallyReachable @" << ToFn.getName() << " from "
<< FromI << " [GBCB: " << bool(GoBackwardsCB) << "][#ExS: "
<< (ExclusionSet ? std::to_string(ExclusionSet->size()) : "none")
<< "]\n";
if (ExclusionSet)
for (auto *ES : *ExclusionSet)
dbgs() << *ES << "\n";
});

// If we can go arbitrarily backwards we will eventually reach an entry point
// that can reach ToI. Only if a set of blocks through which we cannot go is
// provided, or once we track internal functions not accessible from the
// outside, it makes sense to perform backwards analysis in the absence of a
// GoBackwardsCB.
if (!GoBackwardsCB && !ExclusionSet) {
LLVM_DEBUG(dbgs() << "[AA] isPotentiallyReachable @" << ToFn.getName()
<< " from " << FromI << " [GBCB: " << bool(GoBackwardsCB)
<< "]\n");

// TODO: If we can go arbitrarily backwards we will eventually reach an
// entry point that can reach ToI. Only once this takes a set of blocks
// through which we cannot go, or once we track internal functions not
// accessible from the outside, it makes sense to perform backwards analysis
// in the absence of a GoBackwardsCB.
if (!GoBackwardsCB) {
LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI
<< " is not checked backwards and does not have an "
"exclusion set, abort\n");
<< " is not checked backwards, abort\n");
return true;
}

Expand All @@ -609,68 +601,25 @@ isPotentiallyReachable(Attributor &A, const Instruction &FromI,
return true;
LLVM_DEBUG(dbgs() << "[AA] check " << *ToI << " from " << *CurFromI
<< " intraprocedurally\n");
const auto &ReachabilityAA = A.getAAFor<AAIntraFnReachability>(
const auto &ReachabilityAA = A.getAAFor<AAReachability>(
QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);
bool Result =
ReachabilityAA.isAssumedReachable(A, *CurFromI, *ToI, ExclusionSet);
bool Result = ReachabilityAA.isAssumedReachable(A, *CurFromI, *ToI);
LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " "
<< (Result ? "can potentially " : "cannot ") << "reach "
<< *ToI << " [Intra]\n");
if (Result)
return true;
}

bool Result = true;
if (!ToFn.isDeclaration() && ToI) {
const auto &ToReachabilityAA = A.getAAFor<AAIntraFnReachability>(
QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);
const Instruction &EntryI = ToFn.getEntryBlock().front();
Result =
ToReachabilityAA.isAssumedReachable(A, EntryI, *ToI, ExclusionSet);
LLVM_DEBUG(dbgs() << "[AA] Entry " << EntryI << " of @" << ToFn.getName()
<< " " << (Result ? "can potentially " : "cannot ")
<< "reach @" << *ToI << " [ToFn]\n");
}

if (Result) {
// The entry of the ToFn can reach the instruction ToI. If the current
// instruction is already known to reach the ToFn.
const auto &FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);
Result = FnReachabilityAA.instructionCanReach(A, *CurFromI, ToFn,
ExclusionSet);
LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " in @" << FromFn->getName()
<< " " << (Result ? "can potentially " : "cannot ")
<< "reach @" << ToFn.getName() << " [FromFn]\n");
if (Result)
return true;
}

// TODO: Check assumed nounwind.
const auto &ReachabilityAA = A.getAAFor<AAIntraFnReachability>(
// Check if the current instruction is already known to reach the ToFn.
const auto &FnReachabilityAA = A.getAAFor<AAFunctionReachability>(
QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);
auto ReturnInstCB = [&](Instruction &Ret) {
bool Result =
ReachabilityAA.isAssumedReachable(A, *CurFromI, Ret, ExclusionSet);
LLVM_DEBUG(dbgs() << "[AA][Ret] " << *CurFromI << " "
<< (Result ? "can potentially " : "cannot ") << "reach "
<< Ret << " [Intra]\n");
return !Result;
};

// Check if we can reach returns.
bool UsedAssumedInformation = false;
if (A.checkForAllInstructions(ReturnInstCB, FromFn, QueryingAA,
{Instruction::Ret}, UsedAssumedInformation)) {
LLVM_DEBUG(dbgs() << "[AA] No return is reachable, done\n");
return false;
}

if (!GoBackwardsCB) {
LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI
<< " is not checked backwards, abort\n");
bool Result = FnReachabilityAA.instructionCanReach(A, *CurFromI, ToFn);
LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " in @" << FromFn->getName()
<< " " << (Result ? "can potentially " : "cannot ")
<< "reach @" << ToFn.getName() << " [FromFn]\n");
if (Result)
return true;
}

// If we do not go backwards from the FromFn we are done here and so far we
// could not find a way to reach ToFn/ToI.
Expand All @@ -693,6 +642,7 @@ isPotentiallyReachable(Attributor &A, const Instruction &FromI,
return true;
};

bool UsedAssumedInformation = false;
Result = !A.checkForAllCallSites(CheckCallSite, *FromFn,
/* RequireAllCallSites */ true,
&QueryingAA, UsedAssumedInformation);
Expand All @@ -713,20 +663,20 @@ isPotentiallyReachable(Attributor &A, const Instruction &FromI,
bool AA::isPotentiallyReachable(
Attributor &A, const Instruction &FromI, const Instruction &ToI,
const AbstractAttribute &QueryingAA,
const AA::InstExclusionSetTy *ExclusionSet,
std::function<bool(const Function &F)> GoBackwardsCB) {
LLVM_DEBUG(dbgs() << "[AA] isPotentiallyReachable " << ToI << " from "
<< FromI << " [GBCB: " << bool(GoBackwardsCB) << "]\n");
const Function *ToFn = ToI.getFunction();
return ::isPotentiallyReachable(A, FromI, &ToI, *ToFn, QueryingAA,
ExclusionSet, GoBackwardsCB);
GoBackwardsCB);
}

bool AA::isPotentiallyReachable(
Attributor &A, const Instruction &FromI, const Function &ToFn,
const AbstractAttribute &QueryingAA,
const AA::InstExclusionSetTy *ExclusionSet,
std::function<bool(const Function &F)> GoBackwardsCB) {
return ::isPotentiallyReachable(A, FromI, /* ToI */ nullptr, ToFn, QueryingAA,
ExclusionSet, GoBackwardsCB);
GoBackwardsCB);
}

/// Return true if \p New is equal or worse than \p Old.
Expand Down
675 changes: 305 additions & 370 deletions llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Large diffs are not rendered by default.

30 changes: 0 additions & 30 deletions llvm/test/CodeGen/AMDGPU/implicitarg-attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -63,36 +63,6 @@ entry:
ret void
}

; CHECK-NOT: hidden_hostcall_buffer
; CHECK-NOT: hidden_multigrid_sync_arg
; CHECK-LABEL: .name: kernel_3

define amdgpu_kernel void @kernel_3(i32 addrspace(1)* %a, i1 %cond) {
entry:
%tmp7 = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr()
br i1 %cond, label %old, label %new

old: ; preds = %entry
%tmp4 = getelementptr i8, i8 addrspace(4)* %tmp7, i64 12
br label %join

new: ; preds = %entry
%tmp12 = getelementptr inbounds i8, i8 addrspace(4)* %tmp7, i64 18
br label %join

join: ; preds = %new, %old
%.in.in.in = phi i8 addrspace(4)* [ %tmp12, %new ], [ %tmp4, %old ]
%.in.in = bitcast i8 addrspace(4)* %.in.in.in to i16 addrspace(4)*

;;; THIS USE of implicitarg_ptr should not produce hostcall metadata
%.in = load i16, i16 addrspace(4)* %.in.in, align 2

%idx.ext = sext i16 %.in to i64
%add.ptr3 = getelementptr inbounds i32, i32 addrspace(1)* %a, i64 %idx.ext
%tmp16 = atomicrmw add i32 addrspace(1)* %add.ptr3, i32 15 syncscope("agent-one-as") monotonic, align 4
ret void
}

declare i32 @llvm.amdgcn.workitem.id.x()

declare align 4 i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr()
Expand Down
10 changes: 0 additions & 10 deletions llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@
; GCN-O0-NEXT: Scalarize Masked Memory Intrinsics
; GCN-O0-NEXT: Expand reduction intrinsics
; GCN-O0-NEXT: AMDGPU Attributor
; GCN-O0-NEXT: FunctionPass Manager
; GCN-O0-NEXT: Cycle Info Analysis
; GCN-O0-NEXT: CallGraph Construction
; GCN-O0-NEXT: Call Graph SCC Pass Manager
; GCN-O0-NEXT: AMDGPU Annotate Kernel Features
Expand Down Expand Up @@ -227,8 +225,6 @@
; GCN-O1-NEXT: Natural Loop Information
; GCN-O1-NEXT: TLS Variable Hoist
; GCN-O1-NEXT: AMDGPU Attributor
; GCN-O1-NEXT: FunctionPass Manager
; GCN-O1-NEXT: Cycle Info Analysis
; GCN-O1-NEXT: CallGraph Construction
; GCN-O1-NEXT: Call Graph SCC Pass Manager
; GCN-O1-NEXT: AMDGPU Annotate Kernel Features
Expand Down Expand Up @@ -513,8 +509,6 @@
; GCN-O1-OPTS-NEXT: TLS Variable Hoist
; GCN-O1-OPTS-NEXT: Early CSE
; GCN-O1-OPTS-NEXT: AMDGPU Attributor
; GCN-O1-OPTS-NEXT: FunctionPass Manager
; GCN-O1-OPTS-NEXT: Cycle Info Analysis
; GCN-O1-OPTS-NEXT: CallGraph Construction
; GCN-O1-OPTS-NEXT: Call Graph SCC Pass Manager
; GCN-O1-OPTS-NEXT: AMDGPU Annotate Kernel Features
Expand Down Expand Up @@ -813,8 +807,6 @@
; GCN-O2-NEXT: TLS Variable Hoist
; GCN-O2-NEXT: Early CSE
; GCN-O2-NEXT: AMDGPU Attributor
; GCN-O2-NEXT: FunctionPass Manager
; GCN-O2-NEXT: Cycle Info Analysis
; GCN-O2-NEXT: CallGraph Construction
; GCN-O2-NEXT: Call Graph SCC Pass Manager
; GCN-O2-NEXT: AMDGPU Annotate Kernel Features
Expand Down Expand Up @@ -1126,8 +1118,6 @@
; GCN-O3-NEXT: Optimization Remark Emitter
; GCN-O3-NEXT: Global Value Numbering
; GCN-O3-NEXT: AMDGPU Attributor
; GCN-O3-NEXT: FunctionPass Manager
; GCN-O3-NEXT: Cycle Info Analysis
; GCN-O3-NEXT: CallGraph Construction
; GCN-O3-NEXT: Call Graph SCC Pass Manager
; GCN-O3-NEXT: AMDGPU Annotate Kernel Features
Expand Down
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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 = "A7"
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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

declare void @sink(i32)
Expand Down
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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

; Don't promote paramaters of/arguments to naked functions
Expand Down
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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

; ArgumentPromotion should preserve the default function address space
Expand Down
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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 = "x86_64-pc-windows-msvc"

Expand Down
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"

Expand Down
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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

; Unused arguments from variadic functions cannot be eliminated as that changes
Expand Down
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/cgscc_bugs.ll
Original file line number Diff line number Diff line change
@@ -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=2 -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-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/Transforms/Attributor/depgraph.ll
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoRecurse] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-recurse
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAInterFnReachability] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state #queries(1)
; GRAPH-NEXT: [AAFunctionReachability] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state FunctionReachability [1,1]
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIntraFnReachability] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state #queries(1)
; GRAPH-NEXT: [AACallEdges] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state CallEdges[0,1]
; GRAPH-EMPTY:
; GRAPH-NEXT: [AACallEdges] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state CallEdges[0,1]
; GRAPH-EMPTY:
Expand Down Expand Up @@ -300,8 +300,8 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; DOT-DAG: Node[[Node26:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
; DOT-DAG: Node[[Node27:0x[a-z0-9]+]] [shape=record,label="{[AAInstanceInfo]
; DOT-DAG: Node[[Node28:0x[a-z0-9]+]] [shape=record,label="{[AANoRecurse]
; DOT-DAG: Node[[Node29:0x[a-z0-9]+]] [shape=record,label="{[AAInterFnReachability]
; DOT-DAG: Node[[Node30:0x[a-z0-9]+]] [shape=record,label="{[AAIntraFnReachability]
; DOT-DAG: Node[[Node29:0x[a-z0-9]+]] [shape=record,label="{[AAFunctionReachability]
; DOT-DAG: Node[[Node30:0x[a-z0-9]+]] [shape=record,label="{[AACallEdges]
; DOT-DAG: Node[[Node31:0x[a-z0-9]+]] [shape=record,label="{[AACallEdges]
; DOT-DAG: Node[[Node32:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
; DOT-DAG: Node[[Node33:0x[a-z0-9]+]] [shape=record,label="{[AAWillReturn]
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/liveness_chains.ll
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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

; Make sure we need a single iteration to determine the chains are dead/alive.
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/lowerheap.ll
Original file line number Diff line number Diff line change
@@ -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 -max-heap-to-stack-size=-1 -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -max-heap-to-stack-size=-1 -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=CHECK,TUNIT
; RUN: opt -max-heap-to-stack-size=-1 -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC

declare i64 @subfn(i8*) #0
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/misc.ll
Original file line number Diff line number Diff line change
@@ -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=2 -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=3 -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
;
; Mostly check we do not crash on these uses
Expand Down
169 changes: 0 additions & 169 deletions llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll
Original file line number Diff line number Diff line change
Expand Up @@ -291,172 +291,6 @@ entry:
ret i8 %i
}

; FIXME: The whole function is just "ret i8 21".

define i8 @phi_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_1
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 23
; CHECK-NEXT: store i8 21, i8* [[GEP23]], align 4
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 31
; CHECK-NEXT: store i8 21, i8* [[GEP31]], align 4
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI_PTR:%.*]] = phi i8* [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 29
; CHECK-NEXT: [[I:%.*]] = load i8, i8* [[PHI_PTR]], align 4
; CHECK-NEXT: ret i8 [[I]]
;
entry:
%Bytes = alloca [1024 x i8], align 16
br i1 %cnd1, label %then, label %else

then:
%gep23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 23
store i8 21, i8* %gep23, align 4
br label %join

else:
%gep31 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 31
store i8 21, i8* %gep31, align 4
br label %join

join:
%phi.ptr = phi i8* [%gep23, %then], [%gep31, %else]
;; This store is eliminated
%gep29 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 29
store i8 42, i8* %gep29, align 4
%i = load i8, i8* %phi.ptr, align 4
ret i8 %i
}

; FIXME: The whole function is just "ret i8 42".

define i8 @phi_gep_simplifiable_2(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_2
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 23
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 31
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI_PTR:%.*]] = phi i8* [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
; CHECK-NEXT: store i8 21, i8* [[PHI_PTR]], align 4
; CHECK-NEXT: ret i8 42
;
entry:
%Bytes = alloca [1024 x i8], align 16
%gep29 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 29
;; This store is propagated to the load.
store i8 42, i8* %gep29, align 4
br i1 %cnd1, label %then, label %else

then:
%gep23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 23
br label %join

else:
%gep31 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 31
br label %join

join:
%phi.ptr = phi i8* [%gep23, %then], [%gep31, %else]
store i8 21, i8* %phi.ptr, align 4
;; Replaced with the constant, and both store/load are eliminated.
%i = load i8, i8* %gep29, align 4
ret i8 %i
}

define i8 @phi_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_1
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 23
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 31
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI_PTR:%.*]] = phi i8* [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
; CHECK-NEXT: store i8 42, i8* [[GEP23]], align 4
; CHECK-NEXT: [[I:%.*]] = load i8, i8* [[PHI_PTR]], align 4
; CHECK-NEXT: ret i8 [[I]]
;
entry:
%Bytes = alloca [1024 x i8], align 16
%gep23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 23
br i1 %cnd1, label %then, label %else

then:
br label %join

else:
%gep31 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 31
br label %join

join:
%phi.ptr = phi i8* [%gep23, %then], [%gep31, %else]
;; This store cannot be eliminated
store i8 42, i8* %gep23, align 4
%i = load i8, i8* %phi.ptr, align 4
ret i8 %i
}

define i8 @phi_gep_not_simplifiable_2(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_2
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 23
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 31
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI_PTR:%.*]] = phi i8* [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
; CHECK-NEXT: store i8 21, i8* [[PHI_PTR]], align 4
; CHECK-NEXT: [[I:%.*]] = load i8, i8* [[GEP23]], align 4
; CHECK-NEXT: ret i8 [[I]]
;
entry:
%Bytes = alloca [1024 x i8], align 16
%gep23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 23
br i1 %cnd1, label %then, label %else

then:
br label %join

else:
%gep31 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 31
br label %join

join:
%phi.ptr = phi i8* [%gep23, %then], [%gep31, %else]
store i8 21, i8* %phi.ptr, align 4
%i = load i8, i8* %gep23, align 4
ret i8 %i
}

; FIXME: This should be simplifiable. See comment inside.

define i8 @phi_offsets_fixme(i1 %cnd1, i1 %cnd2) {
Expand Down Expand Up @@ -506,6 +340,3 @@ join:
; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(write) }
; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn }
;.
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CGSCC: {{.*}}
; TUNIT: {{.*}}
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/noalias.ll
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ define void @test17_caller(i32* noalias %p, i32 %c) {
; TUNIT-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR10]]
; TUNIT-NEXT: br label [[L3:%.*]]
; TUNIT: l2:
; TUNIT-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR10]]
; TUNIT-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR10]]
; TUNIT-NEXT: br label [[L3]]
; TUNIT: l3:
; TUNIT-NEXT: ret void
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/noundef.ll
Original file line number Diff line number Diff line change
@@ -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=1 -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=2 -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

declare void @unknown()
Expand Down

This file was deleted.

8 changes: 7 additions & 1 deletion llvm/test/Transforms/Attributor/value-simplify-assume.ll
Original file line number Diff line number Diff line change
@@ -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

@Gstatic_int1 = internal global i32 zeroinitializer, align 4
Expand Down Expand Up @@ -347,6 +347,7 @@ define i1 @assume_2_nr(i1 %arg, i1 %cond) norecurse {
; TUNIT-LABEL: define {{[^@]+}}@assume_2_nr
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
Expand All @@ -363,6 +364,7 @@ define i1 @assume_2_nr(i1 %arg, i1 %cond) norecurse {
; CGSCC-LABEL: define {{[^@]+}}@assume_2_nr
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
Expand Down Expand Up @@ -971,6 +973,7 @@ define i1 @assume_2(i1 %arg, i1 %cond) {
; TUNIT-LABEL: define {{[^@]+}}@assume_2
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
Expand All @@ -987,6 +990,7 @@ define i1 @assume_2(i1 %arg, i1 %cond) {
; CGSCC-LABEL: define {{[^@]+}}@assume_2
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
Expand Down Expand Up @@ -1299,6 +1303,7 @@ define i32 @assume_read_global_good() {
; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR6]]
; TUNIT-NEXT: [[LGS2:%.*]] = load i32, i32* @Gstatic_int1, align 4
; TUNIT-NEXT: store i32 13, i32* @Gstatic_int1, align 4
; TUNIT-NEXT: store i32 17, i32* @Gstatic_int1, align 4
; TUNIT-NEXT: [[LGS3:%.*]] = load i32, i32* @Gstatic_int1, align 4
; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]]
Expand All @@ -1311,6 +1316,7 @@ define i32 @assume_read_global_good() {
; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR7]]
; CGSCC-NEXT: [[LGS2:%.*]] = load i32, i32* @Gstatic_int1, align 4
; CGSCC-NEXT: store i32 13, i32* @Gstatic_int1, align 4
; CGSCC-NEXT: store i32 17, i32* @Gstatic_int1, align 4
; CGSCC-NEXT: [[LGS3:%.*]] = load i32, i32* @Gstatic_int1, align 4
; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]]
Expand Down
77 changes: 39 additions & 38 deletions llvm/test/Transforms/Attributor/value-simplify-gpu.ll
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
; 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=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

target triple = "amdgcn-amd-amdhsa"

%struct.ident_t = type { i32, i32, i32, i32, i8* }
@ReachableKernel = internal addrspace(3) global i32 3, align 4
@UnreachableKernel = internal addrspace(3) global i32 42, align 4
@ReachableKernelAS0 = internal global i32 7, align 4
Expand Down Expand Up @@ -111,8 +110,7 @@ define internal void @level2Kernela() {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
; TUNIT-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR5:[0-9]+]]
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR5:[0-9]+]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nosync nounwind
Expand Down Expand Up @@ -140,8 +138,7 @@ define internal void @level2Kernelb() {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
; TUNIT-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR5]]
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR5]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nosync nounwind
Expand All @@ -163,12 +160,18 @@ entry:
}

define internal void @level2Kernelall_late() {
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
; CHECK-LABEL: define {{[^@]+}}@level2Kernelall_late
; CHECK-SAME: () #[[ATTR2]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
; CHECK-NEXT: ret void
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
; TUNIT-LABEL: define {{[^@]+}}@level2Kernelall_late
; TUNIT-SAME: () #[[ATTR2]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
; CGSCC-LABEL: define {{[^@]+}}@level2Kernelall_late
; CGSCC-SAME: () #[[ATTR2]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
; CGSCC-NEXT: ret void
;
entry:
store i32 1, i32 *addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
Expand Down Expand Up @@ -208,12 +211,10 @@ define internal void @level1(i32 %C) {
; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
; TUNIT-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; TUNIT: if.then:
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* [[LOCAL]], align 4
; TUNIT-NEXT: call void @level2a(i32 [[TMP0]]) #[[ATTR3]]
; TUNIT-NEXT: call void @level2a() #[[ATTR3]]
; TUNIT-NEXT: br label [[IF_END:%.*]]
; TUNIT: if.else:
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* [[LOCAL]], align 4
; TUNIT-NEXT: call void @level2b(i32 [[TMP1]]) #[[ATTR3]]
; TUNIT-NEXT: call void @level2b() #[[ATTR3]]
; TUNIT-NEXT: br label [[IF_END]]
; TUNIT: if.end:
; TUNIT-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR3]]
Expand Down Expand Up @@ -262,7 +263,6 @@ define internal void @level2all_early(i32* %addr) {
; TUNIT-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; TUNIT-NEXT: store i32 17, i32* [[ADDR]], align 4
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
Expand All @@ -282,14 +282,11 @@ entry:
define internal void @level2a(i32* %addr) {
; TUNIT: Function Attrs: norecurse nosync nounwind
; TUNIT-LABEL: define {{[^@]+}}@level2a
; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
; TUNIT-SAME: () #[[ATTR1]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[ADDR_PRIV:%.*]] = alloca i32, align 4
; TUNIT-NEXT: store i32 [[TMP0]], i32* [[ADDR_PRIV]], align 4
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; TUNIT-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; TUNIT-NEXT: [[QQQQ2:%.*]] = load i32, i32* [[ADDR_PRIV]], align 4
; TUNIT-NEXT: call void @use(i32 noundef [[TMP1]], i32 noundef [[TMP2]], i32 [[QQQQ2]]) #[[ATTR5]]
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR5]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nosync nounwind
Expand All @@ -313,14 +310,11 @@ entry:
define internal void @level2b(i32* %addr) {
; TUNIT: Function Attrs: norecurse nosync nounwind
; TUNIT-LABEL: define {{[^@]+}}@level2b
; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
; TUNIT-SAME: () #[[ATTR1]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[ADDR_PRIV:%.*]] = alloca i32, align 4
; TUNIT-NEXT: store i32 [[TMP0]], i32* [[ADDR_PRIV]], align 4
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; TUNIT-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; TUNIT-NEXT: [[TMP3:%.*]] = load i32, i32* [[ADDR_PRIV]], align 4
; TUNIT-NEXT: call void @use(i32 noundef [[TMP1]], i32 noundef [[TMP2]], i32 [[TMP3]]) #[[ATTR5]]
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR5]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nosync nounwind
Expand All @@ -342,13 +336,20 @@ entry:
}

define internal void @level2all_late(i32* %addr) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
; CHECK-LABEL: define {{[^@]+}}@level2all_late
; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; CHECK-NEXT: store i32 5, i32* [[ADDR]], align 4
; CHECK-NEXT: ret void
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
; TUNIT-LABEL: define {{[^@]+}}@level2all_late
; TUNIT-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
; CGSCC-LABEL: define {{[^@]+}}@level2all_late
; CGSCC-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; CGSCC-NEXT: store i32 5, i32* [[ADDR]], align 4
; CGSCC-NEXT: ret void
;
entry:
store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,9 +542,13 @@ define i32 @local_alloca_simplifiable_3() {
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3
; CHECK-SAME: () #[[ATTR4:[0-9]+]] {
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32 1, i32* [[A]], align 4
; CHECK-NEXT: br label [[SPLIT:%.*]]
; CHECK: split:
; CHECK-NEXT: ret i32 2
; CHECK-NEXT: store i32 2, i32* [[A]], align 4
; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[A]], align 4
; CHECK-NEXT: ret i32 [[L]]
;
%A = alloca i32, align 4
store i32 1, i32* %A
Expand Down
818 changes: 0 additions & 818 deletions llvm/test/Transforms/Attributor/value-simplify-reachability.ll

This file was deleted.

115 changes: 0 additions & 115 deletions llvm/test/Transforms/OpenMP/value-simplify-openmp-opt.ll

This file was deleted.

24 changes: 12 additions & 12 deletions llvm/unittests/Transforms/IPO/AttributorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,23 +169,23 @@ TEST_F(AttributorTestBase, AAReachabilityTest) {
// call void @func8
Instruction &F9SecondInst = *++(F9.getEntryBlock().begin());

const AAInterFnReachability &F1AA =
A.getOrCreateAAFor<AAInterFnReachability>(IRPosition::function(F1));
const AAFunctionReachability &F1AA =
A.getOrCreateAAFor<AAFunctionReachability>(IRPosition::function(F1));

const AAInterFnReachability &F6AA =
A.getOrCreateAAFor<AAInterFnReachability>(IRPosition::function(F6));
const AAFunctionReachability &F6AA =
A.getOrCreateAAFor<AAFunctionReachability>(IRPosition::function(F6));

const AAInterFnReachability &F7AA =
A.getOrCreateAAFor<AAInterFnReachability>(IRPosition::function(F7));
const AAFunctionReachability &F7AA =
A.getOrCreateAAFor<AAFunctionReachability>(IRPosition::function(F7));

const AAInterFnReachability &F9AA =
A.getOrCreateAAFor<AAInterFnReachability>(IRPosition::function(F9));
const AAFunctionReachability &F9AA =
A.getOrCreateAAFor<AAFunctionReachability>(IRPosition::function(F9));

F1AA.canReach(A, F3);
F1AA.canReach(A, F4);
F6AA.canReach(A, F4);
F7AA.instructionCanReach(A, F7FirstCB, F3);
F7AA.instructionCanReach(A, F7FirstCB, F4);
F7AA.canReach(A, F7FirstCB, F3);
F7AA.canReach(A, F7FirstCB, F4);
F9AA.instructionCanReach(A, F9FirstInst, F3);
F9AA.instructionCanReach(A, F9FirstInst, F4);

Expand All @@ -194,8 +194,8 @@ TEST_F(AttributorTestBase, AAReachabilityTest) {
ASSERT_TRUE(F1AA.canReach(A, F3));
ASSERT_FALSE(F1AA.canReach(A, F4));

ASSERT_TRUE(F7AA.instructionCanReach(A, F7FirstCB, F3));
ASSERT_TRUE(F7AA.instructionCanReach(A, F7FirstCB, F4));
ASSERT_TRUE(F7AA.canReach(A, F7FirstCB, F3));
ASSERT_FALSE(F7AA.canReach(A, F7FirstCB, F4));

// Assumed to be reacahable, since F6 can reach a function with
// a unknown callee.
Expand Down