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
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.
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,
#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"
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.
// 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()))
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) {
/// 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
///
///{
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;
// 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(
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 *>
// 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;
}
}
ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
- size_t NumUnresolvedCalls = UnresolvedCalls.size();
- bool Changed = false;
-
- // 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;
- };
+ ChangeStatus Changed = ChangeStatus::UNCHANGED;
- // Callback for a leaf value returned by the associated function.
- auto VisitValueCB = [](Value &Val, const Instruction *, RVState &RVS,
- 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";
- });
+ auto ReturnValueCB = [&](Value &V, const Instruction *CtxI, ReturnInst &Ret,
+ bool) -> bool {
+ 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 {
// 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");
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())
// 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;
+ 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;
+ }
+ if (*SimplifiedV != nullptr)
+ V = *SimplifiedV;
}
- Value *Val = SimplifiedV.getValue();
- if (isa<UndefValue>(Val)) {
+ if (isa<UndefValue>(V)) {
KnownUBInsts.insert(I);
return llvm::None;
}
- return Val;
+ return V;
}
};
/// 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;
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")
/// 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 =
- A.getAssumedSimplified(IRP, QueryingAA, UsedAssumedInformation);
+ Optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
+ if (Simplify)
+ QueryingValueSimplified =
+ A.getAssumedSimplified(IRP, QueryingAA, UsedAssumedInformation);
return unionAssumed(QueryingValueSimplified);
}
/// 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))
- Changed = ChangeStatus::CHANGED;
- }
+ 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();
}
};
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);
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;
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);
-
- auto PredForReturned =
- [&](Value &V, const SmallSetVector<ReturnInst *, 4> &RetInsts) {
- // We can replace the AssociatedValue with the constant.
- if (&V == C || isa<UndefValue>(V))
+ if (auto *NewV = getReplacementValue()) {
+ auto PredForReturned =
+ [&](Value &, const SmallSetVector<ReturnInst *, 4> &RetInsts) {
+ for (ReturnInst *RI : RetInsts) {
+ 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;
-
- 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");
- if (A.changeUseAfterManifest(RI->getOperandUse(0), *NewV))
- Changed = ChangeStatus::CHANGED;
- }
- return true;
- };
- A.checkForAllReturnedValuesAndReturnInsts(PredForReturned, *this);
+ };
+ A.checkForAllReturnedValuesAndReturnInsts(PredForReturned, *this);
+ }
return Changed | AAValueSimplify::manifest(A);
}
/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
- SimplifiedAssociatedValue = &getAnchorValue();
+ SimplifiedAssociatedValue = nullptr;
indicateOptimisticFixpoint();
}
/// See AbstractAttribute::initialize(...).
}
};
-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) {}
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;
- }
+ if (A.changeUseAfterManifest(U, *NewV))
+ Changed = ChangeStatus::CHANGED;
}
return Changed | AAValueSimplify::manifest(A);
; 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
; 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"
; 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
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__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__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_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
}
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
}
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:
}
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
; 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}
;.
; 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
; 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
}
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
;
; 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:
; 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
; 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
}
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
}
;.
; 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 }
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
}
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
; 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
;
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
;
; 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
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
}
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()
; 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
;
; 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
; 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
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
;
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*)
;
;
; 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
; 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
; 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]+]]
; 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
; 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
; 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
; 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
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
; 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
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]]
;
; 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]] ]
; 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]] ]
}
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:%.*]])
}
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
}
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
}
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
; 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}
;.
; 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
}
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
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]]
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]]
; 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
; 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:
; 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:
; 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 ' %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 [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-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
; GRAPH-NEXT: updates [AAMemoryLocation] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
; 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>
; 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
; 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
; 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:
; 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:
; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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:%.*]]) {
; 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*
; 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*
; 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
; 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
; 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)
; 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 }
;.
; 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)
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()
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)
; 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]]
;
;
; 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]
; 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)
; 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
; 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
;
; 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:
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
; 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*
; 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:
; 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]]
;
; 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)
; 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
;
; 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
;
; 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
; 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
; 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)
; 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)
; 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()
; 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
; 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
;
; 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
; 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
; 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:
; 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
; 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
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:
; 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
; 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
; 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
; 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
}
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)
}
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
}
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
}
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
; 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]] {
;
; 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
; 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
;
; 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
;
; 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
; 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)
; 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
; 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
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
; 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
; 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:
; 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
; 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
; 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
; 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)
; 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:
; 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>)
; 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)
; 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)
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*
; 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 }
;.
; 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
;
; 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)
; 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]]
; 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]]
; 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
; 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]]
; 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]]
; 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:
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)
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]]
; 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]]
; 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
;
; 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
;
;
; 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
;
; 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)
; 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:%.*]]
; 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:
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)
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
;
; 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)
; 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
;
; 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:
; 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
;
; 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:
; 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
; 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
; 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
; 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
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
}
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
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
; 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]]
; 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 }
;.
; 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
; 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
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
; 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)]
}
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
}
; 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
; 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)
; 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
; 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
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]] {
; 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 }
; 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 }
;.
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()
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()