198 changes: 131 additions & 67 deletions llvm/lib/Transforms/IPO/Attributor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ static bool getPotentialCopiesOfMemoryValue(
<< " (only exact: " << OnlyExact << ")\n";);

Value &Ptr = *I.getPointerOperand();
SmallVector<Value *, 8> Objects;
SmallSetVector<Value *, 8> Objects;
if (!AA::getAssumedUnderlyingObjects(A, Ptr, Objects, QueryingAA, &I,
UsedAssumedInformation)) {
LLVM_DEBUG(
Expand All @@ -352,8 +352,8 @@ static bool getPotentialCopiesOfMemoryValue(
// be OK. We do not try to optimize the latter.
if (!NullPointerIsDefined(I.getFunction(),
Ptr.getType()->getPointerAddressSpace()) &&
A.getAssumedSimplified(Ptr, QueryingAA, UsedAssumedInformation) ==
Obj)
A.getAssumedSimplified(Ptr, QueryingAA, UsedAssumedInformation,
AA::Interprocedural) == Obj)
continue;
LLVM_DEBUG(
dbgs() << "Underlying object is a valid nullptr, giving up.\n";);
Expand All @@ -375,10 +375,24 @@ static bool getPotentialCopiesOfMemoryValue(
return false;
}

bool NullOnly = true;
bool NullRequired = false;
auto CheckForNullOnlyAndUndef = [&](Optional<Value *> V) {
if (!V || *V == nullptr)
NullOnly = false;
else if (isa<UndefValue>(*V))
/* No op */;
else if (isa<Constant>(*V) && cast<Constant>(*V)->isNullValue())
NullRequired = true;
else
NullOnly = false;
};

if (IsLoad) {
Value *InitialValue = AA::getInitialValueForObj(*Obj, *I.getType(), TLI);
if (!InitialValue)
return false;
CheckForNullOnlyAndUndef(InitialValue);
NewCopies.push_back(InitialValue);
NewCopyOrigins.push_back(nullptr);
}
Expand All @@ -388,12 +402,19 @@ static bool getPotentialCopiesOfMemoryValue(
return true;
if (IsLoad && Acc.isWrittenValueYetUndetermined())
return true;
if (OnlyExact && !IsExact &&
CheckForNullOnlyAndUndef(Acc.getContent());
if (OnlyExact && !IsExact && !NullOnly &&
!isa_and_nonnull<UndefValue>(Acc.getWrittenValue())) {
LLVM_DEBUG(dbgs() << "Non exact access " << *Acc.getRemoteInst()
<< ", abort!\n");
return false;
}
if (NullRequired && !NullOnly) {
LLVM_DEBUG(dbgs() << "Required all `null` accesses due to non exact "
"one, however found non-null one: "
<< *Acc.getRemoteInst() << ", abort!\n");
return false;
}
if (IsLoad) {
assert(isa<LoadInst>(I) && "Expected load or store instruction only!");
if (!Acc.isWrittenValueUnknown()) {
Expand Down Expand Up @@ -1038,60 +1059,74 @@ Attributor::getAssumedConstant(const IRPosition &IRP,
}
if (auto *C = dyn_cast<Constant>(&IRP.getAssociatedValue()))
return C;
const auto &ValueSimplifyAA =
getAAFor<AAValueSimplify>(AA, IRP, DepClassTy::NONE);
Optional<Value *> SimplifiedV =
ValueSimplifyAA.getAssumedSimplifiedValue(*this);
bool IsKnown = ValueSimplifyAA.isAtFixpoint();
UsedAssumedInformation |= !IsKnown;
if (!SimplifiedV.hasValue()) {
recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL);
return llvm::None;
}
if (isa_and_nonnull<UndefValue>(SimplifiedV.getValue())) {
recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL);
return UndefValue::get(IRP.getAssociatedType());
SmallVector<AA::ValueAndContext> Values;
if (getAssumedSimplifiedValues(IRP, &AA, Values,
AA::ValueScope::Interprocedural,
UsedAssumedInformation)) {
if (Values.empty())
return llvm::None;
if (auto *C = dyn_cast_or_null<Constant>(
AAPotentialValues::getSingleValue(*this, AA, IRP, Values)))
return C;
}
Constant *CI = dyn_cast_or_null<Constant>(SimplifiedV.getValue());
if (CI)
CI = dyn_cast_or_null<Constant>(
AA::getWithType(*CI, *IRP.getAssociatedType()));
if (CI)
recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL);
return CI;
return nullptr;
}

Optional<Value *>
Attributor::getAssumedSimplified(const IRPosition &IRP,
const AbstractAttribute *AA,
bool &UsedAssumedInformation) {
Optional<Value *> Attributor::getAssumedSimplified(const IRPosition &IRP,
const AbstractAttribute *AA,
bool &UsedAssumedInformation,
AA::ValueScope S) {
// First check all callbacks provided by outside AAs. If any of them returns
// a non-null value that is different from the associated value, or None, we
// assume it's simplified.
for (auto &CB : SimplificationCallbacks.lookup(IRP))
return CB(IRP, AA, UsedAssumedInformation);

// If no high-level/outside simplification occurred, use AAValueSimplify.
const auto &ValueSimplifyAA =
getOrCreateAAFor<AAValueSimplify>(IRP, AA, DepClassTy::NONE);
Optional<Value *> SimplifiedV =
ValueSimplifyAA.getAssumedSimplifiedValue(*this);
bool IsKnown = ValueSimplifyAA.isAtFixpoint();
UsedAssumedInformation |= !IsKnown;
if (!SimplifiedV.hasValue()) {
if (AA)
recordDependence(ValueSimplifyAA, *AA, DepClassTy::OPTIONAL);
SmallVector<AA::ValueAndContext> Values;
if (!getAssumedSimplifiedValues(IRP, AA, Values, S, UsedAssumedInformation))
return &IRP.getAssociatedValue();
if (Values.empty())
return llvm::None;
if (AA)
if (Value *V = AAPotentialValues::getSingleValue(*this, *AA, IRP, Values))
return V;
if (IRP.getPositionKind() == IRPosition::IRP_RETURNED ||
IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_RETURNED)
return nullptr;
return &IRP.getAssociatedValue();
}

bool Attributor::getAssumedSimplifiedValues(
const IRPosition &IRP, const AbstractAttribute *AA,
SmallVectorImpl<AA::ValueAndContext> &Values, AA::ValueScope S,
bool &UsedAssumedInformation) {
// First check all callbacks provided by outside AAs. If any of them returns
// a non-null value that is different from the associated value, or None, we
// assume it's simplified.
const auto &SimplificationCBs = SimplificationCallbacks.lookup(IRP);
for (auto &CB : SimplificationCBs) {
Optional<Value *> CBResult = CB(IRP, AA, UsedAssumedInformation);
if (!CBResult.hasValue())
continue;
Value *V = CBResult.getValue();
if (!V)
return false;
if ((S & AA::ValueScope::Interprocedural) ||
AA::isValidInScope(*V, IRP.getAnchorScope()))
Values.push_back(AA::ValueAndContext{*V, nullptr});
else
return false;
}
if (*SimplifiedV == nullptr)
return const_cast<Value *>(&IRP.getAssociatedValue());
if (Value *SimpleV =
AA::getWithType(**SimplifiedV, *IRP.getAssociatedType())) {
if (AA)
recordDependence(ValueSimplifyAA, *AA, DepClassTy::OPTIONAL);
return SimpleV;
}
return const_cast<Value *>(&IRP.getAssociatedValue());
if (!SimplificationCBs.empty())
return true;

// If no high-level/outside simplification occurred, use AAPotentialValues.
const auto &PotentialValuesAA =
getOrCreateAAFor<AAPotentialValues>(IRP, AA, DepClassTy::OPTIONAL);
if (!PotentialValuesAA.getAssumedSimplifiedValues(*this, Values, S))
return false;
UsedAssumedInformation |= !PotentialValuesAA.isAtFixpoint();
return true;
}

Optional<Value *> Attributor::translateArgumentToCallSiteContent(
Expand All @@ -1106,7 +1141,7 @@ Optional<Value *> Attributor::translateArgumentToCallSiteContent(
if (!Arg->hasPointeeInMemoryValueAttr())
return getAssumedSimplified(
IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,
UsedAssumedInformation);
UsedAssumedInformation, AA::Intraprocedural);
return nullptr;
}

Expand Down Expand Up @@ -1188,16 +1223,14 @@ bool Attributor::isAssumedDead(const Instruction &I,
if (ManifestAddedBlocks.contains(I.getParent()))
return false;

if (!FnLivenessAA)
FnLivenessAA =
lookupAAFor<AAIsDead>(IRPosition::function(*I.getFunction(), CBCtx),
QueryingAA, DepClassTy::NONE);
if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != I.getFunction())
FnLivenessAA = &getOrCreateAAFor<AAIsDead>(
IRPosition::function(*I.getFunction(), CBCtx), QueryingAA,
DepClassTy::NONE);

// If we have a context instruction and a liveness AA we use it.
if (FnLivenessAA &&
FnLivenessAA->getIRPosition().getAnchorScope() == I.getFunction() &&
(CheckBBLivenessOnly ? FnLivenessAA->isAssumedDead(I.getParent())
: FnLivenessAA->isAssumedDead(&I))) {
if (CheckBBLivenessOnly ? FnLivenessAA->isAssumedDead(I.getParent())
: FnLivenessAA->isAssumedDead(&I)) {
if (QueryingAA)
recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
if (!FnLivenessAA->isKnownDead(&I))
Expand Down Expand Up @@ -1268,9 +1301,9 @@ bool Attributor::isAssumedDead(const BasicBlock &BB,
const AbstractAttribute *QueryingAA,
const AAIsDead *FnLivenessAA,
DepClassTy DepClass) {
if (!FnLivenessAA)
FnLivenessAA = lookupAAFor<AAIsDead>(IRPosition::function(*BB.getParent()),
QueryingAA, DepClassTy::NONE);
if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != BB.getParent())
FnLivenessAA = &getOrCreateAAFor<AAIsDead>(
IRPosition::function(*BB.getParent()), QueryingAA, DepClassTy::NONE);
if (FnLivenessAA->isAssumedDead(&BB)) {
if (QueryingAA)
recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
Expand Down Expand Up @@ -2876,7 +2909,9 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
getOrCreateAAFor<AAIsDead>(RetPos);

// Every function might be simplified.
getOrCreateAAFor<AAValueSimplify>(RetPos);
bool UsedAssumedInformation = false;
getAssumedSimplified(RetPos, nullptr, UsedAssumedInformation,
AA::Intraprocedural);

// Every returned value might be marked noundef.
getOrCreateAAFor<AANoUndef>(RetPos);
Expand Down Expand Up @@ -2905,7 +2940,8 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
// interface though as outside AAs can register custom simplification
// callbacks.
bool UsedAssumedInformation = false;
getAssumedSimplified(ArgPos, /* AA */ nullptr, UsedAssumedInformation);
getAssumedSimplified(ArgPos, /* AA */ nullptr, UsedAssumedInformation,
AA::Intraprocedural);

// Every argument might be dead.
getOrCreateAAFor<AAIsDead>(ArgPos);
Expand Down Expand Up @@ -2968,7 +3004,9 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {

IRPosition CBRetPos = IRPosition::callsite_returned(CB);
getOrCreateAAFor<AAValueSimplify>(CBRetPos);
bool UsedAssumedInformation = false;
getAssumedSimplified(CBRetPos, nullptr, UsedAssumedInformation,
AA::Intraprocedural);
}

for (int I = 0, E = CB.arg_size(); I < E; ++I) {
Expand All @@ -2982,7 +3020,8 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
// Attributor interface though as outside AAs can register custom
// simplification callbacks.
bool UsedAssumedInformation = false;
getAssumedSimplified(CBArgPos, /* AA */ nullptr, UsedAssumedInformation);
getAssumedSimplified(CBArgPos, /* AA */ nullptr, UsedAssumedInformation,
AA::Intraprocedural);

// Every call site argument might be marked "noundef".
getOrCreateAAFor<AANoUndef>(CBArgPos);
Expand Down Expand Up @@ -3031,10 +3070,15 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
getOrCreateAAFor<AAAlign>(
IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
if (SimplifyAllLoads)
getOrCreateAAFor<AAValueSimplify>(IRPosition::value(I));
} else
getOrCreateAAFor<AAAlign>(
IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
getAssumedSimplified(IRPosition::value(I), nullptr,
UsedAssumedInformation, AA::Intraprocedural);
} else {
auto &SI = cast<StoreInst>(I);
getOrCreateAAFor<AAIsDead>(IRPosition::inst(I));
getAssumedSimplified(IRPosition::value(*SI.getValueOperand()), nullptr,
UsedAssumedInformation, AA::Intraprocedural);
getOrCreateAAFor<AAAlign>(IRPosition::value(*SI.getPointerOperand()));
}
return true;
};
Success = checkForAllInstructionsImpl(
Expand Down Expand Up @@ -3119,6 +3163,26 @@ raw_ostream &llvm::operator<<(raw_ostream &OS,
return OS;
}

raw_ostream &llvm::operator<<(raw_ostream &OS,
const PotentialLLVMValuesState &S) {
OS << "set-state(< {";
if (!S.isValidState())
OS << "full-set";
else {
for (auto &It : S.getAssumedSet()) {
if (auto *F = dyn_cast<Function>(It.first.getValue()))
OS << "@" << F->getName() << "[" << int(It.second) << "], ";
else
OS << *It.first.getValue() << "[" << int(It.second) << "], ";
}
if (S.undefIsContained())
OS << "undef ";
}
OS << "} >)";

return OS;
}

void AbstractAttribute::print(raw_ostream &OS) const {
OS << "[";
OS << getName();
Expand Down
1,797 changes: 1,076 additions & 721 deletions llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion llvm/lib/Transforms/IPO/OpenMPOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4803,7 +4803,7 @@ void OpenMPOpt::registerAAs(bool IsModulePass) {
if (auto *LI = dyn_cast<LoadInst>(&I)) {
bool UsedAssumedInformation = false;
A.getAssumedSimplified(IRPosition::value(*LI), /* AA */ nullptr,
UsedAssumedInformation);
UsedAssumedInformation, AA::Interprocedural);
} else if (auto *SI = dyn_cast<StoreInst>(&I)) {
A.getOrCreateAAFor<AAIsDead>(IRPosition::value(*SI));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,35 @@
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM

define internal i32 @deref(i32* %x) nounwind {
; IS________OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS________OPM-LABEL: define {{[^@]+}}@deref
; IS________OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0:[0-9]+]] {
; IS________OPM-NEXT: entry:
; IS________OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4
; IS________OPM-NEXT: ret i32 [[TMP2]]
; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@deref
; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4
; IS__CGSCC_OPM-NEXT: ret i32 [[TMP2]]
;
; IS________NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS________NPM-LABEL: define {{[^@]+}}@deref
; IS________NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
; IS________NPM-NEXT: entry:
; IS________NPM-NEXT: [[X_PRIV:%.*]] = alloca i32, align 4
; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]], align 4
; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X_PRIV]], align 4
; IS________NPM-NEXT: ret i32 [[TMP2]]
; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@deref
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]], align 4
; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X_PRIV]], align 4
; IS__CGSCC_NPM-NEXT: ret i32 [[TMP2]]
;
entry:
%tmp2 = load i32, i32* %x, align 4
ret i32 %tmp2
}

define i32 @f(i32 %x) {
; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f
; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X_ADDR]]) #[[ATTR2:[0-9]+]]
; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]]
;
; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f
; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
; IS__TUNIT_NPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[TMP0]]) #[[ATTR2:[0-9]+]]
; IS__TUNIT_NPM-NEXT: ret i32 [[TMP1]]
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@f
; IS__TUNIT____-SAME: (i32 returned [[X:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
; IS__TUNIT____-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
; IS__TUNIT____-NEXT: ret i32 [[X]]
;
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
Expand All @@ -71,9 +60,7 @@ entry:
ret i32 %tmp1
}
;.
; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readonly willreturn }
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
;.
; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ define internal x86_thiscallcc void @internalfun(%struct.a* %this, <{ %struct.a
; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0
; CHECK-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0
; CHECK-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* noundef nonnull align 4 dereferenceable(1) [[TMP1]], %struct.a* noundef nonnull align 4 dereferenceable(1) [[A]])
; CHECK-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* noundef nonnull align 4 dereferenceable(1) [[TMP1]], %struct.a* noundef nonnull dereferenceable(1) [[A]])
; CHECK-NEXT: call void @ext(<{ [[STRUCT_A]] }>* noundef nonnull inalloca(<{ [[STRUCT_A]] }>) align 4 dereferenceable(1) [[ARGMEM]])
; CHECK-NEXT: ret void
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@
; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = constant [[T:%.*]] { i32 0, i32 0, i32 17, i32 25 }
;.
define internal i32 @test(%T* %p) {
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test
; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i32 42
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@test
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = load i32, i32* getelementptr inbounds ([[T:%.*]], %T* @G, i64 0, i32 3), align 4
; CHECK-NEXT: [[B:%.*]] = load i32, i32* getelementptr inbounds ([[T]], %T* @G, i64 0, i32 2), align 8
; CHECK-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
; CHECK-NEXT: ret i32 [[V]]
;
entry:
%a.gep = getelementptr %T, %T* %p, i64 0, i32 3
Expand All @@ -29,15 +32,16 @@ entry:
define i32 @caller() {
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-SAME: () #[[ATTR0]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i32 42
; IS__TUNIT____-NEXT: [[V:%.*]] = call i32 @test() #[[ATTR1:[0-9]+]]
; IS__TUNIT____-NEXT: ret i32 [[V]]
;
; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[V:%.*]] = call noundef i32 @test() #[[ATTR2:[0-9]+]]
; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test() #[[ATTR2:[0-9]+]]
; IS__CGSCC____-NEXT: ret i32 [[V]]
;
entry:
Expand All @@ -46,6 +50,7 @@ entry:
}
;.
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
;.
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
Expand Down
52 changes: 25 additions & 27 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM

define void @f() {
; IS__TUNIT____-LABEL: define {{[^@]+}}@f() {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: call void @g()
; IS__TUNIT____-NEXT: ret void
; IS________OPM-LABEL: define {{[^@]+}}@f() {
; IS________OPM-NEXT: entry:
; IS________OPM-NEXT: [[A:%.*]] = alloca i32, align 1
; IS________OPM-NEXT: call void @g(i32* noalias nocapture nofree noundef nonnull readonly dereferenceable(4) [[A]])
; IS________OPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f() {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 1
; IS__CGSCC_OPM-NEXT: call void @g(i32* noalias nocapture nofree noundef nonnull readonly dereferenceable(4) [[A]])
; IS__CGSCC_OPM-NEXT: ret void
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f() {
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 1
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 1
; IS__TUNIT_NPM-NEXT: call void @g(i32 [[TMP0]])
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f() {
; IS__CGSCC_NPM-NEXT: entry:
Expand All @@ -28,23 +30,19 @@ entry:
}

define internal void @g(i32* %a) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@g() {
; IS__TUNIT____-NEXT: call void @z(i32 undef)
; IS__TUNIT____-NEXT: ret void
; IS________OPM-LABEL: define {{[^@]+}}@g
; IS________OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly dereferenceable(4) [[A:%.*]]) {
; IS________OPM-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1
; IS________OPM-NEXT: call void @z(i32 [[AA]])
; IS________OPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g
; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly dereferenceable(4) [[A:%.*]]) {
; IS__CGSCC_OPM-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1
; IS__CGSCC_OPM-NEXT: call void @z(i32 [[AA]])
; IS__CGSCC_OPM-NEXT: ret void
;
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) {
; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]], align 4
; IS__CGSCC_NPM-NEXT: [[AA:%.*]] = load i32, i32* [[A_PRIV]], align 1
; IS__CGSCC_NPM-NEXT: call void @z(i32 [[AA]])
; IS__CGSCC_NPM-NEXT: ret void
; IS________NPM-LABEL: define {{[^@]+}}@g
; IS________NPM-SAME: (i32 [[TMP0:%.*]]) {
; IS________NPM-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]], align 4
; IS________NPM-NEXT: [[AA:%.*]] = load i32, i32* [[A_PRIV]], align 1
; IS________NPM-NEXT: call void @z(i32 [[AA]])
; IS________NPM-NEXT: ret void
;
%aa = load i32, i32* %a, align 1
call void @z(i32 %aa)
Expand Down Expand Up @@ -112,7 +110,7 @@ define internal i32 @caller(i32* %A) {
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]], align 4
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_PRIV]], i64 noundef 1) #[[ATTR3:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_PRIV]], i64 1) #[[ATTR3:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i32 [[C]]
;
%B = alloca i64
Expand All @@ -139,7 +137,7 @@ define i32 @callercaller() {
; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callercaller
; IS__CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 noundef 2) #[[ATTR4:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 2) #[[ATTR4:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i32 [[X]]
;
%B = alloca i32
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/array.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
;
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ define internal i32 @f(%struct.ss* byval(%struct.ss) %b, i32* byval(i32) %X, i32
; IS________OPM-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull byval([[STRUCT_SS:%.*]]) align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree noundef nonnull byval(i32) align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0:[0-9]+]] {
; IS________OPM-NEXT: entry:
; IS________OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B]], i32 0, i32 0
; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4
; IS________OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
; IS________OPM-NEXT: store i32 0, i32* [[X]], align 4
; IS________OPM-NEXT: [[L:%.*]] = load i32, i32* [[X]], align 4
; IS________OPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
Expand All @@ -34,9 +34,9 @@ define internal i32 @f(%struct.ss* byval(%struct.ss) %b, i32* byval(i32) %X, i32
; IS________NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i64 0, i32 1
; IS________NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4
; IS________NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0
; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4
; IS________NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
; IS________NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
; IS________NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
; IS________NPM-NEXT: store i32 0, i32* [[X_PRIV]], align 4
; IS________NPM-NEXT: [[L:%.*]] = load i32, i32* [[X_PRIV]], align 4
; IS________NPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
Expand Down Expand Up @@ -105,7 +105,7 @@ define i32 @test(i32* %X) {
; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X]], align 4
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 noundef 1, i64 noundef 2, i32 [[TMP0]]) #[[ATTR2:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 1, i64 2, i32 [[TMP0]]) #[[ATTR2:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i32 [[C]]
;
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ define internal i32 @caller(i32* %B) {
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV]], align 4
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 noundef 1, i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B_PRIV]]) #[[ATTR3:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 1, i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B_PRIV]]) #[[ATTR3:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i32 [[C]]
;
%A = alloca i32
Expand All @@ -71,7 +71,7 @@ define i32 @callercaller() {
; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callercaller
; IS__CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 noundef 2) #[[ATTR4:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 2) #[[ATTR4:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i32 [[X]]
;
%B = alloca i32
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ define internal void @f(%struct.ss* byval(%struct.ss) %b, i32* byval(i32) %X) n
; IS________OPM-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull byval([[STRUCT_SS:%.*]]) align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree noundef nonnull writeonly byval(i32) align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0:[0-9]+]] {
; IS________OPM-NEXT: entry:
; IS________OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B]], i32 0, i32 0
; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4
; IS________OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
; IS________OPM-NEXT: store i32 0, i32* [[X]], align 4
; IS________OPM-NEXT: ret void
;
Expand All @@ -30,9 +30,9 @@ define internal void @f(%struct.ss* byval(%struct.ss) %b, i32* byval(i32) %X) n
; IS________NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i64 0, i32 1
; IS________NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4
; IS________NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0
; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4
; IS________NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
; IS________NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
; IS________NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
; IS________NPM-NEXT: store i32 0, i32* [[X_PRIV]], align 4
; IS________NPM-NEXT: ret void
;
Expand Down Expand Up @@ -95,7 +95,7 @@ define i32 @test(i32* %X) {
; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X]], align 4
; IS__CGSCC_NPM-NEXT: call void @f(i32 noundef 1, i64 noundef 2, i32 [[TMP0]]) #[[ATTR2:[0-9]+]]
; IS__CGSCC_NPM-NEXT: call void @f(i32 1, i64 2, i32 [[TMP0]]) #[[ATTR2:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i32 0
;
entry:
Expand Down
28 changes: 14 additions & 14 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ define internal i32 @f(%struct.ss* byval(%struct.ss) %b) nounwind {
; IS________OPM-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull byval([[STRUCT_SS:%.*]]) align 8 dereferenceable(12) [[B:%.*]]) #[[ATTR0:[0-9]+]] {
; IS________OPM-NEXT: entry:
; IS________OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B]], i32 0, i32 0
; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4
; IS________OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
; IS________OPM-NEXT: ret i32 [[TMP1]]
;
; IS________NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
Expand All @@ -29,9 +29,9 @@ define internal i32 @f(%struct.ss* byval(%struct.ss) %b) nounwind {
; IS________NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i64 0, i32 1
; IS________NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4
; IS________NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0
; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4
; IS________NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
; IS________NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
; IS________NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
; IS________NPM-NEXT: ret i32 [[TMP1]]
;
entry:
Expand Down Expand Up @@ -100,15 +100,15 @@ define i32 @main() nounwind {
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8
; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32*
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 8
; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 1
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 8
; IS__TUNIT_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) #[[ATTR2:[0-9]+]]
; IS__TUNIT_NPM-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to i32*
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align 32
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST1]], align 8
; IS__TUNIT_NPM-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 1
; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 32
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_12]], align 8
; IS__TUNIT_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) #[[ATTR2:[0-9]+]]
; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32*
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST]], align 32
; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 1
; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_1]], align 32
; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]]) #[[ATTR2]]
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
Expand All @@ -119,7 +119,7 @@ define i32 @main() nounwind {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 32
; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8
; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4
; IS__CGSCC_OPM-NEXT: [[C0:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_SS]]) align 32 dereferenceable(12) [[S]]) #[[ATTR2:[0-9]+]]
Expand All @@ -134,8 +134,8 @@ define i32 @main() nounwind {
; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
; IS__CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 noundef 1, i64 noundef 2) #[[ATTR2:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 noundef 1, i64 noundef 2) #[[ATTR2]]
; IS__CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 1, i64 2) #[[ATTR2:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 1, i64 2) #[[ATTR2]]
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
; IS__CGSCC_NPM-NEXT: ret i32 [[A]]
;
Expand Down
23 changes: 13 additions & 10 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM

Expand All @@ -13,11 +13,12 @@
;.
define internal i32 @test(i32** %x) {
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test
; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i32 0
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@test
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[Z:%.*]] = load i32, i32* @G1, align 4
; CHECK-NEXT: ret i32 [[Z]]
;
entry:
%y = load i32*, i32** %x
Expand All @@ -28,15 +29,16 @@ entry:
define i32 @caller() {
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-SAME: () #[[ATTR0]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i32 0
; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @test() #[[ATTR1:[0-9]+]]
; IS__TUNIT____-NEXT: ret i32 [[X]]
;
; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[X:%.*]] = call noundef i32 @test() #[[ATTR2:[0-9]+]]
; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @test() #[[ATTR2:[0-9]+]]
; IS__CGSCC____-NEXT: ret i32 [[X]]
;
entry:
Expand All @@ -46,6 +48,7 @@ entry:

;.
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
;.
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ define i32 @foo() {
; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo
; IS__CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @callee(i32 noundef 17) #[[ATTR2:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @callee(i32 17) #[[ATTR2:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i32 [[X]]
;
%A = alloca i32 ; <i32*> [#uses=2]
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM

Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
; PR36543
Expand Down Expand Up @@ -131,7 +131,7 @@ define internal i32 @test2b(%T* %p, i32 %p2) {
; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
; IS__TUNIT____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i32 @bar(%T* undef, i32 [[V]]) #[[ATTR5:[0-9]+]]
; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call noundef i32 @bar(%T* undef, i32 [[V]]) #[[ATTR5:[0-9]+]]
; IS__TUNIT____-NEXT: ret i32 [[CA]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn
Expand All @@ -158,8 +158,8 @@ define i32 @caller2b(%T* %g) {
; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2b
; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[G:%.*]]) #[[ATTR3]] {
; IS__TUNIT____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 undef) #[[ATTR6:[0-9]+]]
; IS__TUNIT____-NEXT: ret i32 0
; IS__TUNIT____-NEXT: [[V:%.*]] = call noundef i32 @test2b(%T* nocapture nofree readonly [[G]], i32 undef) #[[ATTR6:[0-9]+]]
; IS__TUNIT____-NEXT: ret i32 [[V]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2b
Expand Down
50 changes: 24 additions & 26 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
; Checks if !prof metadata is corret in deadargelim.

define void @caller() #0 {
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller() {
; IS__TUNIT____-NEXT: [[X:%.*]] = alloca i32, align 4
; IS__TUNIT____-NEXT: call void @promote_i32_ptr(), !prof [[PROF0:![0-9]+]]
; IS__TUNIT____-NEXT: ret void
; IS________OPM-LABEL: define {{[^@]+}}@caller() {
; IS________OPM-NEXT: [[X:%.*]] = alloca i32, align 4
; IS________OPM-NEXT: store i32 42, i32* [[X]], align 4
; IS________OPM-NEXT: call void @promote_i32_ptr(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X]]), !prof [[PROF0:![0-9]+]]
; IS________OPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller() {
; IS__CGSCC_OPM-NEXT: [[X:%.*]] = alloca i32, align 4
; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[X]], align 4
; IS__CGSCC_OPM-NEXT: call void @promote_i32_ptr(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X]]), !prof [[PROF0:![0-9]+]]
; IS__CGSCC_OPM-NEXT: ret void
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller() {
; IS__TUNIT_NPM-NEXT: [[X:%.*]] = alloca i32, align 4
; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[X]], align 4
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[X]], align 4
; IS__TUNIT_NPM-NEXT: call void @promote_i32_ptr(i32 [[TMP1]]), !prof [[PROF0:![0-9]+]]
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller() {
; IS__CGSCC_NPM-NEXT: call void @promote_i32_ptr(i32 noundef 42), !prof [[PROF0:![0-9]+]]
; IS__CGSCC_NPM-NEXT: call void @promote_i32_ptr(i32 42), !prof [[PROF0:![0-9]+]]
; IS__CGSCC_NPM-NEXT: ret void
;
%x = alloca i32
Expand All @@ -30,23 +32,19 @@ define void @caller() #0 {
}

define internal void @promote_i32_ptr(i32* %xp) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@promote_i32_ptr() {
; IS__TUNIT____-NEXT: call void @use_i32(i32 noundef 42)
; IS__TUNIT____-NEXT: ret void
; IS________OPM-LABEL: define {{[^@]+}}@promote_i32_ptr
; IS________OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[XP:%.*]]) {
; IS________OPM-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4
; IS________OPM-NEXT: call void @use_i32(i32 [[X]])
; IS________OPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@promote_i32_ptr
; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[XP:%.*]]) {
; IS__CGSCC_OPM-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4
; IS__CGSCC_OPM-NEXT: call void @use_i32(i32 [[X]])
; IS__CGSCC_OPM-NEXT: ret void
;
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@promote_i32_ptr
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) {
; IS__CGSCC_NPM-NEXT: [[XP_PRIV:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[XP_PRIV]], align 4
; IS__CGSCC_NPM-NEXT: [[X:%.*]] = load i32, i32* [[XP_PRIV]], align 4
; IS__CGSCC_NPM-NEXT: call void @use_i32(i32 [[X]])
; IS__CGSCC_NPM-NEXT: ret void
; IS________NPM-LABEL: define {{[^@]+}}@promote_i32_ptr
; IS________NPM-SAME: (i32 [[TMP0:%.*]]) {
; IS________NPM-NEXT: [[XP_PRIV:%.*]] = alloca i32, align 4
; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[XP_PRIV]], align 4
; IS________NPM-NEXT: [[X:%.*]] = load i32, i32* [[XP_PRIV]], align 4
; IS________NPM-NEXT: call void @use_i32(i32 [[X]])
; IS________NPM-NEXT: ret void
;
%x = load i32, i32* %xp
call void @use_i32(i32 %x)
Expand Down
5 changes: 3 additions & 2 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ define internal void @add({i32, i32}* %this, i32* sret(i32) %r) {
; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@add
; IS__TUNIT____-SAME: ({ i32, i32 }* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-NEXT: store i32 undef, i32* [[R]], align 4
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@add
; IS__CGSCC_OPM-SAME: ({ i32, i32 }* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC_OPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0
; IS__CGSCC_OPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 4
; IS__CGSCC_OPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4
; IS__CGSCC_OPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]]
; IS__CGSCC_OPM-NEXT: store i32 [[AB]], i32* [[R]], align 4
Expand All @@ -30,7 +31,7 @@ define internal void @add({i32, i32}* %this, i32* sret(i32) %r) {
; IS__CGSCC_NPM-SAME: ({ i32, i32 }* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0
; IS__CGSCC_NPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 4
; IS__CGSCC_NPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4
; IS__CGSCC_NPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]]
; IS__CGSCC_NPM-NEXT: store i32 [[AB]], i32* [[R]], align 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ define internal void @vfu1(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nounw
; IS________OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1
; IS________OPM-NEXT: store i32 99, i32* [[TMP0]], align 4
; IS________OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0
; IS________OPM-NEXT: store i8 97, i8* [[TMP1]], align 8
; IS________OPM-NEXT: [[L:%.*]] = load i8, i8* [[TMP1]], align 8
; IS________OPM-NEXT: store i8 97, i8* [[TMP1]], align 4
; IS________OPM-NEXT: [[L:%.*]] = load i8, i8* [[TMP1]], align 4
; IS________OPM-NEXT: call void @use(i8 [[L]])
; IS________OPM-NEXT: br label [[RETURN:%.*]]
; IS________OPM: return:
Expand All @@ -40,8 +40,8 @@ define internal void @vfu1(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nounw
; IS________NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
; IS________NPM-NEXT: store i32 99, i32* [[TMP2]], align 4
; IS________NPM-NEXT: [[TMP3:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0
; IS________NPM-NEXT: store i8 97, i8* [[TMP3]], align 8
; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[TMP3]], align 8
; IS________NPM-NEXT: store i8 97, i8* [[TMP3]], align 4
; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[TMP3]], align 4
; IS________NPM-NEXT: call void @use(i8 [[L]])
; IS________NPM-NEXT: br label [[RETURN:%.*]]
; IS________NPM: return:
Expand All @@ -68,7 +68,7 @@ define internal i32 @vfu2(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nounwi
; IS________OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1
; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
; IS________OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0
; IS________OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8
; IS________OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 4
; IS________OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32
; IS________OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]]
; IS________OPM-NEXT: ret i32 [[TMP5]]
Expand All @@ -85,7 +85,7 @@ define internal i32 @vfu2(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nounwi
; IS________NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
; IS________NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0
; IS________NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8
; IS________NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 4
; IS________NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32
; IS________NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]]
; IS________NPM-NEXT: ret i32 [[TMP7]]
Expand Down Expand Up @@ -163,7 +163,7 @@ define internal i32 @vfu2_v2(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nou
; IS________OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1
; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
; IS________OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0
; IS________OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8
; IS________OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 4
; IS________OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32
; IS________OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]]
; IS________OPM-NEXT: ret i32 [[TMP5]]
Expand All @@ -182,7 +182,7 @@ define internal i32 @vfu2_v2(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nou
; IS________NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
; IS________NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0
; IS________NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8
; IS________NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 4
; IS________NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32
; IS________NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]]
; IS________NPM-NEXT: ret i32 [[TMP7]]
Expand Down Expand Up @@ -212,15 +212,15 @@ define i32 @unions_v2() nounwind {
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unions_v2
; IS__TUNIT_NPM-SAME: () #[[ATTR0]] {
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8*
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]], align 8
; IS__TUNIT_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i64 0, i32 1
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 8
; IS__TUNIT_NPM-NEXT: call void @vfu1(i8 [[TMP0]], i32 [[TMP1]]) #[[ATTR0]]
; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST1:%.*]] = bitcast %struct.MYstr* @mystr to i8*
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i8, i8* [[MYSTR_CAST1]], align 8
; IS__TUNIT_NPM-NEXT: [[MYSTR_0_12:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i64 0, i32 1
; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[MYSTR_0_12]], align 8
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST1]], align 8
; IS__TUNIT_NPM-NEXT: [[MYSTR_0_12:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i64 0, i32 1
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_12]], align 8
; IS__TUNIT_NPM-NEXT: call void @vfu1(i8 [[TMP0]], i32 [[TMP1]]) #[[ATTR0]]
; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8*
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i8, i8* [[MYSTR_CAST]], align 8
; IS__TUNIT_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i64 0, i32 1
; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[MYSTR_0_1]], align 8
; IS__TUNIT_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP2]], i32 [[TMP3]]) #[[ATTR2]]
; IS__TUNIT_NPM-NEXT: ret i32 [[RESULT]]
;
Expand Down
14 changes: 8 additions & 6 deletions llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ define i64 @fn2() {
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2
; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i64 poison
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 poison) #[[ATTR2:[0-9]+]]
; IS__CGSCC____-NEXT: ret i64 [[CALL2]]
;
entry:
%conv = sext i32 undef to i64
Expand All @@ -44,7 +45,8 @@ define i64 @fn2b(i32 %arg) {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
; IS__CGSCC____-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
; IS__CGSCC____-NEXT: ret i64 [[DIV]]
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #[[ATTR2]]
; IS__CGSCC____-NEXT: ret i64 [[CALL2]]
;
entry:
%conv = sext i32 %arg to i64
Expand All @@ -64,7 +66,8 @@ define i64 @fn2c() {
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2c
; IS__CGSCC____-SAME: () #[[ATTR0]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i64 42
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 noundef 42) #[[ATTR2]]
; IS__CGSCC____-NEXT: ret i64 [[CALL2]]
;
entry:
%conv = sext i32 undef to i64
Expand All @@ -78,9 +81,7 @@ define internal i64 @fn1(i64 %p1) {
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1
; IS__CGSCC____-SAME: (i64 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0
; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]]
; IS__CGSCC____-NEXT: ret i64 [[COND]]
; IS__CGSCC____-NEXT: ret i64 [[P1]]
;
entry:
%tobool = icmp ne i64 %p1, 0
Expand All @@ -92,4 +93,5 @@ entry:
;.
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR2]] = { readnone willreturn }
;.
18 changes: 8 additions & 10 deletions llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
Expand Down Expand Up @@ -33,7 +33,8 @@ define void @fn2(i32* %P, i1 %C) {
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
; IS__CGSCC____-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]])
; IS__CGSCC____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
; IS__CGSCC____-NEXT: br label [[FOR_COND1]]
; IS__CGSCC____: exit:
; IS__CGSCC____-NEXT: ret void
Expand All @@ -59,9 +60,7 @@ define internal i32 @fn1(i32 %p1) {
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1
; IS__CGSCC____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
; IS__CGSCC____-NEXT: ret i32 [[COND]]
; IS__CGSCC____-NEXT: ret i32 [[P1]]
;
entry:
%tobool = icmp ne i32 %p1, 0
Expand Down Expand Up @@ -96,7 +95,8 @@ define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid {
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4294967296
; IS__CGSCC____-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
; IS__CGSCC____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
; IS__CGSCC____-NEXT: br label [[FOR_COND1]]
; IS__CGSCC____: exit:
; IS__CGSCC____-NEXT: ret void
Expand All @@ -122,9 +122,7 @@ define internal i32 @fn0(i32 %p1) {
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn0
; IS__CGSCC____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
; IS__CGSCC____-NEXT: ret i32 [[COND]]
; IS__CGSCC____-NEXT: ret i32 [[P1]]
;
entry:
%tobool = icmp ne i32 %p1, 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ entry:
define internal i32 @cb1(i32 %unknown) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@cb1
; CHECK-SAME: (i32 noundef returned [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 [[UNKNOWN]]
;
Expand All @@ -64,13 +64,13 @@ entry:
define internal i32 @cb2(i32 %unknown) {
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@cb2
; IS__TUNIT____-SAME: (i32 noundef returned [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i32 [[UNKNOWN]]
;
; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@cb2
; IS__CGSCC____-SAME: (i32 noundef returned [[UNKNOWN:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__CGSCC____-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i32 [[UNKNOWN]]
;
Expand All @@ -82,7 +82,7 @@ entry:
define internal i32 @cb3(i32 %unknown) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@cb3
; CHECK-SAME: (i32 noundef returned [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 [[UNKNOWN]]
;
Expand All @@ -93,7 +93,7 @@ entry:
define internal i32 @cb4(i32 %unknown) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@cb4
; CHECK-SAME: (i32 noundef returned [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 [[UNKNOWN]]
;
Expand Down
144 changes: 47 additions & 97 deletions llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
; PR36485
Expand All @@ -10,71 +10,38 @@ declare i32 @external()

define i8* @start(i8 %v) {
;
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@start
; IS__TUNIT_OPM-SAME: (i8 [[V:%.*]]) {
; IS__TUNIT_OPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
; IS__TUNIT_OPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; IS__TUNIT_OPM: true:
; IS__TUNIT_OPM-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]])
; IS__TUNIT_OPM-NEXT: ret i8* [[CA]]
; IS__TUNIT_OPM: false:
; IS__TUNIT_OPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
; IS__TUNIT_OPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
; IS__TUNIT_OPM: c2_true:
; IS__TUNIT_OPM-NEXT: ret i8* null
; IS__TUNIT_OPM: c2_false:
; IS__TUNIT_OPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
; IS__TUNIT_OPM-NEXT: ret i8* [[CA2]]
;
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@start
; IS__TUNIT_NPM-SAME: (i8 [[V:%.*]]) {
; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
; IS__TUNIT_NPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; IS__TUNIT_NPM: true:
; IS__TUNIT_NPM-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 undef)
; IS__TUNIT_NPM-NEXT: ret i8* [[CA]]
; IS__TUNIT_NPM: false:
; IS__TUNIT_NPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
; IS__TUNIT_NPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
; IS__TUNIT_NPM: c2_true:
; IS__TUNIT_NPM-NEXT: ret i8* null
; IS__TUNIT_NPM: c2_false:
; IS__TUNIT_NPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
; IS__TUNIT_NPM-NEXT: ret i8* [[CA2]]
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@start
; IS__CGSCC_OPM-SAME: (i8 [[V:%.*]]) {
; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
; IS__CGSCC_OPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; IS__CGSCC_OPM: true:
; IS__CGSCC_OPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @side_effects(i8 [[V]])
; IS__CGSCC_OPM-NEXT: ret i8* [[CA]]
; IS__CGSCC_OPM: false:
; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
; IS__CGSCC_OPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
; IS__CGSCC_OPM: c2_true:
; IS__CGSCC_OPM-NEXT: [[CA1:%.*]] = musttail call noalias noundef align 4294967296 i8* @no_side_effects(i8 [[V]])
; IS__CGSCC_OPM-NEXT: ret i8* [[CA1]]
; IS__CGSCC_OPM: c2_false:
; IS__CGSCC_OPM-NEXT: [[CA2:%.*]] = musttail call noalias noundef align 4294967296 i8* @dont_zap_me(i8 [[V]])
; IS__CGSCC_OPM-NEXT: ret i8* [[CA2]]
; IS__TUNIT____-LABEL: define {{[^@]+}}@start
; IS__TUNIT____-SAME: (i8 [[V:%.*]]) {
; IS__TUNIT____-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
; IS__TUNIT____-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; IS__TUNIT____: true:
; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @side_effects(i8 [[V]])
; IS__TUNIT____-NEXT: ret i8* [[CA]]
; IS__TUNIT____: false:
; IS__TUNIT____-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
; IS__TUNIT____-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
; IS__TUNIT____: c2_true:
; IS__TUNIT____-NEXT: ret i8* null
; IS__TUNIT____: c2_false:
; IS__TUNIT____-NEXT: [[CA2:%.*]] = musttail call noalias noundef align 4294967296 i8* @dont_zap_me(i8 undef)
; IS__TUNIT____-NEXT: ret i8* [[CA2]]
;
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@start
; IS__CGSCC_NPM-SAME: (i8 [[V:%.*]]) {
; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
; IS__CGSCC_NPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; IS__CGSCC_NPM: true:
; IS__CGSCC_NPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @side_effects(i8 undef)
; IS__CGSCC_NPM-NEXT: ret i8* [[CA]]
; IS__CGSCC_NPM: false:
; IS__CGSCC_NPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
; IS__CGSCC_NPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
; IS__CGSCC_NPM: c2_true:
; IS__CGSCC_NPM-NEXT: [[CA1:%.*]] = musttail call noalias noundef align 4294967296 i8* @no_side_effects(i8 [[V]])
; IS__CGSCC_NPM-NEXT: ret i8* [[CA1]]
; IS__CGSCC_NPM: c2_false:
; IS__CGSCC_NPM-NEXT: [[CA2:%.*]] = musttail call noalias noundef align 4294967296 i8* @dont_zap_me(i8 [[V]])
; IS__CGSCC_NPM-NEXT: ret i8* [[CA2]]
; IS__CGSCC____-LABEL: define {{[^@]+}}@start
; IS__CGSCC____-SAME: (i8 [[V:%.*]]) {
; IS__CGSCC____-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
; IS__CGSCC____-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; IS__CGSCC____: true:
; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @side_effects(i8 [[V]])
; IS__CGSCC____-NEXT: ret i8* [[CA]]
; IS__CGSCC____: false:
; IS__CGSCC____-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
; IS__CGSCC____-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
; IS__CGSCC____: c2_true:
; IS__CGSCC____-NEXT: [[CA1:%.*]] = musttail call noalias noundef align 4294967296 i8* @no_side_effects(i8 [[V]])
; IS__CGSCC____-NEXT: ret i8* [[CA1]]
; IS__CGSCC____: c2_false:
; IS__CGSCC____-NEXT: [[CA2:%.*]] = musttail call noalias noundef align 4294967296 i8* @dont_zap_me(i8 [[V]])
; IS__CGSCC____-NEXT: ret i8* [[CA2]]
;
%c1 = icmp eq i8 %v, 0
br i1 %c1, label %true, label %false
Expand All @@ -94,29 +61,17 @@ c2_false:
}

define internal i8* @side_effects(i8 %v) {
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@side_effects
; IS__TUNIT_OPM-SAME: (i8 [[V:%.*]]) {
; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = call i32 @external()
; IS__TUNIT_OPM-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]])
; IS__TUNIT_OPM-NEXT: ret i8* [[CA]]
;
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@side_effects
; IS__TUNIT_NPM-SAME: (i8 [[V:%.*]]) {
; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = call i32 @external()
; IS__TUNIT_NPM-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 0)
; IS__TUNIT_NPM-NEXT: ret i8* [[CA]]
; IS________OPM-LABEL: define {{[^@]+}}@side_effects
; IS________OPM-SAME: (i8 [[V:%.*]]) {
; IS________OPM-NEXT: [[I1:%.*]] = call i32 @external()
; IS________OPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @start(i8 [[V]])
; IS________OPM-NEXT: ret i8* [[CA]]
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@side_effects
; IS__CGSCC_OPM-SAME: (i8 [[V:%.*]]) {
; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = call i32 @external()
; IS__CGSCC_OPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @start(i8 [[V]])
; IS__CGSCC_OPM-NEXT: ret i8* [[CA]]
;
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@side_effects
; IS__CGSCC_NPM-SAME: (i8 [[V:%.*]]) {
; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = call i32 @external()
; IS__CGSCC_NPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @start(i8 0)
; IS__CGSCC_NPM-NEXT: ret i8* [[CA]]
; IS________NPM-LABEL: define {{[^@]+}}@side_effects
; IS________NPM-SAME: (i8 [[V:%.*]]) {
; IS________NPM-NEXT: [[I1:%.*]] = call i32 @external()
; IS________NPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @start(i8 0)
; IS________NPM-NEXT: ret i8* [[CA]]
;
%i1 = call i32 @external()

Expand All @@ -140,15 +95,10 @@ define internal i8* @no_side_effects(i8 %v) readonly nounwind {
}

define internal i8* @dont_zap_me(i8 %v) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@dont_zap_me
; IS__TUNIT____-SAME: (i8 [[V:%.*]]) {
; IS__TUNIT____-NEXT: [[I1:%.*]] = call i32 @external()
; IS__TUNIT____-NEXT: ret i8* undef
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_zap_me
; IS__CGSCC____-SAME: (i8 [[V:%.*]]) {
; IS__CGSCC____-NEXT: [[I1:%.*]] = call i32 @external()
; IS__CGSCC____-NEXT: ret i8* null
; CHECK-LABEL: define {{[^@]+}}@dont_zap_me
; CHECK-SAME: (i8 [[V:%.*]]) {
; CHECK-NEXT: [[I1:%.*]] = call i32 @external()
; CHECK-NEXT: ret i8* null
;
%i1 = call i32 @external()
ret i8* null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=15 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=15 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
;
Expand Down
122 changes: 42 additions & 80 deletions llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll
Original file line number Diff line number Diff line change
Expand Up @@ -66,81 +66,43 @@ define internal { i32, i32 } @foo(i32 %A, i32 %B) {
}

define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@caller
; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] personality i32 (...)* @__gxx_personality_v0 {
; IS__TUNIT_OPM-NEXT: [[Q:%.*]] = alloca i32, align 4
; IS__TUNIT_OPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
; IS__TUNIT_OPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR3:[0-9]+]]
; IS__TUNIT_OPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
; IS__TUNIT_OPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR3]]
; IS__TUNIT_OPM-NEXT: br label [[OK:%.*]]
; IS__TUNIT_OPM: OK:
; IS__TUNIT_OPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
; IS__TUNIT_OPM-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
; IS__TUNIT_OPM-NEXT: store i32 [[Z]], i32* [[W]], align 4
; IS__TUNIT_OPM-NEXT: br label [[RET:%.*]]
; IS__TUNIT_OPM: LPAD:
; IS__TUNIT_OPM-NEXT: unreachable
; IS__TUNIT_OPM: RET:
; IS__TUNIT_OPM-NEXT: ret void
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] personality i32 (...)* @__gxx_personality_v0 {
; IS__TUNIT____-NEXT: [[Q:%.*]] = alloca i32, align 4
; IS__TUNIT____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
; IS__TUNIT____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR3:[0-9]+]]
; IS__TUNIT____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
; IS__TUNIT____-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR3]]
; IS__TUNIT____-NEXT: br label [[OK:%.*]]
; IS__TUNIT____: OK:
; IS__TUNIT____-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
; IS__TUNIT____-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
; IS__TUNIT____-NEXT: store i32 [[Z]], i32* [[Q]], align 4
; IS__TUNIT____-NEXT: br label [[RET:%.*]]
; IS__TUNIT____: LPAD:
; IS__TUNIT____-NEXT: unreachable
; IS__TUNIT____: RET:
; IS__TUNIT____-NEXT: ret void
;
; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller
; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] personality i32 (...)* @__gxx_personality_v0 {
; IS__TUNIT_NPM-NEXT: [[Q:%.*]] = alloca i32, align 4
; IS__TUNIT_NPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
; IS__TUNIT_NPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR3:[0-9]+]]
; IS__TUNIT_NPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
; IS__TUNIT_NPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR3]]
; IS__TUNIT_NPM-NEXT: br label [[OK:%.*]]
; IS__TUNIT_NPM: OK:
; IS__TUNIT_NPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
; IS__TUNIT_NPM-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
; IS__TUNIT_NPM-NEXT: store i32 [[Z]], i32* [[Q]], align 4
; IS__TUNIT_NPM-NEXT: br label [[RET:%.*]]
; IS__TUNIT_NPM: LPAD:
; IS__TUNIT_NPM-NEXT: unreachable
; IS__TUNIT_NPM: RET:
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 {
; IS__CGSCC_OPM-NEXT: [[Q:%.*]] = alloca i32, align 4
; IS__CGSCC_OPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[Q]]) #[[ATTR3:[0-9]+]]
; IS__CGSCC_OPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR4:[0-9]+]]
; IS__CGSCC_OPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
; IS__CGSCC_OPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR5:[0-9]+]]
; IS__CGSCC_OPM-NEXT: br label [[OK:%.*]]
; IS__CGSCC_OPM: OK:
; IS__CGSCC_OPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
; IS__CGSCC_OPM-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
; IS__CGSCC_OPM-NEXT: store i32 [[Z]], i32* [[W]], align 4
; IS__CGSCC_OPM-NEXT: br label [[RET:%.*]]
; IS__CGSCC_OPM: LPAD:
; IS__CGSCC_OPM-NEXT: unreachable
; IS__CGSCC_OPM: RET:
; IS__CGSCC_OPM-NEXT: ret void
;
; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller
; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 {
; IS__CGSCC_NPM-NEXT: [[Q:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[Q]]) #[[ATTR3:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR4:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
; IS__CGSCC_NPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR5:[0-9]+]]
; IS__CGSCC_NPM-NEXT: br label [[OK:%.*]]
; IS__CGSCC_NPM: OK:
; IS__CGSCC_NPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
; IS__CGSCC_NPM-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
; IS__CGSCC_NPM-NEXT: store i32 [[Z]], i32* [[Q]], align 4
; IS__CGSCC_NPM-NEXT: br label [[RET:%.*]]
; IS__CGSCC_NPM: LPAD:
; IS__CGSCC_NPM-NEXT: unreachable
; IS__CGSCC_NPM: RET:
; IS__CGSCC_NPM-NEXT: ret void
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 {
; IS__CGSCC____-NEXT: [[Q:%.*]] = alloca i32, align 4
; IS__CGSCC____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[Q]]) #[[ATTR3:[0-9]+]]
; IS__CGSCC____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR4:[0-9]+]]
; IS__CGSCC____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
; IS__CGSCC____-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR5:[0-9]+]]
; IS__CGSCC____-NEXT: br label [[OK:%.*]]
; IS__CGSCC____: OK:
; IS__CGSCC____-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
; IS__CGSCC____-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
; IS__CGSCC____-NEXT: store i32 [[Z]], i32* [[W]], align 4
; IS__CGSCC____-NEXT: br label [[RET:%.*]]
; IS__CGSCC____: LPAD:
; IS__CGSCC____-NEXT: unreachable
; IS__CGSCC____: RET:
; IS__CGSCC____-NEXT: ret void
;
%Q = alloca i32
;; Call incdec to see if %W is properly replaced by %Q
Expand Down Expand Up @@ -172,13 +134,13 @@ declare i32 @__gxx_personality_v0(...)
;.
; IS__TUNIT____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind willreturn }
; IS__TUNIT____: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn }
; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn }
;.
; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR3:[0-9]+]] = { nounwind willreturn }
; IS__CGSCC____: attributes #[[ATTR4:[0-9]+]] = { readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR5:[0-9]+]] = { nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn }
; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind willreturn }
; IS__CGSCC____: attributes #[[ATTR4]] = { readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR5]] = { nounwind readnone willreturn }
;.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define internal i32 @callee(i32* %thread_local_ptr, i32* %shared_ptr) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
; CHECK-LABEL: define {{[^@]+}}@callee
; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[THREAD_LOCAL_PTR:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[SHARED_PTR:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[THREAD_LOCAL_PTR:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[SHARED_PTR:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[THREAD_LOCAL_PTR]], align 4
; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* @gtl, align 4
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @gsh, align 4
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP]], [[TMP1]]
; CHECK-NEXT: ret i32 [[ADD]]
Expand All @@ -47,7 +47,7 @@ entry:
define dso_local void @caller() {
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller() {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: call void @broker(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* noundef nonnull @callee, i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) undef)
; IS__TUNIT____-NEXT: call void @broker(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) undef, i32 (i32*, i32*)* noundef nonnull @callee, i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) undef)
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller() {
Expand Down
Loading