1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[Attributor] Use AAValueSimplify to simplify returned values

We should use AAValueSimplify for all value simplification, however
there was some leftover logic that predates AAValueSimplify in
AAReturnedValues. This remove the AAReturnedValues part and provides a
replacement by making AAValueSimplifyReturned strong enough to handle
all previously covered cases. Further, this improve
AAValueSimplifyCallSiteReturned to handle returned arguments.

AAReturnedValues is now much easier and the collected returned
values/instructions are now from the associated function only, making it
much more sane. We also do not have the brittle logic anymore that looks
for unresolved calls. Instead, we use AAValueSimplify to handle
recursion.

Useful code has been split into helper functions, e.g., an Attributor
interface to get a simplified value.

Differential Revision: https://reviews.llvm.org/D103860
This commit is contained in:
Johannes Doerfert 2021-05-09 20:16:50 -05:00
parent 7153a66c48
commit 8ee9d51790
38 changed files with 853 additions and 1103 deletions

View File

@ -1481,6 +1481,12 @@ struct Attributor {
bool &UsedAssumedInformation) {
return getAssumedSimplified(IRP, &AA, UsedAssumedInformation);
}
Optional<Value *> getAssumedSimplified(const Value &V,
const AbstractAttribute &AA,
bool &UsedAssumedInformation) {
return getAssumedSimplified(IRPosition::value(V), AA,
UsedAssumedInformation);
}
/// Register \p CB as a simplification callback.
/// `Attributor::getAssumedSimplified` will use these callbacks before
@ -1507,6 +1513,12 @@ private:
bool &UsedAssumedInformation);
public:
/// Translate \p V from the callee context into the call site context.
Optional<Value *>
translateArgumentToCallSiteContent(Optional<Value *> V, CallBase &CB,
const AbstractAttribute &AA,
bool &UsedAssumedInformation);
/// Return true if \p AA (or its context instruction) is assumed dead.
///
/// If \p LivenessAA is not provided it is queried.
@ -2654,7 +2666,6 @@ struct AAReturnedValues
virtual llvm::iterator_range<const_iterator> returned_values() const = 0;
virtual size_t getNumReturnValues() const = 0;
virtual const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const = 0;
/// Create an abstract attribute view for the position \p IRP.
static AAReturnedValues &createForPosition(const IRPosition &IRP,

View File

@ -26,6 +26,7 @@
#include "llvm/Analysis/MustExecute.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/IRBuilder.h"
@ -670,6 +671,21 @@ Attributor::getAssumedSimplified(const IRPosition &IRP,
return const_cast<Value *>(&IRP.getAssociatedValue());
}
Optional<Value *> Attributor::translateArgumentToCallSiteContent(
Optional<Value *> V, CallBase &CB, const AbstractAttribute &AA,
bool &UsedAssumedInformation) {
if (!V.hasValue())
return V;
if (*V == nullptr || isa<Constant>(*V))
return V;
if (auto *Arg = dyn_cast<Argument>(*V))
if (!Arg->hasPointeeInMemoryValueAttr())
return getAssumedSimplified(
IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,
UsedAssumedInformation);
return nullptr;
}
Attributor::~Attributor() {
// The abstract attributes are allocated via the BumpPtrAllocator Allocator,
// thus we cannot delete them. We can, and want to, destruct them though.
@ -1365,11 +1381,17 @@ ChangeStatus Attributor::cleanupIR() {
// Do not replace uses in returns if the value is a must-tail call we will
// not delete.
if (isa<ReturnInst>(U->getUser()))
if (auto *RI = dyn_cast<ReturnInst>(U->getUser())) {
if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))
if (CI->isMustTailCall() &&
(!ToBeDeletedInsts.count(CI) || !isRunOn(*CI->getCaller())))
return;
// If we rewrite a return and the new value is not an argument, strip the
// `returned` attribute as it is wrong now.
if (!isa<Argument>(NewV))
for (auto &Arg : RI->getFunction()->args())
Arg.removeAttr(Attribute::Returned);
}
// Do not perform call graph altering changes outside the SCC.
if (auto *CB = dyn_cast<CallBase>(U->getUser()))
@ -2292,10 +2314,7 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
IRPosition CBRetPos = IRPosition::callsite_returned(CB);
// Call site return integer values might be limited by a constant range.
if (Callee->getReturnType()->isIntegerTy())
getOrCreateAAFor<AAValueConstantRange>(CBRetPos);
getOrCreateAAFor<AAValueSimplify>(CBRetPos);
}
for (int I = 0, E = CB.getNumArgOperands(); I < E; ++I) {

View File

@ -831,13 +831,6 @@ class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
/// return instructions that might return them.
MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
/// Mapping to remember the number of returned values for a call site such
/// that we can avoid updates if nothing changed.
DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
/// Set of unresolved calls returned by the associated function.
SmallSetVector<CallBase *, 4> UnresolvedCalls;
/// State flags
///
///{
@ -904,10 +897,6 @@ public:
return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
}
const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
return UnresolvedCalls;
}
/// Return the number of potential return values, -1 if unknown.
size_t getNumReturnValues() const override {
return isValidState() ? ReturnedValues.size() : -1;
@ -962,16 +951,6 @@ ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
// Bookkeeping.
STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
"Number of function with unique return");
// Callback to replace the uses of CB with the constant C.
auto ReplaceCallSiteUsersWith = [&A](CallBase &CB, Constant &C) {
if (CB.use_empty())
return ChangeStatus::UNCHANGED;
if (A.changeValueAfterManifest(CB, C))
return ChangeStatus::CHANGED;
return ChangeStatus::UNCHANGED;
};
// If the assumed unique return value is an argument, annotate it.
if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
if (UniqueRVArg->getType()->canLosslesslyBitCastTo(
@ -979,40 +958,13 @@ ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
getIRPosition() = IRPosition::argument(*UniqueRVArg);
Changed = IRAttribute::manifest(A);
}
} else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
// We can replace the returned value with the unique returned constant.
Value &AnchorValue = getAnchorValue();
if (Function *F = dyn_cast<Function>(&AnchorValue)) {
for (const Use &U : F->uses())
if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
if (CB->isCallee(&U)) {
Constant *RVCCast =
CB->getType() == RVC->getType()
? RVC
: ConstantExpr::getPointerCast(RVC, CB->getType());
Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
}
} else {
assert(isa<CallBase>(AnchorValue) &&
"Expcected a function or call base anchor!");
Constant *RVCCast =
AnchorValue.getType() == RVC->getType()
? RVC
: ConstantExpr::getPointerCast(RVC, AnchorValue.getType());
Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
}
if (Changed == ChangeStatus::CHANGED)
STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
"Number of function returns replaced by constant return");
}
return Changed;
}
const std::string AAReturnedValuesImpl::getAsStr() const {
return (isAtFixpoint() ? "returns(#" : "may-return(#") +
(isValidState() ? std::to_string(getNumReturnValues()) : "?") +
")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
(isValidState() ? std::to_string(getNumReturnValues()) : "?") + ")";
}
Optional<Value *>
@ -1046,11 +998,6 @@ bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
// encountered an overdefined one during an update.
for (auto &It : ReturnedValues) {
Value *RV = It.first;
CallBase *CB = dyn_cast<CallBase>(RV);
if (CB && !UnresolvedCalls.count(CB))
continue;
if (!Pred(*RV, It.second))
return false;
}
@ -1059,180 +1006,35 @@ bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
}
ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
size_t NumUnresolvedCalls = UnresolvedCalls.size();
bool Changed = false;
ChangeStatus Changed = ChangeStatus::UNCHANGED;
// State used in the value traversals starting in returned values.
struct RVState {
// The map in which we collect return values -> return instrs.
decltype(ReturnedValues) &RetValsMap;
// The flag to indicate a change.
bool &Changed;
// The return instrs we come from.
SmallSetVector<ReturnInst *, 4> RetInsts;
};
// Callback for a leaf value returned by the associated function.
auto VisitValueCB = [](Value &Val, const Instruction *, RVState &RVS,
auto ReturnValueCB = [&](Value &V, const Instruction *CtxI, ReturnInst &Ret,
bool) -> bool {
auto Size = RVS.RetValsMap[&Val].size();
RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
bool Inserted = RVS.RetValsMap[&Val].size() != Size;
RVS.Changed |= Inserted;
LLVM_DEBUG({
if (Inserted)
dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
<< " => " << RVS.RetInsts.size() << "\n";
});
bool UsedAssumedInformation = false;
Optional<Value *> SimpleRetVal =
A.getAssumedSimplified(V, *this, UsedAssumedInformation);
if (!SimpleRetVal.hasValue())
return true;
Value *RetVal = *SimpleRetVal ? *SimpleRetVal : &V;
assert(AA::isValidInScope(*RetVal, Ret.getFunction()) &&
"Assumed returned value should be valid in function scope!");
if (ReturnedValues[RetVal].insert(&Ret))
Changed = ChangeStatus::CHANGED;
return true;
};
// Helper method to invoke the generic value traversal.
auto VisitReturnedValue = [&](Value &RV, RVState &RVS,
const Instruction *CtxI) {
IRPosition RetValPos = IRPosition::value(RV, getCallBaseContext());
return genericValueTraversal<RVState>(A, RetValPos, *this, RVS,
VisitValueCB, CtxI,
/* UseValueSimplify */ false);
};
// Callback for all "return intructions" live in the associated function.
auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
auto ReturnInstCB = [&](Instruction &I) {
ReturnInst &Ret = cast<ReturnInst>(I);
RVState RVS({ReturnedValues, Changed, {}});
RVS.RetInsts.insert(&Ret);
return VisitReturnedValue(*Ret.getReturnValue(), RVS, &I);
return genericValueTraversal<ReturnInst>(
A, IRPosition::value(*Ret.getReturnValue()), *this, Ret, ReturnValueCB,
&I);
};
// Start by discovering returned values from all live returned instructions in
// the associated function.
if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
// Discover returned values from all live returned instructions in the
// associated function.
if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret}))
return indicatePessimisticFixpoint();
// Once returned values "directly" present in the code are handled we try to
// resolve returned calls. To avoid modifications to the ReturnedValues map
// while we iterate over it we kept record of potential new entries in a copy
// map, NewRVsMap.
decltype(ReturnedValues) NewRVsMap;
auto HandleReturnValue = [&](Value *RV,
SmallSetVector<ReturnInst *, 4> &RIs) {
LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *RV << " by #"
<< RIs.size() << " RIs\n");
CallBase *CB = dyn_cast<CallBase>(RV);
if (!CB || UnresolvedCalls.count(CB))
return;
if (!CB->getCalledFunction()) {
LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
<< "\n");
UnresolvedCalls.insert(CB);
return;
}
// TODO: use the function scope once we have call site AAReturnedValues.
const auto &RetValAA = A.getAAFor<AAReturnedValues>(
*this, IRPosition::function(*CB->getCalledFunction()),
DepClassTy::REQUIRED);
LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
<< RetValAA << "\n");
// Skip dead ends, thus if we do not know anything about the returned
// call we mark it as unresolved and it will stay that way.
if (!RetValAA.getState().isValidState()) {
LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
<< "\n");
UnresolvedCalls.insert(CB);
return;
}
// Do not try to learn partial information. If the callee has unresolved
// return values we will treat the call as unresolved/opaque.
auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
if (!RetValAAUnresolvedCalls.empty()) {
UnresolvedCalls.insert(CB);
return;
}
// Now check if we can track transitively returned values. If possible, thus
// if all return value can be represented in the current scope, do so.
bool Unresolved = false;
for (auto &RetValAAIt : RetValAA.returned_values()) {
Value *RetVal = RetValAAIt.first;
if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
isa<Constant>(RetVal))
continue;
// Anything that did not fit in the above categories cannot be resolved,
// mark the call as unresolved.
LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
"cannot be translated: "
<< *RetVal << "\n");
UnresolvedCalls.insert(CB);
Unresolved = true;
break;
}
if (Unresolved)
return;
// Now track transitively returned values.
unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
if (NumRetAA == RetValAA.getNumReturnValues()) {
LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
"changed since it was seen last\n");
return;
}
NumRetAA = RetValAA.getNumReturnValues();
for (auto &RetValAAIt : RetValAA.returned_values()) {
Value *RetVal = RetValAAIt.first;
if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
// Arguments are mapped to call site operands and we begin the traversal
// again.
bool Unused = false;
RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS, CB);
continue;
}
if (isa<CallBase>(RetVal)) {
// Call sites are resolved by the callee attribute over time, no need to
// do anything for us.
continue;
}
if (isa<Constant>(RetVal)) {
// Constants are valid everywhere, we can simply take them.
NewRVsMap[RetVal].insert(RIs.begin(), RIs.end());
continue;
}
}
};
for (auto &It : ReturnedValues)
HandleReturnValue(It.first, It.second);
// Because processing the new information can again lead to new return values
// we have to be careful and iterate until this iteration is complete. The
// idea is that we are in a stable state at the end of an update. All return
// values have been handled and properly categorized. We might not update
// again if we have not requested a non-fix attribute so we cannot "wait" for
// the next update to analyze a new return value.
while (!NewRVsMap.empty()) {
auto It = std::move(NewRVsMap.back());
NewRVsMap.pop_back();
assert(!It.second.empty() && "Entry does not add anything.");
auto &ReturnInsts = ReturnedValues[It.first];
for (ReturnInst *RI : It.second)
if (ReturnInsts.insert(RI)) {
LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
<< *It.first << " => " << *RI << "\n");
HandleReturnValue(It.first, ReturnInsts);
Changed = true;
}
}
Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
return Changed;
}
struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
@ -1943,7 +1745,8 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
// If we reach here, we know we have an instruction
// that accesses memory through a pointer operand,
// for which getPointerOperand() should give it to us.
const Value *PtrOp = getPointerOperand(&I, /* AllowVolatile */ true);
Value *PtrOp =
const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
assert(PtrOp &&
"Expected pointer operand of memory accessing instruction");
@ -1985,7 +1788,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
return true;
// We know we have a branch instruction.
auto BrInst = cast<BranchInst>(&I);
auto *BrInst = cast<BranchInst>(&I);
// Unconditional branches are never considered UB.
if (BrInst->isUnconditional())
@ -2202,27 +2005,27 @@ private:
// action was taken and the caller should stop.
// Otherwise, we return the simplified value that the caller should
// use for specific processing.
Optional<Value *> stopOnUndefOrAssumed(Attributor &A, const Value *V,
Optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
Instruction *I) {
bool UsedAssumedInformation = false;
Optional<Value *> SimplifiedV = A.getAssumedSimplified(
IRPosition::value(*V), *this, UsedAssumedInformation);
if (UsedAssumedInformation) {
if (!UsedAssumedInformation) {
// Don't depend on assumed values.
return llvm::None;
}
if (!SimplifiedV.hasValue()) {
// If it is known (which we tested above) but it doesn't have a value,
// then we can assume `undef` and hence the instruction is UB.
KnownUBInsts.insert(I);
return llvm::None;
}
Value *Val = SimplifiedV.getValue();
if (isa<UndefValue>(Val)) {
if (*SimplifiedV != nullptr)
V = *SimplifiedV;
}
if (isa<UndefValue>(V)) {
KnownUBInsts.insert(I);
return llvm::None;
}
return Val;
return V;
}
};
@ -2821,6 +2624,10 @@ struct AAIsDeadValueImpl : public AAIsDead {
/// Check if all uses are assumed dead.
bool areAllUsesAssumedDead(Attributor &A, Value &V) {
// Callers might not check the type, void has no uses.
if (V.getType()->isVoidTy())
return true;
// If we replace a value with a constant there are no uses left afterwards.
if (!isa<Constant>(V)) {
bool UsedAssumedInformation = false;
@ -4561,7 +4368,7 @@ struct AAValueSimplifyImpl : AAValueSimplify {
const std::string getAsStr() const override {
LLVM_DEBUG({
errs() << "SAV: " << SimplifiedAssociatedValue << " ";
if (SimplifiedAssociatedValue)
if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
errs() << "SAV: " << **SimplifiedAssociatedValue << " ";
});
return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
@ -4573,17 +4380,33 @@ struct AAValueSimplifyImpl : AAValueSimplify {
/// See AAValueSimplify::getAssumedSimplifiedValue()
Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
if (!isValidState())
return const_cast<Value *>(&getAssociatedValue());
return SimplifiedAssociatedValue;
}
/// Return a value we can use as replacement for the associated one, or
/// nullptr if we don't have one that makes sense.
virtual Value *getReplacementValue() const {
Value *NewV;
NewV = SimplifiedAssociatedValue.hasValue()
? SimplifiedAssociatedValue.getValue()
: UndefValue::get(getAssociatedType());
if (!NewV)
return nullptr;
NewV = AA::getWithType(*NewV, *getAssociatedType());
if (!NewV || NewV == &getAssociatedValue() ||
!AA::isValidInScope(*NewV, getAnchorScope()))
return nullptr;
return NewV;
}
/// Helper function for querying AAValueSimplify and updating candicate.
/// \param IRP The value position we are trying to unify with SimplifiedValue
bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
const IRPosition &IRP) {
const IRPosition &IRP, bool Simplify = true) {
bool UsedAssumedInformation = false;
Optional<Value *> QueryingValueSimplified =
Optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
if (Simplify)
QueryingValueSimplified =
A.getAssumedSimplified(IRP, QueryingAA, UsedAssumedInformation);
return unionAssumed(QueryingValueSimplified);
}
@ -4623,36 +4446,23 @@ struct AAValueSimplifyImpl : AAValueSimplify {
/// See AbstractAttribute::manifest(...).
ChangeStatus manifest(Attributor &A) override {
ChangeStatus Changed = ChangeStatus::UNCHANGED;
if (SimplifiedAssociatedValue.hasValue() &&
!SimplifiedAssociatedValue.getValue())
if (getAssociatedValue().user_empty())
return Changed;
Value &V = getAssociatedValue();
auto *C = SimplifiedAssociatedValue.hasValue()
? dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())
: UndefValue::get(V.getType());
if (C && C != &V && !V.user_empty()) {
Value *NewV = AA::getWithType(*C, *V.getType());
// We can replace the AssociatedValue with the constant.
if (NewV && NewV != &V) {
LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *NewV
<< " :: " << *this << "\n");
if (A.changeValueAfterManifest(V, *NewV))
if (auto *NewV = getReplacementValue()) {
LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue() << " -> "
<< *NewV << " :: " << *this << "\n");
if (A.changeValueAfterManifest(getAssociatedValue(), *NewV))
Changed = ChangeStatus::CHANGED;
}
}
return Changed | AAValueSimplify::manifest(A);
}
/// See AbstractState::indicatePessimisticFixpoint(...).
ChangeStatus indicatePessimisticFixpoint() override {
// NOTE: Associated value will be returned in a pessimistic fixpoint and is
// regarded as known. That's why`indicateOptimisticFixpoint` is called.
SimplifiedAssociatedValue = &getAssociatedValue();
indicateOptimisticFixpoint();
return ChangeStatus::CHANGED;
return AAValueSimplify::indicatePessimisticFixpoint();
}
};
@ -4703,14 +4513,27 @@ struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
return false;
// Simplify the argument operand explicitly and check if the result is
// valid in the current scope. This avoids refering to simplified values
// in other functions, e.g., we don't want to say a an argument in a
// static function is actually an argument in a different function.
Value &ArgOp = ACSArgPos.getAssociatedValue();
bool UsedAssumedInformation;
Optional<Value *> SimpleArgOp =
A.getAssumedSimplified(ACSArgPos, *this, UsedAssumedInformation);
if (!SimpleArgOp.hasValue())
return true;
Value *SimpleArgOpVal = *SimpleArgOp ? *SimpleArgOp : &ArgOp;
if (!AA::isValidInScope(*SimpleArgOpVal, getAnchorScope()))
return false;
// We can only propagate thread independent values through callbacks.
// This is different to direct/indirect call sites because for them we
// know the thread executing the caller and callee is the same. For
// callbacks this is not guaranteed, thus a thread dependent value could
// be different for the caller and callee, making it invalid to propagate.
Value &ArgOp = ACSArgPos.getAssociatedValue();
if (ACS.isCallbackCall())
if (auto *C = dyn_cast<Constant>(&ArgOp))
if (auto *C = dyn_cast<Constant>(SimpleArgOpVal))
if (C->isThreadDependent())
return false;
return checkAndUpdate(A, *this, ACSArgPos);
@ -4745,6 +4568,13 @@ struct AAValueSimplifyReturned : AAValueSimplifyImpl {
AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
: AAValueSimplifyImpl(IRP, A) {}
/// See AAValueSimplify::getAssumedSimplifiedValue()
Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
if (!isValidState())
return nullptr;
return SimplifiedAssociatedValue;
}
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
auto Before = SimplifiedAssociatedValue;
@ -4766,36 +4596,25 @@ struct AAValueSimplifyReturned : AAValueSimplifyImpl {
ChangeStatus manifest(Attributor &A) override {
ChangeStatus Changed = ChangeStatus::UNCHANGED;
if (SimplifiedAssociatedValue.hasValue() &&
!SimplifiedAssociatedValue.getValue())
return Changed | AAValueSimplify::manifest(A);
auto *C = SimplifiedAssociatedValue.hasValue()
? dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())
: UndefValue::get(getAssociatedType());
if (!C || C == &getAssociatedValue())
return Changed | AAValueSimplify::manifest(A);
if (auto *NewV = getReplacementValue()) {
auto PredForReturned =
[&](Value &V, const SmallSetVector<ReturnInst *, 4> &RetInsts) {
// We can replace the AssociatedValue with the constant.
if (&V == C || isa<UndefValue>(V))
return true;
[&](Value &, const SmallSetVector<ReturnInst *, 4> &RetInsts) {
for (ReturnInst *RI : RetInsts) {
if (RI->getFunction() != getAnchorScope())
continue;
Value *NewV = AA::getWithType(*C, *RI->getReturnValue()->getType());
if (!NewV)
continue;
LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *NewV
<< " in " << *RI << " :: " << *this << "\n");
Value *ReturnedVal = RI->getReturnValue();
if (ReturnedVal == NewV || isa<UndefValue>(ReturnedVal))
return true;
assert(RI->getFunction() == getAnchorScope() &&
"ReturnInst in wrong function!");
LLVM_DEBUG(dbgs()
<< "[ValueSimplify] " << *ReturnedVal << " -> "
<< *NewV << " in " << *RI << " :: " << *this << "\n");
if (A.changeUseAfterManifest(RI->getOperandUse(0), *NewV))
Changed = ChangeStatus::CHANGED;
}
return true;
};
A.checkForAllReturnedValuesAndReturnInsts(PredForReturned, *this);
}
return Changed | AAValueSimplify::manifest(A);
}
@ -4934,7 +4753,7 @@ struct AAValueSimplifyFunction : AAValueSimplifyImpl {
/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
SimplifiedAssociatedValue = &getAnchorValue();
SimplifiedAssociatedValue = nullptr;
indicateOptimisticFixpoint();
}
/// See AbstractAttribute::initialize(...).
@ -4957,19 +4776,43 @@ struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
}
};
struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
: AAValueSimplifyReturned(IRP, A) {}
: AAValueSimplifyImpl(IRP, A) {}
/// See AbstractAttribute::manifest(...).
ChangeStatus manifest(Attributor &A) override {
return AAValueSimplifyImpl::manifest(A);
void initialize(Attributor &A) override {
if (!getAssociatedFunction())
indicatePessimisticFixpoint();
}
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
auto Before = SimplifiedAssociatedValue;
auto &RetAA = A.getAAFor<AAReturnedValues>(
*this, IRPosition::function(*getAssociatedFunction()),
DepClassTy::REQUIRED);
auto PredForReturned =
[&](Value &RetVal, const SmallSetVector<ReturnInst *, 4> &RetInsts) {
bool UsedAssumedInformation;
Optional<Value *> CSRetVal = A.translateArgumentToCallSiteContent(
&RetVal, *cast<CallBase>(getCtxI()), *this,
UsedAssumedInformation);
SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice(
SimplifiedAssociatedValue, CSRetVal, getAssociatedType());
return SimplifiedAssociatedValue != Optional<Value *>(nullptr);
};
if (!RetAA.checkForAllReturnedValuesAndReturnInsts(PredForReturned))
if (!askSimplifiedValueForOtherAAs(A))
return indicatePessimisticFixpoint();
return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
: ChangeStatus ::CHANGED;
}
void trackStatistics() const override {
STATS_DECLTRACK_CSRET_ATTR(value_simplify)
}
};
struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
: AAValueSimplifyFloating(IRP, A) {}
@ -4978,24 +4821,12 @@ struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
ChangeStatus manifest(Attributor &A) override {
ChangeStatus Changed = ChangeStatus::UNCHANGED;
if (SimplifiedAssociatedValue.hasValue() &&
!SimplifiedAssociatedValue.getValue())
return Changed;
Value &V = getAssociatedValue();
auto *C = SimplifiedAssociatedValue.hasValue()
? dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())
: UndefValue::get(V.getType());
if (C) {
if (auto *NewV = getReplacementValue()) {
Use &U = cast<CallBase>(&getAnchorValue())
->getArgOperandUse(getCallSiteArgNo());
// We can replace the AssociatedValue with the constant.
if (&V != C) {
if (Value *NewV = AA::getWithType(*C, *V.getType()))
if (A.changeUseAfterManifest(U, *NewV))
Changed = ChangeStatus::CHANGED;
}
}
return Changed | AAValueSimplify::manifest(A);
}

View File

@ -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=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 -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

View File

@ -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
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"

View File

@ -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=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

View File

@ -8,37 +8,20 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define i64 @fn2() {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2
; IS__TUNIT_OPM-SAME: () #[[ATTR0:[0-9]+]] {
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #[[ATTR0]]
; IS__TUNIT_OPM-NEXT: ret i64 [[CALL2]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2
; IS__TUNIT_NPM-SAME: () #[[ATTR0:[0-9]+]] {
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #[[ATTR0]], !range [[RNG0:![0-9]+]]
; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2
; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i64 undef
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn2
; IS__CGSCC_OPM-SAME: () #[[ATTR0:[0-9]+]] {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = sext i32 undef to i64
; IS__CGSCC_OPM-NEXT: [[DIV:%.*]] = sdiv i64 8, 0
; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #[[ATTR1:[0-9]+]]
; IS__CGSCC_OPM-NEXT: ret i64 [[CALL2]]
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn2
; IS__CGSCC_NPM-SAME: () #[[ATTR0:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = sext i32 undef to i64
; IS__CGSCC_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, 0
; IS__CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i64 [[CALL2]]
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2
; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CONV:%.*]] = sext i32 undef to i64
; IS__CGSCC____-NEXT: [[DIV:%.*]] = sdiv i64 8, 0
; IS__CGSCC____-NEXT: ret i64 undef
;
entry:
%conv = sext i32 undef to i64
@ -48,32 +31,22 @@ entry:
}
define i64 @fn2b(i32 %arg) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2b
; IS__TUNIT_OPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
; IS__TUNIT_OPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
; IS__TUNIT_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #[[ATTR0]]
; IS__TUNIT_OPM-NEXT: ret i64 [[CALL2]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2b
; IS__TUNIT_NPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
; IS__TUNIT_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #[[ATTR0]], !range [[RNG0]]
; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2b
; IS__TUNIT____-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
; IS__TUNIT____-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
; IS__TUNIT____-NEXT: ret i64 [[DIV]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2b
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
; IS__CGSCC____-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
; IS__CGSCC____-NEXT: ret i64 [[CALL2]]
; IS__CGSCC____-NEXT: ret i64 [[DIV]]
;
entry:
%conv = sext i32 %arg to i64
@ -83,35 +56,23 @@ entry:
}
define i64 @fn2c() {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2c
; IS__TUNIT_OPM-SAME: () #[[ATTR0]] {
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 noundef 42) #[[ATTR0]]
; IS__TUNIT_OPM-NEXT: ret i64 [[CALL2]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2c
; IS__TUNIT_NPM-SAME: () #[[ATTR0]] {
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 noundef 42) #[[ATTR0]], !range [[RNG0]]
; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2c
; IS__TUNIT____-SAME: () #[[ATTR0]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i64 42
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn2c
; IS__CGSCC_OPM-SAME: () #[[ATTR0]] {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = sext i32 undef to i64
; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i64 42, 0
; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 noundef 42) #[[ATTR1]]
; IS__CGSCC_OPM-NEXT: ret i64 [[CALL2]]
; IS__CGSCC_OPM-NEXT: ret i64 42
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn2c
; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = sext i32 undef to i64
; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add i64 42, 0
; IS__CGSCC_NPM-NEXT: ret i64 42
;
entry:
@ -122,21 +83,11 @@ entry:
}
define internal i64 @fn1(i64 %p1) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn1
; IS__TUNIT____-SAME: (i64 returned [[P1:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0
; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]]
; IS__TUNIT____-NEXT: ret i64 [[COND]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1
; IS__CGSCC____-SAME: (i64 returned [[P1:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-SAME: (i64 [[P1:%.*]]) #[[ATTR0]] {
; 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 undef
;
entry:
%tobool = icmp ne i64 %p1, 0
@ -147,9 +98,4 @@ entry:
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
;.
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn }
;.
; IS__TUNIT_NPM: [[RNG0]] = !{i64 -2147483606, i64 2147483690}
;.
; IS__CGSCC____: [[RNG0]] = !{i64 -8, i64 43}
;.

View File

@ -18,8 +18,7 @@ define void @fn2(i32* %P, i1 %C) {
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]]) #[[ATTR3:[0-9]+]]
; IS__TUNIT____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
; IS__TUNIT____-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
; IS__TUNIT____-NEXT: br label [[FOR_COND1]]
; IS__TUNIT____: exit:
; IS__TUNIT____-NEXT: ret void
@ -34,8 +33,7 @@ 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: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]])
; IS__CGSCC____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
; IS__CGSCC____-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
; IS__CGSCC____-NEXT: br label [[FOR_COND1]]
; IS__CGSCC____: exit:
; IS__CGSCC____-NEXT: ret void
@ -57,21 +55,11 @@ exit:
}
define internal i32 @fn1(i32 %p1) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn1
; IS__TUNIT____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
; IS__TUNIT____-NEXT: ret i32 [[COND]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1
; IS__CGSCC____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__CGSCC____-SAME: (i32 [[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 undef
;
entry:
%tobool = icmp ne i32 %p1, 0
@ -83,7 +71,7 @@ define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid {
;
; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn_no_null_opt
; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: br label [[IF_END:%.*]]
; IS__TUNIT____: for.cond1:
@ -91,8 +79,7 @@ define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid {
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) #[[ATTR3]]
; IS__TUNIT____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
; IS__TUNIT____-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
; IS__TUNIT____-NEXT: br label [[FOR_COND1]]
; IS__TUNIT____: exit:
; IS__TUNIT____-NEXT: ret void
@ -107,8 +94,7 @@ 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 4
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
; IS__CGSCC____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
; IS__CGSCC____-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
; IS__CGSCC____-NEXT: br label [[FOR_COND1]]
; IS__CGSCC____: exit:
; IS__CGSCC____-NEXT: ret void
@ -130,21 +116,11 @@ exit:
}
define internal i32 @fn0(i32 %p1) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn0
; IS__TUNIT____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
; IS__TUNIT____-NEXT: ret i32 [[COND]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn0
; IS__CGSCC____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-SAME: (i32 [[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 undef
;
entry:
%tobool = icmp ne i32 %p1, 0
@ -153,9 +129,7 @@ entry:
}
;.
; IS__TUNIT____: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind }
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind null_pointer_is_valid }
; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind readnone }
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind null_pointer_is_valid }
;.
; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind }
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }

View File

@ -118,8 +118,8 @@ define dso_local i16 @vararg_tests(i16 %a) {
define internal i16 @vararg_prop(i16 %p1, ...) {
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_prop
; IS__CGSCC____-SAME: (i16 returned [[P1:%.*]], ...) #[[ATTR0]] {
; IS__CGSCC____-NEXT: ret i16 7
; IS__CGSCC____-SAME: (i16 [[P1:%.*]], ...) #[[ATTR0]] {
; IS__CGSCC____-NEXT: ret i16 undef
;
ret i16 %p1
}
@ -127,12 +127,12 @@ define internal i16 @vararg_prop(i16 %p1, ...) {
define internal i16 @vararg_no_prop(i16 %p1, i16 %p2, ...) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@vararg_no_prop
; IS__TUNIT____-SAME: (i16 returned [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
; IS__TUNIT____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
; IS__TUNIT____-NEXT: ret i16 7
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_no_prop
; IS__CGSCC____-SAME: (i16 returned [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
; IS__CGSCC____-NEXT: ret i16 7
;
ret i16 %p1

View File

@ -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=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-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
;
@ -42,13 +42,13 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define internal i32 @cb0(i32 %zero) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@cb0
; IS__TUNIT____-SAME: (i32 returned [[ZERO:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-SAME: (i32 [[ZERO:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i32 0
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@cb0
; IS__CGSCC____-SAME: (i32 returned [[ZERO:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-SAME: (i32 [[ZERO:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i32 0
;

View File

@ -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=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
; PR36485
@ -10,37 +10,69 @@ declare i32 @external()
define i8* @start(i8 %v) {
;
; 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 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 i8* @dont_zap_me(i8 undef)
; IS__TUNIT____-NEXT: ret i8* [[CA2]]
; 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__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 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: ret i8* undef
; IS__CGSCC____: c2_false:
; IS__CGSCC____-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
; IS__CGSCC____-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 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: ret i8* undef
; IS__CGSCC_OPM: c2_false:
; IS__CGSCC_OPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
; IS__CGSCC_OPM-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 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: ret i8* undef
; IS__CGSCC_NPM: c2_false:
; IS__CGSCC_NPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
; IS__CGSCC_NPM-NEXT: ret i8* [[CA2]]
;
%c1 = icmp eq i8 %v, 0
br i1 %c1, label %true, label %false
@ -60,11 +92,17 @@ c2_false:
}
define internal i8* @side_effects(i8 %v) {
; CHECK-LABEL: define {{[^@]+}}@side_effects
; CHECK-SAME: (i8 [[V:%.*]]) {
; CHECK-NEXT: [[I1:%.*]] = call i32 @external()
; CHECK-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]])
; CHECK-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 i8* @start(i8 [[V]])
; IS________OPM-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 i8* @start(i8 noundef 0)
; IS________NPM-NEXT: ret i8* [[CA]]
;
%i1 = call i32 @external()

View File

@ -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=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 -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
;

View File

@ -40,7 +40,7 @@ define dso_local i32 @main() {
; IS__TUNIT____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
; IS__TUNIT____-NEXT: [[THREAD:%.*]] = alloca i64, align 8
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree readnone align 536870912 undef)
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" undef)
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) undef)
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]])
; IS__TUNIT____-NEXT: ret i32 0
@ -51,7 +51,7 @@ define dso_local i32 @main() {
; IS__CGSCC____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
; IS__CGSCC____-NEXT: [[THREAD:%.*]] = alloca i64, align 8
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree noundef readnone align 536870912 null)
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]])
; IS__CGSCC____-NEXT: ret i32 0
@ -72,13 +72,13 @@ declare !callback !0 dso_local i32 @pthread_create(i64*, %union.pthread_attr_t*,
define internal i8* @foo(i8* %arg) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
; IS__TUNIT____-SAME: (i8* noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree readnone align 536870912 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i8* null
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
; IS__CGSCC____-SAME: (i8* noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-SAME: (i8* noalias nocapture nofree readnone align 536870912 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i8* null
;
@ -89,13 +89,13 @@ entry:
define internal i8* @bar(i8* %arg) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@bar
; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
; IS__CGSCC____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
;

View File

@ -22,17 +22,17 @@ define internal i32* @incdec(i1 %C, i32* %V) {
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@incdec
; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4
; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC____: T:
; IS__CGSCC____-NEXT: [[X1:%.*]] = add i32 [[X]], 1
; IS__CGSCC____-NEXT: store i32 [[X1]], i32* [[V]], align 4
; IS__CGSCC____-NEXT: ret i32* [[V]]
; IS__CGSCC____-NEXT: ret i32* undef
; IS__CGSCC____: F:
; IS__CGSCC____-NEXT: [[X2:%.*]] = sub i32 [[X]], 1
; IS__CGSCC____-NEXT: store i32 [[X2]], i32* [[V]], align 4
; IS__CGSCC____-NEXT: ret i32* [[V]]
; IS__CGSCC____-NEXT: ret i32* undef
;
%X = load i32, i32* %V
br i1 %C, label %T, label %F
@ -86,7 +86,7 @@ define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
; 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* [[W]], align 4
; IS__TUNIT____-NEXT: store i32 [[Z]], i32* [[Q]], align 4
; IS__TUNIT____-NEXT: br label [[RET:%.*]]
; IS__TUNIT____: LPAD:
; IS__TUNIT____-NEXT: unreachable
@ -97,7 +97,7 @@ define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] 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* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
; IS__CGSCC____-NEXT: [[W:%.*]] = call i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
; IS__CGSCC____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR3:[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) #[[ATTR4:[0-9]+]]
@ -105,7 +105,7 @@ define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
; 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: store i32 [[Z]], i32* [[Q]], align 4
; IS__CGSCC____-NEXT: br label [[RET:%.*]]
; IS__CGSCC____: LPAD:
; IS__CGSCC____-NEXT: unreachable

View File

@ -157,23 +157,14 @@ define i32* @test6_2() #0 {
; Function Attrs: nounwind readnone ssp uwtable
define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@f1
; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
; IS__TUNIT____-NEXT: br label [[TMP3:%.*]]
; IS__TUNIT____: 2:
; IS__TUNIT____-NEXT: unreachable
; IS__TUNIT____: 3:
; IS__TUNIT____-NEXT: ret i8* [[TMP0]]
;
; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1
; IS__CGSCC_OPM-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]]
; IS__CGSCC_OPM: 2:
; IS__CGSCC_OPM-NEXT: unreachable
; IS__CGSCC_OPM: 3:
; IS__CGSCC_OPM-NEXT: ret i8* @a1
; IS__CGSCC_OPM-NEXT: ret i8* undef
;
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1
@ -204,24 +195,22 @@ define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
; IS__CGSCC_OPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
; IS__CGSCC_OPM-NEXT: br label [[TMP2:%.*]]
; IS__CGSCC_OPM: 2:
; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nonnull readnone align 536870912 dereferenceable(4294967295) undef)
; IS__CGSCC_OPM-NEXT: br label [[TMP5:%.*]]
; IS__CGSCC_OPM: 4:
; IS__CGSCC_OPM-NEXT: br label [[TMP4:%.*]]
; IS__CGSCC_OPM: 3:
; IS__CGSCC_OPM-NEXT: unreachable
; IS__CGSCC_OPM: 5:
; IS__CGSCC_OPM-NEXT: ret i8* [[TMP3]]
; IS__CGSCC_OPM: 4:
; IS__CGSCC_OPM-NEXT: ret i8* undef
;
; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2
; IS__CGSCC_NPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: br label [[TMP2:%.*]]
; IS__CGSCC_NPM: 2:
; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = tail call i8* @f1()
; IS__CGSCC_NPM-NEXT: br label [[TMP5:%.*]]
; IS__CGSCC_NPM: 4:
; IS__CGSCC_NPM-NEXT: br label [[TMP4:%.*]]
; IS__CGSCC_NPM: 3:
; IS__CGSCC_NPM-NEXT: unreachable
; IS__CGSCC_NPM: 5:
; IS__CGSCC_NPM-NEXT: ret i8* @a1
; IS__CGSCC_NPM: 4:
; IS__CGSCC_NPM-NEXT: ret i8* undef
;
%2 = icmp eq i8* %0, null
br i1 %2, label %5, label %3
@ -278,8 +267,7 @@ define align 4 i8* @test7() #0 {
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test7
; IS__TUNIT____-SAME: () #[[ATTR0]] {
; IS__TUNIT____-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) #[[ATTR9:[0-9]+]]
; IS__TUNIT____-NEXT: ret i8* [[C]]
; IS__TUNIT____-NEXT: ret i8* @a1
;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test7
@ -295,12 +283,12 @@ define align 4 i8* @test7() #0 {
define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1b
; IS__CGSCC_OPM-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]]
; IS__CGSCC_OPM: 2:
; IS__CGSCC_OPM-NEXT: unreachable
; IS__CGSCC_OPM: 3:
; IS__CGSCC_OPM-NEXT: ret i8* @a1
; IS__CGSCC_OPM-NEXT: ret i8* undef
;
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1b
@ -333,24 +321,22 @@ define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
; IS__CGSCC_OPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3]] {
; IS__CGSCC_OPM-NEXT: br label [[TMP2:%.*]]
; IS__CGSCC_OPM: 2:
; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nonnull readnone align 536870912 dereferenceable(4294967295) undef)
; IS__CGSCC_OPM-NEXT: br label [[TMP5:%.*]]
; IS__CGSCC_OPM: 4:
; IS__CGSCC_OPM-NEXT: br label [[TMP4:%.*]]
; IS__CGSCC_OPM: 3:
; IS__CGSCC_OPM-NEXT: unreachable
; IS__CGSCC_OPM: 5:
; IS__CGSCC_OPM-NEXT: ret i8* [[TMP3]]
; IS__CGSCC_OPM: 4:
; IS__CGSCC_OPM-NEXT: ret i8* undef
;
; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2b
; IS__CGSCC_NPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
; IS__CGSCC_NPM-NEXT: br label [[TMP2:%.*]]
; IS__CGSCC_NPM: 2:
; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = tail call i8* @f1b()
; IS__CGSCC_NPM-NEXT: br label [[TMP5:%.*]]
; IS__CGSCC_NPM: 4:
; IS__CGSCC_NPM-NEXT: br label [[TMP4:%.*]]
; IS__CGSCC_NPM: 3:
; IS__CGSCC_NPM-NEXT: unreachable
; IS__CGSCC_NPM: 5:
; IS__CGSCC_NPM-NEXT: ret i8* @a1
; IS__CGSCC_NPM: 4:
; IS__CGSCC_NPM-NEXT: ret i8* undef
;
%2 = icmp eq i8* %0, null
br i1 %2, label %5, label %3
@ -1104,7 +1090,7 @@ end:
define i64 @ptr2int(i32* %p) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr2int
; IS__TUNIT____-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9]] {
; IS__TUNIT____-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9:[0-9]+]] {
; IS__TUNIT____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
; IS__TUNIT____-NEXT: ret i64 [[P2I]]
;

View File

@ -68,10 +68,10 @@ define i32 @test(i32 %0, i32 %1) #0 {
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
; CHECK: 4:
; CHECK-NEXT: [[TMP5:%.*]] = call i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
; CHECK-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
; CHECK-NEXT: br label [[TMP8:%.*]]
; CHECK: 6:
; CHECK-NEXT: [[TMP7:%.*]] = call i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]]
; CHECK-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]]
; CHECK-NEXT: br label [[TMP8]]
; CHECK: 8:
; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ]

View File

@ -68,10 +68,10 @@ define i32 @test(i32 %0, i32 %1) #0 {
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
; CHECK: 4:
; CHECK-NEXT: [[TMP5:%.*]] = call i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
; CHECK-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
; CHECK-NEXT: br label [[TMP8:%.*]]
; CHECK: 6:
; CHECK-NEXT: [[TMP7:%.*]] = call i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]]
; CHECK-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]]
; CHECK-NEXT: br label [[TMP8]]
; CHECK: 8:
; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ]
@ -94,16 +94,12 @@ define i32 @test(i32 %0, i32 %1) #0 {
}
define i32 @test_pcheck1(i32 %0) #0 {
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_pcheck1
; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: ret i32 1
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_pcheck1
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2:![0-9]+]]
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101
; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; IS__CGSCC____-NEXT: ret i32 [[TMP4]]
; CHECK-LABEL: define {{[^@]+}}@test_pcheck1
; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2:![0-9]+]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101
; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; CHECK-NEXT: ret i32 [[TMP4]]
;
; IS__TUNIT_____ENABLED-LABEL: define {{[^@]+}}@test_pcheck1
; IS__TUNIT_____ENABLED-SAME: (i32 [[TMP0:%.*]])
@ -115,16 +111,12 @@ define i32 @test_pcheck1(i32 %0) #0 {
}
define i32 @test_pcheck2(i32 %0) #0 {
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_pcheck2
; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: ret i32 1
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_pcheck2
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]]
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99
; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; IS__CGSCC____-NEXT: ret i32 [[TMP4]]
; CHECK-LABEL: define {{[^@]+}}@test_pcheck2
; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99
; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; CHECK-NEXT: ret i32 [[TMP4]]
;
%2 = call i32 @test(i32 %0, i32 0)
%3 = icmp sgt i32 %2, 99
@ -133,19 +125,12 @@ define i32 @test_pcheck2(i32 %0) #0 {
}
define i32 @test_ncheck1(i32 %0) #0 {
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_ncheck1
; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG0]]
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50
; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; IS__TUNIT____-NEXT: ret i32 [[TMP4]]
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_ncheck1
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2]]
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50
; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; IS__CGSCC____-NEXT: ret i32 [[TMP4]]
; CHECK-LABEL: define {{[^@]+}}@test_ncheck1
; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50
; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; CHECK-NEXT: ret i32 [[TMP4]]
;
%2 = call i32 @test(i32 %0, i32 1)
%3 = icmp sgt i32 %2, 50
@ -154,19 +139,12 @@ define i32 @test_ncheck1(i32 %0) #0 {
}
define i32 @test_ncheck2(i32 %0) #0 {
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_ncheck2
; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG1]]
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150
; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; IS__TUNIT____-NEXT: ret i32 [[TMP4]]
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_ncheck2
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]]
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150
; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; IS__CGSCC____-NEXT: ret i32 [[TMP4]]
; CHECK-LABEL: define {{[^@]+}}@test_ncheck2
; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150
; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
; CHECK-NEXT: ret i32 [[TMP4]]
;
%2 = call i32 @test(i32 %0, i32 0)
%3 = icmp sgt i32 %2, 150
@ -185,10 +163,7 @@ attributes #0 = { noinline nounwind sspstrong uwtable}
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone sspstrong uwtable willreturn }
; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn }
;.
; IS__TUNIT____: [[RNG0]] = !{i32 0, i32 101}
; IS__TUNIT____: [[RNG1]] = !{i32 100, i32 201}
;.
; IS__CGSCC____: [[RNG0]] = !{i32 0, i32 101}
; IS__CGSCC____: [[RNG1]] = !{i32 100, i32 201}
; IS__CGSCC____: [[RNG2]] = !{i32 0, i32 201}
; CHECK: [[RNG0]] = !{i32 0, i32 101}
; CHECK: [[RNG1]] = !{i32 100, i32 201}
; CHECK: [[RNG2]] = !{i32 0, i32 201}
;.

View File

@ -64,19 +64,9 @@ define i32 @test2(i32 %unknown, i32 %b) {
; we need to look into this again. For the purpose of making some progress we take this regression
; for now, call site contexts are not on by default anyway (yet).
define i32 @test1_pcheck(i32 %unknown) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_pcheck
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG1:![0-9]+]]
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_pcheck
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1:![0-9]+]]
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]
; CHECK-LABEL: define {{[^@]+}}@test1_pcheck
; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret i32 1
;
%1 = call i32 @test1(i32 %unknown, i32 20)
%2 = icmp sle i32 %1, 90
@ -85,19 +75,9 @@ define i32 @test1_pcheck(i32 %unknown) {
}
define i32 @test2_pcheck(i32 %unknown) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_pcheck
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG2:![0-9]+]]
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_pcheck
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG2:![0-9]+]]
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]
; CHECK-LABEL: define {{[^@]+}}@test2_pcheck
; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret i32 1
;
%1 = call i32 @test2(i32 %unknown, i32 20)
%2 = icmp sge i32 %1, 20
@ -110,14 +90,14 @@ define i32 @test2_pcheck(i32 %unknown) {
define i32 @test1_ncheck(i32 %unknown) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_ncheck
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG1]]
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG1:![0-9]+]]
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_ncheck
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1]]
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1:![0-9]+]]
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]
@ -131,14 +111,14 @@ define i32 @test1_ncheck(i32 %unknown) {
define i32 @test2_ncheck(i32 %unknown) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_ncheck
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG2]]
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG2:![0-9]+]]
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_ncheck
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG2]]
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG2:![0-9]+]]
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]

View File

@ -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=13 -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=13 -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=12 -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=12 -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

View File

@ -53,29 +53,30 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH: [AAIsDead] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state Live[#BB 4/4][#TBEP 0][#KDE 1]
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state simplified
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state not-simple
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAWillReturn] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-noreturn
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAUndefinedBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state undefined-behavior
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state simplified
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state not-simple
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIsDead] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state assumed-live
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoUndef] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state may-undef-or-poison
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAReturnedValues] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state returns(#3)[#UC: 1]
; GRAPH-NEXT: [AAReturnedValues] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state returns(#3)
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoUnwind] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nounwind
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-EMPTY:
@ -85,7 +86,7 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIsDead] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state assumed-live
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state simplified
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state not-simple
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueConstantRange] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state range(32)<full-set / full-set>
; GRAPH-EMPTY:
@ -104,17 +105,18 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-NEXT: [AANoRecurse] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-recurse
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAMemoryLocation] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
@ -123,7 +125,7 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAHeapToStack] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state [H2S] Mallocs Good/Bad: 0/1
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state simplified
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state not-simple
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAAlign] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state align<1-16>
; GRAPH-NEXT: updates [AAAlign] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state align<1-16>
@ -161,6 +163,7 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state readonly
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state readonly
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state nofree
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nofree
@ -171,11 +174,15 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
; GRAPH-NEXT: updates [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state assumed-live
; GRAPH-NEXT: updates [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state assumed-live
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nounwind
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
; GRAPH-NEXT: updates [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state assumed-live
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state readonly
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state not-simple
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed-live
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state simplified
@ -185,6 +192,7 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-NEXT: [AANoCapture] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoAlias] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state may-alias
; GRAPH-EMPTY:
@ -197,7 +205,7 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueConstantRange] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state range(1)<full-set / full-set>
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueSimplify] for CtxI <<null inst>> at position {flt: [@-1]} with state simplified
; GRAPH-NEXT: [AAValueSimplify] for CtxI <<null inst>> at position {flt: [@-1]} with state not-simple
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueConstantRange] for CtxI <<null inst>> at position {flt: [@-1]} with state range(32)<[0,1) / [0,1)>
; GRAPH-EMPTY:
@ -207,14 +215,10 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoReturn] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state may-return
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoAlias] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state may-alias
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state simplified
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state not-simple
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoUndef] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state may-undef-or-poison
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state simplified
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAAlign] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state align<16-16>
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANonNull] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state nonnull
@ -222,14 +226,17 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nonnull
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIsDead] for CtxI ' ret i32* %.0' at position {flt: [@-1]} with state assumed-live
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIsDead] for CtxI ' br label %8' at position {flt: [@-1]} with state assumed-live
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIsDead] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state assumed-live
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIsDead] for CtxI ' br label %8' at position {flt: [@-1]} with state assumed-live
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIsDead] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state assumed-live
; GRAPH-NEXT: [AANoAlias] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state may-alias
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAMemoryLocation] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
; GRAPH-NEXT: updates [AAMemoryLocation] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
@ -238,21 +245,19 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoRecurse] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state may-recurse
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoFree] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nofree
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nofree
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoSync] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nosync
; GRAPH-NEXT: updates [AANoSync] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nosync
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAAlign] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state align<1-16>
; GRAPH-NEXT: updates [AAAlign] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state align<1-16>
; GRAPH-NEXT: [AANoFree] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nofree
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nofree
; GRAPH-EMPTY:
; GRAPH-NEXT: [AADereferenceable] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state unknown-dereferenceable
; GRAPH-NEXT: [AADereferenceable] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state unknown-dereferenceable
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANonNull] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state nonnull
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
; GRAPH-EMPTY:
; GRAPH-NEXT: [AADereferenceable] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state unknown-dereferenceable
; GRAPH-NEXT: [AAAlign] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state align<1-16>
; GRAPH-NEXT: updates [AAAlign] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state align<1-16>
; GRAPH-NOT: update

View File

@ -299,15 +299,13 @@ define void @volatile_is_not_dereferenceable(i16* %ptr) {
; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2
; IS__CGSCC____-NEXT: ret void
;
%arrayidx0 = getelementptr i16, i16* %ptr, i64 0

View File

@ -299,15 +299,13 @@ define void @volatile_is_not_dereferenceable(i16* %ptr) {
; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2
; IS__CGSCC____-NEXT: ret void
;
%arrayidx0 = getelementptr i16, i16* %ptr, i64 0

View File

@ -41,11 +41,9 @@ define void @h2s_value_simplify_interaction(i1 %c, i8* %A) {
; IS________OPM: f:
; IS________OPM-NEXT: br label [[J:%.*]]
; IS________OPM: f2:
; IS________OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M]] to i32*
; IS________OPM-NEXT: [[C2:%.*]] = bitcast i32* [[C1]] to i8*
; IS________OPM-NEXT: [[L:%.*]] = load i8, i8* [[C2]], align 1
; IS________OPM-NEXT: [[L:%.*]] = load i8, i8* [[M]], align 1
; IS________OPM-NEXT: call void @usei8(i8 [[L]])
; IS________OPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef [[C2]]) #[[ATTR5:[0-9]+]]
; IS________OPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef [[M]]) #[[ATTR5:[0-9]+]]
; IS________OPM-NEXT: br label [[J]]
; IS________OPM: dead:
; IS________OPM-NEXT: unreachable
@ -64,11 +62,9 @@ define void @h2s_value_simplify_interaction(i1 %c, i8* %A) {
; IS________NPM: f:
; IS________NPM-NEXT: br label [[J:%.*]]
; IS________NPM: f2:
; IS________NPM-NEXT: [[C1:%.*]] = bitcast i8* [[M]] to i32*
; IS________NPM-NEXT: [[C2:%.*]] = bitcast i32* [[C1]] to i8*
; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[C2]], align 1
; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[M]], align 1
; IS________NPM-NEXT: call void @usei8(i8 [[L]])
; IS________NPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef [[C2]]) #[[ATTR6:[0-9]+]]
; IS________NPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef [[M]]) #[[ATTR6:[0-9]+]]
; IS________NPM-NEXT: br label [[J]]
; IS________NPM: dead:
; IS________NPM-NEXT: unreachable
@ -540,10 +536,9 @@ define i32 @irreducible_cfg(i32 %0) {
; IS________OPM-NEXT: br label [[TMP8]]
; IS________OPM: 15:
; IS________OPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4
; IS________OPM-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP3]] to i8*
; IS________OPM-NEXT: call void @free(i8* nocapture noundef [[TMP17]])
; IS________OPM-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP3]], align 4
; IS________OPM-NEXT: ret i32 [[TMP18]]
; IS________OPM-NEXT: call void @free(i8* nocapture noundef [[TMP2]])
; IS________OPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
; IS________OPM-NEXT: ret i32 [[TMP17]]
;
; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg
; IS________NPM-SAME: (i32 [[TMP0:%.*]]) {
@ -571,9 +566,8 @@ define i32 @irreducible_cfg(i32 %0) {
; IS________NPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1
; IS________NPM-NEXT: br label [[TMP8]]
; IS________NPM: 15:
; IS________NPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8*
; IS________NPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
; IS________NPM-NEXT: ret i32 [[TMP17]]
; IS________NPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4
; IS________NPM-NEXT: ret i32 [[TMP16]]
;
%2 = call noalias i8* @malloc(i64 4)
%3 = bitcast i8* %2 to i32*

View File

@ -404,10 +404,9 @@ define i32 @irreducible_cfg(i32 %0) {
; CHECK-NEXT: br label [[TMP8]]
; CHECK: 15:
; CHECK-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4
; CHECK-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP3]] to i8*
; CHECK-NEXT: call void @free(i8* nocapture noundef [[TMP17]])
; CHECK-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP3]], align 4
; CHECK-NEXT: ret i32 [[TMP18]]
; CHECK-NEXT: call void @free(i8* nocapture noundef [[TMP2]])
; CHECK-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
; CHECK-NEXT: ret i32 [[TMP17]]
;
%2 = call noalias i8* @malloc(i64 4)
%3 = bitcast i8* %2 to i32*

View File

@ -8,8 +8,8 @@
; Deep Wrapper enabled
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=12 -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM,CHECK_ENABLED,NOT_CGSCC_NPM_ENABLED,NOT_CGSCC_OPM_ENABLED,NOT_TUNIT_NPM_ENABLED,IS__TUNIT_____ENABLED,IS________OPM_ENABLED,IS__TUNIT_OPM_ENABLED
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=12 -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM,CHECK_ENABLED,NOT_CGSCC_OPM_ENABLED,NOT_CGSCC_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,IS__TUNIT_____ENABLED,IS________NPM_ENABLED,IS__TUNIT_NPM_ENABLED
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM,CHECK_ENABLED,NOT_CGSCC_NPM_ENABLED,NOT_CGSCC_OPM_ENABLED,NOT_TUNIT_NPM_ENABLED,IS__TUNIT_____ENABLED,IS________OPM_ENABLED,IS__TUNIT_OPM_ENABLED
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM,CHECK_ENABLED,NOT_CGSCC_OPM_ENABLED,NOT_CGSCC_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,IS__TUNIT_____ENABLED,IS________NPM_ENABLED,IS__TUNIT_NPM_ENABLED
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM,CHECK_ENABLED,NOT_TUNIT_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,NOT_CGSCC_NPM_ENABLED,IS__CGSCC_____ENABLED,IS________OPM_ENABLED,IS__CGSCC_OPM_ENABLED
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM,CHECK_ENABLED,NOT_TUNIT_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,NOT_CGSCC_OPM_ENABLED,IS__CGSCC_____ENABLED,IS________NPM_ENABLED,IS__CGSCC_NPM_ENABLED

View File

@ -639,20 +639,20 @@ define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) {
; IS__TUNIT____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1
; IS__TUNIT____-NEXT: ret i8 [[R]]
; IS__TUNIT____: f:
; IS__TUNIT____-NEXT: store i8 1, i8* [[PTR]], align 1
; IS__TUNIT____-NEXT: store i8 1, i8* [[ALLOC]], align 1
; IS__TUNIT____-NEXT: ret i8 0
;
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2
; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
; IS__CGSCC____-SAME: (i8* noalias nocapture nofree nonnull readnone [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR9]] {
; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC____: t:
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal2(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]]
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal2(i8* noalias nocapture nofree nonnull readnone dereferenceable(1) undef, i1 noundef false) #[[ATTR9]]
; IS__CGSCC____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1
; IS__CGSCC____-NEXT: ret i8 [[R]]
; IS__CGSCC____: f:
; IS__CGSCC____-NEXT: store i8 1, i8* [[PTR]], align 1
; IS__CGSCC____-NEXT: store i8 1, i8* [[ALLOC]], align 1
; IS__CGSCC____-NEXT: ret i8 0
;
%alloc = alloca i8
@ -676,7 +676,7 @@ define i8 @readnone_caller2(i1 %c) {
; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone
; IS__CGSCC____-LABEL: define {{[^@]+}}@readnone_caller2
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR9]] {
; IS__CGSCC____-NEXT: [[R:%.*]] = call i8 @recursive_not_readnone_internal2(i8* undef, i1 [[C]]) #[[ATTR12]]
; IS__CGSCC____-NEXT: [[R:%.*]] = call i8 @recursive_not_readnone_internal2(i8* undef, i1 [[C]]) #[[ATTR13:[0-9]+]]
; IS__CGSCC____-NEXT: ret i8 [[R]]
;
%r = call i8 @recursive_not_readnone_internal2(i8* undef, i1 %c)
@ -742,4 +742,5 @@ define void @argmemonky_caller() {
; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind willreturn writeonly }
; IS__CGSCC____: attributes #[[ATTR11]] = { nofree nosync nounwind }
; IS__CGSCC____: attributes #[[ATTR12]] = { nounwind }
; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind readnone }
;.

View File

@ -417,25 +417,21 @@ define void @test12_4(){
; IS________OPM-LABEL: define {{[^@]+}}@test12_4() {
; IS________OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
; IS________OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
; IS________OPM-NEXT: [[A_0:%.*]] = getelementptr i8, i8* [[A]], i64 0
; IS________OPM-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
; IS________OPM-NEXT: [[B_0:%.*]] = getelementptr i8, i8* [[B]], i64 0
; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]])
; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_0]])
; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]])
; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]])
; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A_0]], i8* nocapture [[B_0]])
; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]])
; IS________OPM-NEXT: ret void
;
; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test12_4() {
; NOT_TUNIT_OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
; NOT_TUNIT_OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
; NOT_TUNIT_OPM-NEXT: [[A_0:%.*]] = getelementptr i8, i8* [[A]], i64 0
; NOT_TUNIT_OPM-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
; NOT_TUNIT_OPM-NEXT: [[B_0:%.*]] = getelementptr i8, i8* [[B]], i64 0
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* noalias nocapture [[A]], i8* noalias nocapture [[B]])
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_0]])
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]])
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]])
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A_0]], i8* nocapture [[B_0]])
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]])
; NOT_TUNIT_OPM-NEXT: ret void
;
%A = tail call noalias i8* @malloc(i64 4)
@ -469,9 +465,7 @@ define void @use_i8_internal(i8* %a) {
define void @test13_use_noalias(){
; CHECK-LABEL: define {{[^@]+}}@test13_use_noalias() {
; CHECK-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
; CHECK-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
; CHECK-NEXT: [[C2:%.*]] = bitcast i16* [[C1]] to i8*
; CHECK-NEXT: call void @use_i8_internal(i8* noalias nocapture [[C2]])
; CHECK-NEXT: call void @use_i8_internal(i8* noalias nocapture [[M1]])
; CHECK-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias()
@ -490,11 +484,8 @@ define void @test13_use_noalias(){
define void @test13_use_alias(){
; CHECK-LABEL: define {{[^@]+}}@test13_use_alias() {
; CHECK-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
; CHECK-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
; CHECK-NEXT: [[C2A:%.*]] = bitcast i16* [[C1]] to i8*
; CHECK-NEXT: [[C2B:%.*]] = bitcast i16* [[C1]] to i8*
; CHECK-NEXT: call void @use_i8_internal(i8* nocapture [[C2A]])
; CHECK-NEXT: call void @use_i8_internal(i8* nocapture [[C2B]])
; CHECK-NEXT: call void @use_i8_internal(i8* nocapture [[M1]])
; CHECK-NEXT: call void @use_i8_internal(i8* nocapture [[M1]])
; CHECK-NEXT: ret void
;
%m1 = tail call noalias i8* @malloc(i64 4)

View File

@ -245,27 +245,23 @@ define i32 @nc1(i32* %q, i32* %p, i1 %b) {
; IS__TUNIT____-NEXT: e:
; IS__TUNIT____-NEXT: br label [[L:%.*]]
; IS__TUNIT____: l:
; IS__TUNIT____-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ]
; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
; IS__TUNIT____-NEXT: [[TMP:%.*]] = bitcast i32* [[X]] to i32*
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ]
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Y]]
; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
; IS__TUNIT____-NEXT: store i32 0, i32* [[TMP]], align 4
; IS__TUNIT____-NEXT: store i32 0, i32* [[P]], align 4
; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g, align 8
; IS__TUNIT____-NEXT: ret i32 [[VAL]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@nc1
; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5:[0-9]+]] {
; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree align 4 [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5:[0-9]+]] {
; IS__CGSCC____-NEXT: e:
; IS__CGSCC____-NEXT: br label [[L:%.*]]
; IS__CGSCC____: l:
; IS__CGSCC____-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ]
; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
; IS__CGSCC____-NEXT: [[TMP:%.*]] = bitcast i32* [[X]] to i32*
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ]
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Y]]
; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
; IS__CGSCC____-NEXT: store i32 0, i32* [[TMP]], align 4
; IS__CGSCC____-NEXT: store i32 0, i32* [[P]], align 4
; IS__CGSCC____-NEXT: store i32* [[Y]], i32** @g, align 8
; IS__CGSCC____-NEXT: ret i32 [[VAL]]
;
@ -335,8 +331,8 @@ define void @nc2(i32* %p, i32* %q) {
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@nc2
; IS__CGSCC____-SAME: (i32* nocapture nofree [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR5]] {
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 noundef false) #[[ATTR16:[0-9]+]]
; IS__CGSCC____-SAME: (i32* nocapture nofree align 4 [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR5]] {
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree align 4 [[P]], i1 noundef false) #[[ATTR16:[0-9]+]]
; IS__CGSCC____-NEXT: ret void
;
%1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; <i32> [#uses=0]
@ -826,7 +822,7 @@ define i8* @test_returned1(i8* %A, i8* returned %B) nounwind readonly {
; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* [[A]], i8* [[B]])
; CHECK-NEXT: ret i8* [[P]]
; CHECK-NEXT: ret i8* [[B]]
;
entry:
%p = call i8* @unknownpi8pi8(i8* %A, i8* %B)
@ -839,7 +835,7 @@ define i8* @test_returned2(i8* %A, i8* %B) {
; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* readonly [[A]], i8* readonly [[B]]) #[[ATTR4]]
; CHECK-NEXT: ret i8* [[P]]
; CHECK-NEXT: ret i8* [[B]]
;
entry:
%p = call i8* @unknownpi8pi8(i8* %A, i8* %B) nounwind readonly

View File

@ -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
;
@ -219,9 +219,9 @@ define float* @scc_A(i32* dereferenceable_or_null(4) %a) {
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i16*
; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[CALL]] to double*
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(8) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]]
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i32*
; CHECK-NEXT: [[CALL2:%.*]] = call float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL2]] to i32*
; CHECK-NEXT: br label [[COND_END:%.*]]
; CHECK: cond.false:
@ -254,6 +254,7 @@ cond.end: ; preds = %cond.false, %cond.t
ret float* %4
}
; FIXME: the call1 below to scc_B should return dereferenceable_or_null(8) (as the callee does). Something prevented that deduction and needs to be investigated.
define i64* @scc_B(double* dereferenceable_or_null(8) %a) {
; CHECK: Function Attrs: nofree nosync nounwind readnone
; CHECK-LABEL: define {{[^@]+}}@scc_B
@ -265,9 +266,9 @@ define i64* @scc_B(double* dereferenceable_or_null(8) %a) {
; CHECK-NEXT: [[TMP0:%.*]] = bitcast double* [[A]] to i32*
; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[CALL]] to double*
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(8) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]]
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i16*
; CHECK-NEXT: [[CALL2:%.*]] = call i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
; CHECK-NEXT: br label [[COND_END:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP3:%.*]] = bitcast double* [[A]] to i8*
@ -312,7 +313,7 @@ define i8* @scc_C(i16* dereferenceable_or_null(2) %a) {
; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[A]] to double*
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(8) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64* [[CALL1]] to i8*
; CHECK-NEXT: br label [[COND_END:%.*]]
; CHECK: cond.false:
@ -321,7 +322,7 @@ define i8* @scc_C(i16* dereferenceable_or_null(2) %a) {
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i8* [ [[TMP1]], [[COND_TRUE]] ], [ [[CALL2]], [[COND_FALSE]] ]
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[COND]] to i32*
; CHECK-NEXT: [[CALL3:%.*]] = call float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL3:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL3]] to i8*
; CHECK-NEXT: ret i8* [[TMP3]]
;
@ -497,14 +498,14 @@ define i64* @negative_test_not_captured_but_returned_call_0a(i64* %a) #0 {
; IS__TUNIT____-SAME: (i64* nofree returned writeonly align 8 "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
; IS__TUNIT____-NEXT: ret i64* [[CALL]]
; IS__TUNIT____-NEXT: ret i64* [[A]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a
; IS__CGSCC____-SAME: (i64* nofree noundef nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
; IS__CGSCC____-NEXT: ret i64* [[CALL]]
; IS__CGSCC____-NEXT: ret i64* [[A]]
;
entry:
%call = call i64* @not_captured_but_returned_0(i64* %a)
@ -524,7 +525,7 @@ define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 [[A:%.*]]) #[[ATTR4]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[A]] to i64
; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8
; IS__TUNIT____-NEXT: ret void
;
@ -533,7 +534,7 @@ define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[A]] to i64
; IS__CGSCC____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8
; IS__CGSCC____-NEXT: ret void
;
@ -701,7 +702,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either1(i32* %b, i32* re
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]]
; CHECK-NEXT: ret i32* [[CALL]]
; CHECK-NEXT: ret i32* [[R]]
;
entry:
%call = call i32* @readonly_unknown(i32* %b, i32* %r) nounwind
@ -715,7 +716,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either2(i32* %b, i32* %r
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]]
; CHECK-NEXT: ret i32* [[CALL]]
; CHECK-NEXT: ret i32* [[R]]
;
entry:
%call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r) nounwind
@ -729,7 +730,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either3(i32* %b, i32* %r
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR8]]
; CHECK-NEXT: ret i32* [[CALL]]
; CHECK-NEXT: ret i32* [[R]]
;
entry:
%call = call i32* @readonly_unknown_r1b(i32* %b, i32* %r)
@ -742,7 +743,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either4(i32* %b, i32* %r
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR6]]
; CHECK-NEXT: ret i32* [[CALL]]
; CHECK-NEXT: ret i32* [[R]]
;
entry:
%call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r)

View File

@ -276,7 +276,7 @@ define i8* @test6b(i1 %c) {
; CHECK-NEXT: [[PHI:%.*]] = phi i8* [ [[RET]], [[ENTRY:%.*]] ], [ [[PHI]], [[LOOP]] ]
; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret i8* [[PHI]]
; CHECK-NEXT: ret i8* [[RET]]
;
entry:
%ret = call i8* @ret_nonnull()
@ -292,14 +292,12 @@ define i8* @test7(i8* %a) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test7
; IS__TUNIT____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 0
; IS__TUNIT____-NEXT: ret i8* [[B]]
; IS__TUNIT____-NEXT: ret i8* [[A]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test7
; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 0
; IS__CGSCC____-NEXT: ret i8* [[B]]
; IS__CGSCC____-NEXT: ret i8* [[A]]
;
%b = getelementptr inbounds i8, i8* %a, i64 0
ret i8* %b

View File

@ -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 -enable-new-pm=0 -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=24 -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=24 -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 -enable-new-pm=0 -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=23 -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=23 -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 -enable-new-pm=0 -attributor-cgscc -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
;
@ -568,25 +568,15 @@ f:
; FIXME: returned value can be simplified to 0
define i32 @potential_test11(i1 %c) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test11
; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
; IS__TUNIT_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR0]]
; IS__TUNIT_OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
; IS__TUNIT_OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
; IS__TUNIT_OPM-NEXT: ret i32 [[ACC2]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test11
; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
; IS__TUNIT_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]]
; IS__TUNIT_NPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR0]], !range [[RNG2]]
; IS__TUNIT_NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
; IS__TUNIT_NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
; IS__TUNIT_NPM-NEXT: ret i32 [[ACC2]]
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test11
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]]
; IS__TUNIT____-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]]
; IS__TUNIT____-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR0]], !range [[RNG2]]
; IS__TUNIT____-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
; IS__TUNIT____-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
; IS__TUNIT____-NEXT: ret i32 [[ACC2]]
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test11
@ -633,7 +623,7 @@ define i32 @optimize_poison_1(i1 %c) {
; IS__TUNIT_NPM: t:
; IS__TUNIT_NPM-NEXT: ret i32 0
; IS__TUNIT_NPM: f:
; IS__TUNIT_NPM-NEXT: ret i32 0
; IS__TUNIT_NPM-NEXT: ret i32 undef
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@optimize_poison_1
@ -651,7 +641,7 @@ define i32 @optimize_poison_1(i1 %c) {
; IS__CGSCC_NPM: t:
; IS__CGSCC_NPM-NEXT: ret i32 0
; IS__CGSCC_NPM: f:
; IS__CGSCC_NPM-NEXT: ret i32 0
; IS__CGSCC_NPM-NEXT: ret i32 undef
;
br i1 %c, label %t, label %f
t:
@ -677,7 +667,7 @@ define i32 @potential_test12(i1 %c) {
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test12
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
; IS__CGSCC_OPM-NEXT: [[ZERO:%.*]] = call i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]], !range [[RNG3]]
; IS__CGSCC_OPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]], !range [[RNG3]]
; IS__CGSCC_OPM-NEXT: ret i32 [[ZERO]]
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
@ -715,7 +705,7 @@ define i32 @potential_test13_caller1() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test13_caller1
; IS__TUNIT____-SAME: () #[[ATTR0]] {
; IS__TUNIT____-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR0]], !range [[RNG2:![0-9]+]]
; IS__TUNIT____-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR0]], !range [[RNG2]]
; IS__TUNIT____-NEXT: ret i32 [[RET]]
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn

View File

@ -801,12 +801,12 @@ entry:
define dso_local i32 @test-5() {
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test-5() {
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 noundef 0), !range [[RNG3:![0-9]+]]
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0), !range [[RNG3:![0-9]+]]
; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]]
;
; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test-5() {
; NOT_TUNIT_OPM-NEXT: entry:
; NOT_TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 noundef 0), !range [[RNG4:![0-9]+]]
; NOT_TUNIT_OPM-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0), !range [[RNG4:![0-9]+]]
; NOT_TUNIT_OPM-NEXT: ret i32 [[CALL]]
;
entry:
@ -1462,10 +1462,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT_OPM: t:
; IS__TUNIT_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR1]], !range [[RNG3]]
; IS__TUNIT_OPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR1]], !range [[RNG3]]
; IS__TUNIT_OPM-NEXT: ret i32 [[RET1]]
; IS__TUNIT_OPM: f:
; IS__TUNIT_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR1]], !range [[RNG3]]
; IS__TUNIT_OPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR1]], !range [[RNG3]]
; IS__TUNIT_OPM-NEXT: ret i32 [[RET2]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
@ -1474,10 +1474,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT_NPM: t:
; IS__TUNIT_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef true) #[[ATTR1]], !range [[RNG4]]
; IS__TUNIT_NPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef true) #[[ATTR1]], !range [[RNG4]]
; IS__TUNIT_NPM-NEXT: ret i32 [[RET1]]
; IS__TUNIT_NPM: f:
; IS__TUNIT_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR1]], !range [[RNG4]]
; IS__TUNIT_NPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR1]], !range [[RNG4]]
; IS__TUNIT_NPM-NEXT: ret i32 [[RET2]]
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
@ -1486,10 +1486,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC_OPM: t:
; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR5]], !range [[RNG4]]
; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR5]], !range [[RNG4]]
; IS__CGSCC_OPM-NEXT: ret i32 [[RET1]]
; IS__CGSCC_OPM: f:
; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR5]], !range [[RNG4]]
; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR5]], !range [[RNG4]]
; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]]
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
@ -1498,10 +1498,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC_NPM: t:
; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef true) #[[ATTR3]], !range [[RNG4]]
; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef true) #[[ATTR3]], !range [[RNG4]]
; IS__CGSCC_NPM-NEXT: ret i32 [[RET1]]
; IS__CGSCC_NPM: f:
; IS__CGSCC_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR3]], !range [[RNG4]]
; IS__CGSCC_NPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR3]], !range [[RNG4]]
; IS__CGSCC_NPM-NEXT: ret i32 [[RET2]]
;
%c = select i1 %d, i1 true, i1 false
@ -1515,23 +1515,38 @@ f:
}
define internal i32 @less_than_65536(i32 %arg) {
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_65536
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: [[SHRINKED:%.*]] = udiv i32 undef, 65536
; IS__CGSCC____-NEXT: ret i32 undef
;
%shrinked = udiv i32 %arg, 65536
ret i32 %shrinked
}
define internal i1 @is_less_than_65536(i32 %arg) {
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_65536
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp ult i32 undef, 65536
; IS__CGSCC____-NEXT: ret i1 undef
;
%cmp = icmp ult i32 %arg, 65536
ret i1 %cmp
}
define i1 @check_divided_range(i32 %arg) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@check_divided_range
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@check_divided_range
; IS__CGSCC_NPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {
; IS__CGSCC_NPM-NEXT: ret i1 true
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@check_divided_range
; IS__TUNIT____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: ret i1 true
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@check_divided_range
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: ret i1 true
;
%csret1 = call i32 @less_than_65536(i32 0)
%csret2 = call i32 @less_than_65536(i32 %arg)
@ -1542,23 +1557,32 @@ define i1 @check_divided_range(i32 %arg) {
}
define internal i32 @cast_and_return(i1 %c) {
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@cast_and_return
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 undef to i32
; IS__CGSCC____-NEXT: ret i32 undef
;
%ret = zext i1 %c to i32
ret i32 %ret
}
define internal i1 @is_less_than_3(i32 %c) {
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_3
; IS__CGSCC____-SAME: () #[[ATTR1]] {
; IS__CGSCC____-NEXT: ret i1 undef
;
%cmp = icmp slt i32 %c, 3
ret i1 %cmp
}
define i1 @check_casted_range(i1 %c) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@check_casted_range
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@check_casted_range
; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
; IS__TUNIT_NPM-NEXT: ret i1 true
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@check_casted_range
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: ret i1 true
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@check_casted_range
@ -1654,6 +1678,35 @@ define i1 @propagate_range1(i32 %c){
}
define internal i32 @less_than_100_2(i32 %c) {
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_100_2
; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [
; IS__CGSCC____-NEXT: i32 0, label [[ONZERO:%.*]]
; IS__CGSCC____-NEXT: i32 1, label [[ONONE:%.*]]
; IS__CGSCC____-NEXT: i32 2, label [[ONTWO:%.*]]
; IS__CGSCC____-NEXT: i32 3, label [[ONTHREE:%.*]]
; IS__CGSCC____-NEXT: i32 4, label [[ONFOUR:%.*]]
; IS__CGSCC____-NEXT: i32 5, label [[ONFIVE:%.*]]
; IS__CGSCC____-NEXT: i32 6, label [[ONSIX:%.*]]
; IS__CGSCC____-NEXT: ]
; IS__CGSCC____: onzero:
; IS__CGSCC____-NEXT: ret i32 undef
; IS__CGSCC____: onone:
; IS__CGSCC____-NEXT: ret i32 undef
; IS__CGSCC____: ontwo:
; IS__CGSCC____-NEXT: ret i32 undef
; IS__CGSCC____: onthree:
; IS__CGSCC____-NEXT: ret i32 undef
; IS__CGSCC____: onfour:
; IS__CGSCC____-NEXT: ret i32 undef
; IS__CGSCC____: onfive:
; IS__CGSCC____-NEXT: ret i32 undef
; IS__CGSCC____: onsix:
; IS__CGSCC____-NEXT: ret i32 undef
; IS__CGSCC____: otherwise:
; IS__CGSCC____-NEXT: ret i32 undef
;
switch i32 %c, label %otherwise [ i32 0, label %onzero
i32 1, label %onone
@ -1681,18 +1734,22 @@ otherwise:
}
define internal i1 @is_less_than_100_2(i32 %c) {
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_2
; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 undef, 100
; IS__CGSCC____-NEXT: ret i1 undef
;
%cmp = icmp slt i32 %c, 100
ret i1 %cmp
}
define i1 @propagate_range2(i32 %c) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@propagate_range2
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@propagate_range2
; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__TUNIT_NPM-NEXT: ret i1 true
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@propagate_range2
; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: ret i1 true
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@propagate_range2
@ -1714,12 +1771,6 @@ define internal i1 @non_zero(i8 %v) {
; IS__TUNIT_OPM-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0
; IS__TUNIT_OPM-NEXT: ret i1 [[R]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@non_zero
; IS__TUNIT_NPM-SAME: (i8 [[V:%.*]]) #[[ATTR1]] {
; IS__TUNIT_NPM-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0
; IS__TUNIT_NPM-NEXT: ret i1 [[R]]
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@non_zero
; IS__CGSCC_OPM-SAME: (i8 [[V:%.*]]) #[[ATTR1]] {
@ -1728,9 +1779,8 @@ define internal i1 @non_zero(i8 %v) {
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@non_zero
; IS__CGSCC_NPM-SAME: (i8 [[V:%.*]]) #[[ATTR1]] {
; IS__CGSCC_NPM-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0
; IS__CGSCC_NPM-NEXT: ret i1 [[R]]
; IS__CGSCC_NPM-SAME: () #[[ATTR1]] {
; IS__CGSCC_NPM-NEXT: ret i1 undef
;
%r = icmp ne i8 %v, 0
ret i1 %r
@ -1757,8 +1807,7 @@ define i1 @context(i8* %p) {
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]
; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT_NPM: t:
; IS__TUNIT_NPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR1]]
; IS__TUNIT_NPM-NEXT: ret i1 [[R]]
; IS__TUNIT_NPM-NEXT: ret i1 true
; IS__TUNIT_NPM: f:
; IS__TUNIT_NPM-NEXT: ret i1 false
;
@ -1781,8 +1830,7 @@ define i1 @context(i8* %p) {
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC_NPM: t:
; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR3]]
; IS__CGSCC_NPM-NEXT: ret i1 [[R]]
; IS__CGSCC_NPM-NEXT: ret i1 true
; IS__CGSCC_NPM: f:
; IS__CGSCC_NPM-NEXT: ret i1 false
;

View File

@ -43,7 +43,7 @@ define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree align 4 [[R0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3:[0-9]+]]
; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
; IS__TUNIT____-NEXT: ret i32* [[CALL3]]
; IS__TUNIT____-NEXT: ret i32* [[W0]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@external_ret2_nrw
@ -53,7 +53,7 @@ define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3:[0-9]+]]
; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
; IS__CGSCC____-NEXT: ret i32* [[CALL3]]
; IS__CGSCC____-NEXT: ret i32* [[W0]]
;
entry:
%call = call i32* @internal_ret0_nw(i32* %n0, i32* %w0)
@ -86,12 +86,12 @@ define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: return:
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* [[RETVAL_0]]
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[N0]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* [[N0]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret0_nw
; IS__CGSCC____-SAME: (i32* nofree returned [[N0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[R0:%.*]] = alloca i32, align 4
; IS__CGSCC____-NEXT: [[R1:%.*]] = alloca i32, align 4
@ -111,8 +111,8 @@ define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: return:
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: ret i32* [[RETVAL_0]]
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[N0]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: ret i32* undef
;
entry:
%r0 = alloca i32, align 4
@ -143,7 +143,7 @@ return: ; preds = %if.end, %if.then
define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_ret1_rrw
; IS__TUNIT____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
@ -166,12 +166,12 @@ define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: return:
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL8]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[R1]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* undef
;
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret1_rrw
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree nonnull returned align 4 dereferenceable(4) [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree nonnull align 4 dereferenceable(4) [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
@ -194,7 +194,7 @@ define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: return:
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL8]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[R1]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: ret i32* undef
;
entry:
@ -293,12 +293,12 @@ define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: return:
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL4]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* [[RETVAL_0]]
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[W0]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* [[W0]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret1_rw
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[W0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
@ -315,8 +315,8 @@ define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: return:
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL4]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: ret i32* [[RETVAL_0]]
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[W0]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: ret i32* undef
;
entry:
%0 = load i32, i32* %r0, align 4
@ -348,7 +348,7 @@ define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
; IS__TUNIT____-NEXT: ret i32* [[CALL1]]
; IS__TUNIT____-NEXT: ret i32* [[W0]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@external_source_ret2_nrw
@ -356,7 +356,7 @@ define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR4]]
; IS__CGSCC____-NEXT: ret i32* [[CALL1]]
; IS__CGSCC____-NEXT: ret i32* [[W0]]
;
entry:
%call = call i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)

View File

@ -143,16 +143,14 @@ define void @test8_2(i32* %p) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_2
; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR0]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @test8_1(i32* noalias nofree readnone "no-capture-maybe-returned" [[P]]) #[[ATTR1]]
; IS__TUNIT____-NEXT: store i32 10, i32* [[CALL]], align 4
; IS__TUNIT____-NEXT: store i32 10, i32* [[P]], align 4
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_2
; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 4 i32* @test8_1(i32* noalias nofree readnone "no-capture-maybe-returned" [[P]]) #[[ATTR11:[0-9]+]]
; IS__CGSCC____-NEXT: store i32 10, i32* [[CALL]], align 4
; IS__CGSCC____-NEXT: store i32 10, i32* [[P]], align 4
; IS__CGSCC____-NEXT: ret void
;
entry:
@ -176,7 +174,7 @@ define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) {
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@test9
; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR4:[0-9]+]] {
; IS__CGSCC____-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef <i1 true, i1 false, i1 true, i1 false>) #[[ATTR12:[0-9]+]]
; IS__CGSCC____-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef <i1 true, i1 false, i1 true, i1 false>) #[[ATTR11:[0-9]+]]
; IS__CGSCC____-NEXT: ret void
;
call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32>%val, <4 x i32*> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>)
@ -195,7 +193,7 @@ define <4 x i32> @test10(<4 x i32*> %ptrs) {
; IS__CGSCC____: Function Attrs: nofree nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test10
; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR5:[0-9]+]] {
; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef) #[[ATTR13:[0-9]+]]
; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef) #[[ATTR12:[0-9]+]]
; IS__CGSCC____-NEXT: ret <4 x i32> [[RES]]
;
%res = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>, <4 x i32>undef)
@ -233,7 +231,7 @@ define <4 x i32> @test12_2(<4 x i32*> %ptrs) {
; IS__CGSCC____: Function Attrs: argmemonly nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@test12_2
; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR7:[0-9]+]] {
; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR14:[0-9]+]]
; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR13:[0-9]+]]
; IS__CGSCC____-NEXT: ret <4 x i32> [[RES]]
;
%res = call <4 x i32> @test12_1(<4 x i32*> %ptrs)
@ -432,25 +430,7 @@ define void @ptr_uses(i8* %ptr) {
define void @ptr_use_chain(i8* %ptr) {
; CHECK-LABEL: define {{[^@]+}}@ptr_use_chain
; CHECK-SAME: (i8* [[PTR:%.*]]) {
; CHECK-NEXT: [[BC0:%.*]] = bitcast i8* [[PTR]] to i32*
; CHECK-NEXT: [[BC1:%.*]] = bitcast i32* [[BC0]] to i8*
; CHECK-NEXT: [[BC2:%.*]] = bitcast i8* [[BC1]] to i32*
; CHECK-NEXT: [[BC3:%.*]] = bitcast i32* [[BC2]] to i8*
; CHECK-NEXT: [[BC4:%.*]] = bitcast i8* [[BC3]] to i32*
; CHECK-NEXT: [[BC5:%.*]] = bitcast i32* [[BC4]] to i8*
; CHECK-NEXT: [[BC6:%.*]] = bitcast i8* [[BC5]] to i32*
; CHECK-NEXT: [[BC7:%.*]] = bitcast i32* [[BC6]] to i8*
; CHECK-NEXT: [[BC8:%.*]] = bitcast i8* [[BC7]] to i32*
; CHECK-NEXT: [[BC9:%.*]] = bitcast i32* [[BC8]] to i8*
; CHECK-NEXT: [[ABC2:%.*]] = bitcast i8* [[BC9]] to i32*
; CHECK-NEXT: [[ABC3:%.*]] = bitcast i32* [[ABC2]] to i8*
; CHECK-NEXT: [[ABC4:%.*]] = bitcast i8* [[ABC3]] to i32*
; CHECK-NEXT: [[ABC5:%.*]] = bitcast i32* [[ABC4]] to i8*
; CHECK-NEXT: [[ABC6:%.*]] = bitcast i8* [[ABC5]] to i32*
; CHECK-NEXT: [[ABC7:%.*]] = bitcast i32* [[ABC6]] to i8*
; CHECK-NEXT: [[ABC8:%.*]] = bitcast i8* [[ABC7]] to i32*
; CHECK-NEXT: [[ABC9:%.*]] = bitcast i32* [[ABC8]] to i8*
; CHECK-NEXT: call void @escape_i8(i8* [[ABC9]])
; CHECK-NEXT: call void @escape_i8(i8* [[PTR]])
; CHECK-NEXT: ret void
;
%bc0 = bitcast i8* %ptr to i32*
@ -518,8 +498,7 @@ define i32 @read_only_constant_mem() {
; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nounwind willreturn }
; IS__CGSCC____: attributes #[[ATTR9]] = { readnone }
; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind readonly }
; IS__CGSCC____: attributes #[[ATTR11]] = { readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR12]] = { willreturn writeonly }
; IS__CGSCC____: attributes #[[ATTR13]] = { readonly willreturn }
; IS__CGSCC____: attributes #[[ATTR14]] = { nounwind }
; IS__CGSCC____: attributes #[[ATTR11]] = { willreturn writeonly }
; IS__CGSCC____: attributes #[[ATTR12]] = { readonly willreturn }
; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind }
;.

View File

@ -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=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
;
@ -64,17 +64,15 @@ define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 {
; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_r1
; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR5:[0-9]+]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[CALL]]) #[[ATTR6:[0-9]+]]
; IS__TUNIT____-NEXT: ret i32 [[CALL1]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR6:[0-9]+]]
; IS__TUNIT____-NEXT: ret i32 [[R]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r1
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR6:[0-9]+]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[CALL]]) #[[ATTR7:[0-9]+]]
; IS__CGSCC____-NEXT: ret i32 [[CALL1]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR7:[0-9]+]]
; IS__CGSCC____-NEXT: ret i32 [[R]]
;
entry:
%call = call i32 @sink_r0(i32 %r)
@ -90,20 +88,18 @@ define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__TUNIT____: if.then:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR5]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
; IS__TUNIT____: if.then3:
; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: if.end12:
; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
@ -114,33 +110,31 @@ define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[COND_END]]
; IS__TUNIT____: cond.end:
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: return:
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__TUNIT____-NEXT: ret i32 [[R]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r2
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__CGSCC____: if.then:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR6]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
; IS__CGSCC____: if.then3:
; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]])
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: if.end12:
; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
@ -151,11 +145,11 @@ define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: br label [[COND_END]]
; IS__CGSCC____: cond.end:
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: return:
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__CGSCC____-NEXT: ret i32 [[R]]
;
entry:
%cmp = icmp sgt i32 %a, %b
@ -209,20 +203,18 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__TUNIT____: if.then:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR5]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
; IS__TUNIT____: if.then3:
; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[B]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[B]], i32 undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: if.end12:
; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
@ -233,33 +225,24 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[COND_END]]
; IS__TUNIT____: cond.end:
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: return:
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[B]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_rX
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__CGSCC____: if.then:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR6]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) #[[ATTR8:[0-9]+]]
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
; IS__CGSCC____: if.then3:
; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]])
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR8]]
; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR8]]
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) #[[ATTR8]]
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR8]]
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) #[[ATTR8]]
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) #[[ATTR8]]
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: if.end12:
; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
@ -267,13 +250,12 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
; IS__CGSCC____: cond.true:
; IS__CGSCC____-NEXT: br label [[COND_END:%.*]]
; IS__CGSCC____: cond.false:
; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]]
; IS__CGSCC____-NEXT: br label [[COND_END]]
; IS__CGSCC____: cond.end:
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: return:
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[B]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
;
entry:
@ -361,19 +343,17 @@ entry:
define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 {
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r1
; IS__TUNIT____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR5]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: ret double* [[CALL1]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: ret double* [[R]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r1
; IS__CGSCC____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR2:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: ret double* [[CALL1]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: ret double* [[R]]
;
entry:
%call = call double* @ptr_sink_r0(double* %r)
@ -384,25 +364,23 @@ entry:
define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r2
; IS__TUNIT____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]], double* nofree readnone returned [[R:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__TUNIT____: if.then:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR5]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[B]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
; IS__TUNIT____: if.then3:
; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL6]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[CALL5]], double* noalias nofree readnone [[CALL7]], double* noalias nofree readnone [[CALL8]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[CALL4]], double* noalias nofree readnone [[CALL9]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: if.end12:
; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
@ -410,36 +388,34 @@ define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
; IS__TUNIT____: cond.true:
; IS__TUNIT____-NEXT: br label [[COND_END:%.*]]
; IS__TUNIT____: cond.false:
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[COND_END]]
; IS__TUNIT____: cond.end:
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: return:
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__TUNIT____-NEXT: ret double* [[RETVAL_0]]
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__TUNIT____-NEXT: ret double* [[R]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r2
; IS__CGSCC____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]], double* nofree readnone returned [[R:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR2]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__CGSCC____: if.then:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[B]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
; IS__CGSCC____: if.then3:
; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[B]])
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL6]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[CALL5]], double* noalias nofree readnone [[CALL7]], double* noalias nofree readnone [[CALL8]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[CALL4]], double* noalias nofree readnone [[CALL9]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: if.end12:
; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
@ -447,14 +423,14 @@ define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
; IS__CGSCC____: cond.true:
; IS__CGSCC____-NEXT: br label [[COND_END:%.*]]
; IS__CGSCC____: cond.false:
; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: br label [[COND_END]]
; IS__CGSCC____: cond.end:
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: return:
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__CGSCC____-NEXT: ret double* [[RETVAL_0]]
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__CGSCC____-NEXT: ret double* [[R]]
;
entry:
%cmp = icmp ugt double* %a, %b
@ -516,7 +492,7 @@ define i32* @rt0(i32* %a) #0 {
;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt0
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2:[0-9]+]] {
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: unreachable
;
@ -543,7 +519,7 @@ define i32* @rt1(i32* %a) #0 {
;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt1
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] {
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: unreachable
;
@ -563,14 +539,14 @@ define i32* @rt2_helper(i32* %a) #0 {
; IS__TUNIT____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: ret i32* [[CALL]]
; IS__TUNIT____-NEXT: ret i32* [[A]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2_helper
; IS__CGSCC____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR2]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: ret i32* [[CALL]]
; IS__CGSCC____-NEXT: ret i32* [[A]]
;
entry:
%call = call i32* @rt2(i32* %a, i32* %a)
@ -588,12 +564,12 @@ define i32* @rt2(i32* %a, i32 *%b) #0 {
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[IF_END]]
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[CALL]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* [[SEL]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2
; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR2]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
@ -601,7 +577,7 @@ define i32* @rt2(i32* %a, i32 *%b) #0 {
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: br label [[IF_END]]
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[CALL]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: ret i32* [[SEL]]
;
entry:
@ -622,17 +598,17 @@ if.end:
define i32* @rt3_helper(i32* %a, i32* %b) #0 {
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3_helper
; IS__TUNIT____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: ret i32* [[CALL]]
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: ret i32* [[B]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3_helper
; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR2]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: ret i32* [[CALL]]
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: ret i32* [[B]]
;
entry:
%call = call i32* @rt3(i32* %a, i32* %b)
@ -642,29 +618,29 @@ entry:
define i32* @rt3(i32* %a, i32 *%b) #0 {
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3
; IS__TUNIT____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__TUNIT____: if.then:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[IF_END]]
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[CALL]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* [[SEL]]
; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* [[B]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3
; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR2]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__CGSCC____: if.then:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: br label [[IF_END]]
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[CALL]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: ret i32* [[SEL]]
; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ]
; IS__CGSCC____-NEXT: ret i32* [[B]]
;
entry:
%cmp = icmp eq i32* %a, null
@ -699,8 +675,8 @@ define i32* @calls_unknown_fn(i32* %r) #0 {
;
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_unknown_fn
; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR3:[0-9]+]] {
; IS__CGSCC____-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR9:[0-9]+]]
; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR4:[0-9]+]] {
; IS__CGSCC____-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR8:[0-9]+]]
; IS__CGSCC____-NEXT: ret i32* [[R]]
;
tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn)
@ -722,11 +698,17 @@ define i32* @calls_unknown_fn(i32* %r) #0 {
; Verify the maybe-redefined function is not annotated:
;
define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 {
; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn
; CHECK-SAME: (i32* [[R:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32* [[R]]
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn
; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR3]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i32* [[R]]
;
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@maybe_redefined_fn
; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i32* [[R]]
;
entry:
ret i32* %r
@ -742,9 +724,9 @@ define i32* @calls_maybe_redefined_fn(i32* %r) #0 {
;
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn
; IS__CGSCC____-SAME: (i32* returned [[R:%.*]]) #[[ATTR3]] {
; IS__CGSCC____-SAME: (i32* returned [[R:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR9]]
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR8]]
; IS__CGSCC____-NEXT: ret i32* [[R]]
;
entry:
@ -765,11 +747,17 @@ entry:
; Verify the maybe-redefined function is not annotated:
;
define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 {
; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn2
; CHECK-SAME: (i32* [[R:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32* [[R]]
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn2
; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR3]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i32* [[R]]
;
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@maybe_redefined_fn2
; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i32* [[R]]
;
entry:
ret i32* %r
@ -785,9 +773,9 @@ define i32* @calls_maybe_redefined_fn2(i32* %r) #0 {
;
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2
; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR3]] {
; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR9]]
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR8]]
; IS__CGSCC____-NEXT: ret i32* [[CALL]]
;
entry:
@ -815,10 +803,7 @@ define double @select_and_phi(double %b) #0 {
; IS__TUNIT____: if.then:
; IS__TUNIT____-NEXT: br label [[IF_END]]
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
; IS__TUNIT____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
; IS__TUNIT____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
; IS__TUNIT____-NEXT: ret double [[SEL]]
; IS__TUNIT____-NEXT: ret double [[B]]
;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@select_and_phi
@ -829,10 +814,7 @@ define double @select_and_phi(double %b) #0 {
; IS__CGSCC____: if.then:
; IS__CGSCC____-NEXT: br label [[IF_END]]
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
; IS__CGSCC____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
; IS__CGSCC____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
; IS__CGSCC____-NEXT: ret double [[SEL]]
; IS__CGSCC____-NEXT: ret double [[B]]
;
entry:
%cmp = fcmp ogt double %b, 0.000000e+00
@ -870,14 +852,11 @@ define double @recursion_select_and_phi(i32 %a, double %b) #0 {
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR6]]
; IS__TUNIT____-NEXT: br label [[IF_END]]
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi double [ [[CALL]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
; IS__TUNIT____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
; IS__TUNIT____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
; IS__TUNIT____-NEXT: ret double [[SEL]]
; IS__TUNIT____-NEXT: ret double [[B]]
;
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursion_select_and_phi
; IS__CGSCC____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR2]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[DEC:%.*]] = add nsw i32 [[A]], -1
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0
@ -886,10 +865,7 @@ define double @recursion_select_and_phi(i32 %a, double %b) #0 {
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR7]]
; IS__CGSCC____-NEXT: br label [[IF_END]]
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi double [ [[CALL]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
; IS__CGSCC____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
; IS__CGSCC____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
; IS__CGSCC____-NEXT: ret double [[SEL]]
; IS__CGSCC____-NEXT: ret double [[B]]
;
entry:
%dec = add nsw i32 %a, -1
@ -1207,17 +1183,29 @@ ret_undef1:
declare i32* @unknown(i32*)
define i32* @ret_arg_or_unknown(i32* %b) #0 {
; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown
; CHECK-SAME: (i32* [[B:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
; CHECK: ret_arg:
; CHECK-NEXT: ret i32* [[B]]
; CHECK: ret_unknown:
; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
; CHECK-NEXT: ret i32* [[CALL]]
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown
; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR3]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
; IS__TUNIT____: ret_arg:
; IS__TUNIT____-NEXT: ret i32* [[B]]
; IS__TUNIT____: ret_unknown:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
; IS__TUNIT____-NEXT: ret i32* [[CALL]]
;
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_or_unknown
; IS__CGSCC____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
; IS__CGSCC____: ret_arg:
; IS__CGSCC____-NEXT: ret i32* [[B]]
; IS__CGSCC____: ret_unknown:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
; IS__CGSCC____-NEXT: ret i32* [[CALL]]
;
entry:
%cmp = icmp eq i32* %b, null
@ -1232,20 +1220,35 @@ ret_unknown:
}
define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
; CHECK-SAME: (i32* [[B:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
; CHECK: ret_arg:
; CHECK-NEXT: br label [[R:%.*]]
; CHECK: ret_unknown:
; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
; CHECK-NEXT: br label [[R]]
; CHECK: r:
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ]
; CHECK-NEXT: ret i32* [[PHI]]
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR3]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
; IS__TUNIT____: ret_arg:
; IS__TUNIT____-NEXT: br label [[R:%.*]]
; IS__TUNIT____: ret_unknown:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
; IS__TUNIT____-NEXT: br label [[R]]
; IS__TUNIT____: r:
; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ]
; IS__TUNIT____-NEXT: ret i32* [[PHI]]
;
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
; IS__CGSCC____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
; IS__CGSCC____: ret_arg:
; IS__CGSCC____-NEXT: br label [[R:%.*]]
; IS__CGSCC____: ret_unknown:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
; IS__CGSCC____-NEXT: br label [[R]]
; IS__CGSCC____: r:
; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ]
; IS__CGSCC____-NEXT: ret i32* [[PHI]]
;
entry:
%cmp = icmp eq i32* %b, null
@ -1408,20 +1411,35 @@ r:
declare void @noreturn() noreturn;
define i32 @deadblockphi3(i32 %A, i1 %c) #0 {
; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@deadblockphi3
; CHECK-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]]
; CHECK: unreachablecall:
; CHECK-NEXT: call void @noreturn() #[[ATTR4:[0-9]+]]
; CHECK-NEXT: unreachable
; CHECK: unreachableblock2:
; CHECK-NEXT: unreachable
; CHECK: unreachableblock3:
; CHECK-NEXT: unreachable
; CHECK: r:
; CHECK-NEXT: ret i32 [[A]]
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@deadblockphi3
; IS__TUNIT____-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR3]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]]
; IS__TUNIT____: unreachablecall:
; IS__TUNIT____-NEXT: call void @noreturn() #[[ATTR4:[0-9]+]]
; IS__TUNIT____-NEXT: unreachable
; IS__TUNIT____: unreachableblock2:
; IS__TUNIT____-NEXT: unreachable
; IS__TUNIT____: unreachableblock3:
; IS__TUNIT____-NEXT: unreachable
; IS__TUNIT____: r:
; IS__TUNIT____-NEXT: ret i32 [[A]]
;
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@deadblockphi3
; IS__CGSCC____-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR4]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]]
; IS__CGSCC____: unreachablecall:
; IS__CGSCC____-NEXT: call void @noreturn() #[[ATTR5:[0-9]+]]
; IS__CGSCC____-NEXT: unreachable
; IS__CGSCC____: unreachableblock2:
; IS__CGSCC____-NEXT: unreachable
; IS__CGSCC____: unreachableblock3:
; IS__CGSCC____-NEXT: unreachable
; IS__CGSCC____: r:
; IS__CGSCC____-NEXT: ret i32 [[A]]
;
entry:
br i1 %c, label %r, label %unreachablecall
@ -1486,10 +1504,10 @@ define i32 @exact(i32* align 8 %a, i32* align 8 %b) {
; CHECK-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2)
; CHECK-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]])
; CHECK-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]])
; CHECK-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32
; CHECK-NEXT: [[C3L:%.*]] = load i32, i32* [[A]], align 32
; CHECK-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16
; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]]
; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[C2]]
; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2
; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]]
; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]]
; CHECK-NEXT: ret i32 [[ADD4]]
@ -1602,19 +1620,18 @@ attributes #0 = { noinline nounwind uwtable }
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn }
; IS__TUNIT____: attributes #[[ATTR3]] = { noinline nounwind uwtable }
; IS__TUNIT____: attributes #[[ATTR4]] = { noreturn }
; IS__TUNIT____: attributes #[[ATTR5]] = { nofree nosync nounwind readnone willreturn }
; IS__TUNIT____: attributes #[[ATTR5:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
; IS__TUNIT____: attributes #[[ATTR6]] = { nofree nosync nounwind readnone }
; IS__TUNIT____: attributes #[[ATTR7]] = { nounwind }
; IS__TUNIT____: attributes #[[ATTR8:[0-9]+]] = { nounwind readnone }
;.
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn }
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable }
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn }
; IS__CGSCC____: attributes #[[ATTR3]] = { noinline nounwind uwtable }
; IS__CGSCC____: attributes #[[ATTR4]] = { noreturn }
; IS__CGSCC____: attributes #[[ATTR5:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR6]] = { readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable willreturn }
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree noinline nosync nounwind readnone uwtable }
; IS__CGSCC____: attributes #[[ATTR3]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn }
; IS__CGSCC____: attributes #[[ATTR4]] = { noinline nounwind uwtable }
; IS__CGSCC____: attributes #[[ATTR5]] = { noreturn }
; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind readnone }
; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind readnone }
; IS__CGSCC____: attributes #[[ATTR9]] = { nounwind }
; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind }
;.

View File

@ -1086,12 +1086,12 @@ define i32 @violate_noundef_nonpointer() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
; IS__TUNIT____-SAME: () #[[ATTR0]] {
; IS__TUNIT____-NEXT: unreachable
; IS__TUNIT____-NEXT: ret i32 undef
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
; IS__CGSCC____-SAME: () #[[ATTR0]] {
; IS__CGSCC____-NEXT: unreachable
; IS__CGSCC____-NEXT: ret i32 undef
;
%ret = call i32 @argument_noundef1(i32 undef)
ret i32 %ret
@ -1115,12 +1115,12 @@ define i32* @violate_noundef_pointer() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_pointer
; IS__TUNIT____-SAME: () #[[ATTR0]] {
; IS__TUNIT____-NEXT: unreachable
; IS__TUNIT____-NEXT: ret i32* undef
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_pointer
; IS__CGSCC____-SAME: () #[[ATTR0]] {
; IS__CGSCC____-NEXT: unreachable
; IS__CGSCC____-NEXT: ret i32* undef
;
%ret = call i32* @argument_noundef2(i32* undef)
ret i32* %ret

View File

@ -433,21 +433,14 @@ define internal i32* @test_inalloca(i32* inalloca(i32) %a) {
define i32* @complicated_args_inalloca(i32* %arg) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_inalloca
; IS__TUNIT____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR1]]
; IS__TUNIT____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call nonnull dereferenceable(4) i32* @test_inalloca(i32* noalias nofree writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR1]]
; IS__TUNIT____-NEXT: ret i32* [[CALL]]
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_inalloca
; IS__CGSCC_OPM-SAME: (i32* nofree noundef nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[ARG]]) #[[ATTR7:[0-9]+]]
; IS__CGSCC_OPM-NEXT: ret i32* [[CALL]]
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_inalloca
; IS__CGSCC_NPM-SAME: (i32* nofree noundef nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[ARG]]) #[[ATTR6:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i32* [[CALL]]
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_inalloca
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: ret i32* [[ARG]]
;
%call = call i32* @test_inalloca(i32* inalloca(i32) %arg)
ret i32* %call
@ -471,29 +464,27 @@ define i32* @complicated_args_preallocated() {
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
; IS__TUNIT_OPM-SAME: () #[[ATTR0:[0-9]+]] {
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR7:[0-9]+]]
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR1]] [ "preallocated"(token [[C]]) ]
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noundef nonnull align 536870912 dereferenceable(4) i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR1]] [ "preallocated"(token [[C]]) ]
; IS__TUNIT_OPM-NEXT: ret i32* [[CALL]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
; IS__TUNIT_NPM-SAME: () #[[ATTR0:[0-9]+]] {
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR6:[0-9]+]]
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR1]] [ "preallocated"(token [[C]]) ]
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noundef nonnull align 536870912 dereferenceable(4) i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR1]] [ "preallocated"(token [[C]]) ]
; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]]
;
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
; IS__CGSCC_OPM-SAME: () #[[ATTR0:[0-9]+]] {
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR8:[0-9]+]]
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR9:[0-9]+]] [ "preallocated"(token [[C]]) ]
; IS__CGSCC_OPM-NEXT: ret i32* [[CALL]]
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR7:[0-9]+]]
; IS__CGSCC_OPM-NEXT: ret i32* null
;
; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
; IS__CGSCC_NPM-SAME: () #[[ATTR0:[0-9]+]] {
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR7:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR8:[0-9]+]] [ "preallocated"(token [[C]]) ]
; IS__CGSCC_NPM-NEXT: ret i32* [[CALL]]
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR6:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i32* null
;
%c = call token @llvm.call.preallocated.setup(i32 1)
%call = call i32* @test_preallocated(i32* preallocated(i32) null) ["preallocated"(token %c)]
@ -542,15 +533,10 @@ define void @complicated_args_sret(%struct.X** %b) {
}
define internal %struct.X* @test_nest(%struct.X* nest %a) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_nest
; IS__TUNIT____-SAME: (%struct.X* nest noalias nofree noundef readnone returned align 536870912 "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: ret %struct.X* [[A]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_nest
; IS__CGSCC____-SAME: (%struct.X* nest noalias nofree noundef readnone returned align 536870912 "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: ret %struct.X* [[A]]
; IS__CGSCC____-SAME: (%struct.X* nest noalias nocapture nofree readnone align 536870912 [[A:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: ret %struct.X* undef
;
ret %struct.X* %a
}
@ -558,20 +544,12 @@ define %struct.X* @complicated_args_nest() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_nest
; IS__TUNIT____-SAME: () #[[ATTR1]] {
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nocapture nofree noundef readnone align 536870912 null) #[[ATTR1]]
; IS__TUNIT____-NEXT: ret %struct.X* [[CALL]]
; IS__TUNIT____-NEXT: ret %struct.X* null
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_nest
; IS__CGSCC_OPM-SAME: () #[[ATTR1]] {
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nocapture nofree noundef readnone align 536870912 null) #[[ATTR7]]
; IS__CGSCC_OPM-NEXT: ret %struct.X* [[CALL]]
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_nest
; IS__CGSCC_NPM-SAME: () #[[ATTR1]] {
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nocapture nofree noundef readnone align 536870912 null) #[[ATTR6]]
; IS__CGSCC_NPM-NEXT: ret %struct.X* [[CALL]]
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_nest
; IS__CGSCC____-SAME: () #[[ATTR1]] {
; IS__CGSCC____-NEXT: ret %struct.X* null
;
%call = call %struct.X* @test_nest(%struct.X* null)
ret %struct.X* %call
@ -648,13 +626,13 @@ define i8* @complicated_args_byval2() {
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_byval2
; IS__CGSCC_OPM-SAME: () #[[ATTR3]] {
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR10:[0-9]+]]
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR8:[0-9]+]]
; IS__CGSCC_OPM-NEXT: ret i8* [[C]]
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval2
; IS__CGSCC_NPM-SAME: () #[[ATTR3]] {
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR9:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR7:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i8* [[C]]
;
%c = call i8* @test_byval2(%struct.X* byval(%struct.X) @S)
@ -991,7 +969,7 @@ define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) {
; IS__CGSCC_OPM-NEXT: [[OR:%.*]] = or i1 false, [[C]]
; IS__CGSCC_OPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
; IS__CGSCC_OPM: a:
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR11:[0-9]+]]
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR9:[0-9]+]]
; IS__CGSCC_OPM-NEXT: ret i1 undef
; IS__CGSCC_OPM: b:
; IS__CGSCC_OPM-NEXT: ret i1 undef
@ -1004,7 +982,7 @@ define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) {
; IS__CGSCC_NPM-NEXT: [[OR:%.*]] = or i1 false, [[C]]
; IS__CGSCC_NPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
; IS__CGSCC_NPM: a:
; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR10:[0-9]+]]
; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR8:[0-9]+]]
; IS__CGSCC_NPM-NEXT: ret i1 undef
; IS__CGSCC_NPM: b:
; IS__CGSCC_NPM-NEXT: ret i1 undef
@ -1035,6 +1013,7 @@ define i1 @test_merge_with_undef_values(i1 %c) {
ret i1 %r1
}
define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) {
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_then_1
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
@ -1270,11 +1249,9 @@ define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) {
; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind writeonly }
; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly }
; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nofree nosync nounwind readnone willreturn }
; IS__CGSCC_OPM: attributes #[[ATTR7]] = { readnone willreturn }
; IS__CGSCC_OPM: attributes #[[ATTR8]] = { willreturn }
; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nounwind readnone willreturn }
; IS__CGSCC_OPM: attributes #[[ATTR10]] = { readonly willreturn }
; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree nosync nounwind readnone }
; IS__CGSCC_OPM: attributes #[[ATTR7]] = { willreturn }
; IS__CGSCC_OPM: attributes #[[ATTR8]] = { readonly willreturn }
; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree nosync nounwind readnone }
;.
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
@ -1282,9 +1259,7 @@ define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) {
; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readonly willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn writeonly }
; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nofree nosync nounwind readnone willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR6]] = { readnone willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR7]] = { willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nounwind readnone willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR9]] = { readonly willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree nosync nounwind readnone }
; IS__CGSCC_NPM: attributes #[[ATTR6]] = { willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR7]] = { readonly willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree nosync nounwind readnone }
;.

View File

@ -28,7 +28,7 @@ define void @bar() {
ret void
}
; CHECK: %{{.*}} = bitcast i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([16 x i8], [16 x i8] addrspace(3)* [[SHARED_X]], i32 0, i32 0) to i8*) to [4 x i32]*
; CHECK: call void @use.internalized(i8* nofree writeonly addrspacecast (i8 addrspace(3)* getelementptr inbounds ([16 x i8], [16 x i8] addrspace(3)* [[SHARED_X]], i32 0, i32 0) to i8*))
define internal void @baz() {
entry:
%tid = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
@ -45,7 +45,7 @@ exit:
ret void
}
; CHECK: %{{.*}} = bitcast i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([4 x i8], [4 x i8] addrspace(3)* [[SHARED_Y]], i32 0, i32 0) to i8*) to [4 x i32]*
; CHECK: call void @use.internalized(i8* nofree writeonly addrspacecast (i8 addrspace(3)* getelementptr inbounds ([4 x i8], [4 x i8] addrspace(3)* [[SHARED_Y]], i32 0, i32 0) to i8*))
define internal void @qux() {
entry:
%tid = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()