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

[Attributor] Make DepClass a required argument

We often used a sub-optimal dependence class in the past because we
didn't see the argument. Let's make it explicit so we remember to think
about it.
This commit is contained in:
Johannes Doerfert 2021-03-01 19:31:42 -06:00
parent fa902e7024
commit c5b0326e2f
5 changed files with 269 additions and 170 deletions

View File

@ -1056,8 +1056,7 @@ struct Attributor {
/// the `Attributor::recordDependence` method.
template <typename AAType>
const AAType &getAAFor(const AbstractAttribute &QueryingAA,
const IRPosition &IRP,
DepClassTy DepClass = DepClassTy::REQUIRED) {
const IRPosition &IRP, DepClassTy DepClass) {
return getOrCreateAAFor<AAType>(IRP, &QueryingAA, DepClass,
/* ForceUpdate */ false);
}
@ -1069,8 +1068,7 @@ struct Attributor {
/// was assumed dead.
template <typename AAType>
const AAType &getAndUpdateAAFor(const AbstractAttribute &QueryingAA,
const IRPosition &IRP,
DepClassTy DepClass = DepClassTy::REQUIRED) {
const IRPosition &IRP, DepClassTy DepClass) {
return getOrCreateAAFor<AAType>(IRP, &QueryingAA, DepClass,
/* ForceUpdate */ true);
}
@ -1081,10 +1079,9 @@ struct Attributor {
/// function.
/// NOTE: ForceUpdate is ignored in any stage other than the update stage.
template <typename AAType>
const AAType &getOrCreateAAFor(const IRPosition &IRP,
const AbstractAttribute *QueryingAA = nullptr,
DepClassTy DepClass = DepClassTy::REQUIRED,
bool ForceUpdate = false) {
const AAType &
getOrCreateAAFor(const IRPosition &IRP, const AbstractAttribute *QueryingAA,
DepClassTy DepClass, bool ForceUpdate = false) {
if (AAType *AAPtr = lookupAAFor<AAType>(IRP, QueryingAA, DepClass)) {
if (ForceUpdate && Phase == AttributorPhase::UPDATE)
updateAA(*AAPtr);
@ -1160,6 +1157,11 @@ struct Attributor {
DepClass);
return AA;
}
template <typename AAType>
const AAType &getOrCreateAAFor(const IRPosition &IRP) {
return getOrCreateAAFor<AAType>(IRP, /* QueryingAA */ nullptr,
DepClassTy::NONE);
}
/// Return the attribute of \p AAType for \p IRP if existing. This also allows
/// non-AA users lookup.

View File

@ -864,7 +864,8 @@ bool Attributor::checkForAllReturnedValuesAndReturnInsts(
// and liveness information.
// TODO: use the function scope once we have call site AAReturnedValues.
const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
const auto &AARetVal =
getAAFor<AAReturnedValues>(QueryingAA, QueryIRP, DepClassTy::REQUIRED);
if (!AARetVal.getState().isValidState())
return false;
@ -881,7 +882,8 @@ bool Attributor::checkForAllReturnedValues(
// TODO: use the function scope once we have call site AAReturnedValues.
const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
const auto &AARetVal =
getAAFor<AAReturnedValues>(QueryingAA, QueryIRP, DepClassTy::REQUIRED);
if (!AARetVal.getState().isValidState())
return false;

View File

@ -450,7 +450,8 @@ static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
// Callback for each possibly returned value.
auto CheckReturnValue = [&](Value &RV) -> bool {
const IRPosition &RVPos = IRPosition::value(RV);
const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
const AAType &AA =
A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
<< " @ " << RVPos << "\n");
const StateType &AAS = AA.getState();
@ -512,7 +513,8 @@ static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
return false;
const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
const AAType &AA =
A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
<< " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
const StateType &AAS = AA.getState();
@ -571,7 +573,7 @@ struct AACallSiteReturnedFromReturned : public BaseType {
return S.indicatePessimisticFixpoint();
IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
const AAType &AA = A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(S, AA.getState());
}
};
@ -708,8 +710,8 @@ struct AANoUnwindImpl : AANoUnwind {
return true;
if (const auto *CB = dyn_cast<CallBase>(&I)) {
const auto &NoUnwindAA =
A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(*CB));
const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(
*this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED);
return NoUnwindAA.isAssumedNoUnwind();
}
return false;
@ -751,7 +753,7 @@ struct AANoUnwindCallSite final : AANoUnwindImpl {
// redirecting requests to the callee argument.
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), FnAA.getState());
}
@ -1084,7 +1086,8 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
// TODO: use the function scope once we have call site AAReturnedValues.
const auto &RetValAA = A.getAAFor<AAReturnedValues>(
*this, IRPosition::function(*CB->getCalledFunction()));
*this, IRPosition::function(*CB->getCalledFunction()),
DepClassTy::REQUIRED);
LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
<< RetValAA << "\n");
@ -1344,11 +1347,9 @@ ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
if (CB->hasFnAttr(Attribute::NoSync))
return true;
const auto &NoSyncAA =
A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(*CB));
if (NoSyncAA.isAssumedNoSync())
return true;
return false;
const auto &NoSyncAA = A.getAAFor<AANoSync>(
*this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED);
return NoSyncAA.isAssumedNoSync();
}
if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
@ -1403,7 +1404,7 @@ struct AANoSyncCallSite final : AANoSyncImpl {
// redirecting requests to the callee argument.
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), FnAA.getState());
}
@ -1423,8 +1424,8 @@ struct AANoFreeImpl : public AANoFree {
if (CB.hasFnAttr(Attribute::NoFree))
return true;
const auto &NoFreeAA =
A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(CB));
const auto &NoFreeAA = A.getAAFor<AANoFree>(
*this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
return NoFreeAA.isAssumedNoFree();
};
@ -1468,7 +1469,7 @@ struct AANoFreeCallSite final : AANoFreeImpl {
// redirecting requests to the callee argument.
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), FnAA.getState());
}
@ -1504,7 +1505,8 @@ struct AANoFreeFloating : AANoFreeImpl {
unsigned ArgNo = CB->getArgOperandNo(&U);
const auto &NoFreeArg = A.getAAFor<AANoFree>(
*this, IRPosition::callsite_argument(*CB, ArgNo));
*this, IRPosition::callsite_argument(*CB, ArgNo),
DepClassTy::REQUIRED);
return NoFreeArg.isAssumedNoFree();
}
@ -1550,7 +1552,7 @@ struct AANoFreeCallSiteArgument final : AANoFreeFloating {
if (!Arg)
return indicatePessimisticFixpoint();
const IRPosition &ArgPos = IRPosition::argument(*Arg);
auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos);
auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), ArgAA.getState());
}
@ -1756,7 +1758,8 @@ struct AANonNullFloating : public AANonNullImpl {
auto VisitValueCB = [&](Value &V, const Instruction *CtxI,
AANonNull::StateType &T, bool Stripped) -> bool {
const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V),
DepClassTy::REQUIRED);
if (!Stripped && this == &AA) {
if (!isKnownNonZero(&V, DL, 0, AC, CtxI, DT))
T.indicatePessimisticFixpoint();
@ -1874,8 +1877,8 @@ struct AANoRecurseFunction final : AANoRecurseImpl {
if (CB.hasFnAttr(Attribute::NoRecurse))
return true;
const auto &NoRecurseAA =
A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(CB));
const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(
*this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
if (!NoRecurseAA.isAssumedNoRecurse())
return false;
@ -1915,7 +1918,7 @@ struct AANoRecurseCallSite final : AANoRecurseImpl {
// redirecting requests to the callee argument.
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), FnAA.getState());
}
@ -2205,8 +2208,8 @@ private:
// use for specific processing.
Optional<Value *> stopOnUndefOrAssumed(Attributor &A, const Value *V,
Instruction *I) {
const auto &ValueSimplifyAA =
A.getAAFor<AAValueSimplify>(*this, IRPosition::value(*V));
const auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
*this, IRPosition::value(*V), DepClassTy::REQUIRED);
Optional<Value *> SimplifiedV =
ValueSimplifyAA.getAssumedSimplifiedValue(A);
if (!ValueSimplifyAA.isKnown()) {
@ -2290,12 +2293,14 @@ struct AAWillReturnImpl : public AAWillReturn {
ChangeStatus updateImpl(Attributor &A) override {
auto CheckForWillReturn = [&](Instruction &I) {
IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I));
const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
const auto &WillReturnAA =
A.getAAFor<AAWillReturn>(*this, IPos, DepClassTy::REQUIRED);
if (WillReturnAA.isKnownWillReturn())
return true;
if (!WillReturnAA.isAssumedWillReturn())
return false;
const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
const auto &NoRecurseAA =
A.getAAFor<AANoRecurse>(*this, IPos, DepClassTy::REQUIRED);
return NoRecurseAA.isAssumedNoRecurse();
};
@ -2340,7 +2345,7 @@ struct AAWillReturnCallSite final : AAWillReturnImpl {
// redirecting requests to the callee argument.
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), FnAA.getState());
}
@ -2420,8 +2425,8 @@ struct AANoAliasFloating final : AANoAliasImpl {
Val->getType()->getPointerAddressSpace()))
indicateOptimisticFixpoint();
else if (Val != &getAssociatedValue()) {
const auto &ValNoAliasAA =
A.getAAFor<AANoAlias>(*this, IRPosition::value(*Val));
const auto &ValNoAliasAA = A.getAAFor<AANoAlias>(
*this, IRPosition::value(*Val), DepClassTy::OPTIONAL);
if (ValNoAliasAA.isKnownNoAlias())
indicateOptimisticFixpoint();
}
@ -2461,14 +2466,15 @@ struct AANoAliasArgument final
// function, otherwise we give up for now.
// If the function is no-sync, no-alias cannot break synchronization.
const auto &NoSyncAA = A.getAAFor<AANoSync>(
*this, IRPosition::function_scope(getIRPosition()));
const auto &NoSyncAA =
A.getAAFor<AANoSync>(*this, IRPosition::function_scope(getIRPosition()),
DepClassTy::OPTIONAL);
if (NoSyncAA.isAssumedNoSync())
return Base::updateImpl(A);
// If the argument is read-only, no-alias cannot break synchronization.
const auto &MemBehaviorAA =
A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
*this, getIRPosition(), DepClassTy::OPTIONAL);
if (MemBehaviorAA.isAssumedReadOnly())
return Base::updateImpl(A);
@ -2593,8 +2599,8 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
return true;
if (ScopeFn) {
const auto &ReachabilityAA =
A.getAAFor<AAReachability>(*this, IRPosition::function(*ScopeFn));
const auto &ReachabilityAA = A.getAAFor<AAReachability>(
*this, IRPosition::function(*ScopeFn), DepClassTy::OPTIONAL);
if (!ReachabilityAA.isAssumedReachable(A, *UserI, *getCtxI()))
return true;
@ -2605,7 +2611,8 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
unsigned ArgNo = CB->getArgOperandNo(&U);
const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
*this, IRPosition::callsite_argument(*CB, ArgNo));
*this, IRPosition::callsite_argument(*CB, ArgNo),
DepClassTy::OPTIONAL);
if (NoCaptureAA.isAssumedNoCapture())
return true;
@ -2703,11 +2710,13 @@ struct AANoAliasReturned final : AANoAliasImpl {
return false;
const IRPosition &RVPos = IRPosition::value(RV);
const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
const auto &NoAliasAA =
A.getAAFor<AANoAlias>(*this, RVPos, DepClassTy::REQUIRED);
if (!NoAliasAA.isAssumedNoAlias())
return false;
const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
const auto &NoCaptureAA =
A.getAAFor<AANoCapture>(*this, RVPos, DepClassTy::REQUIRED);
return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
};
@ -2742,7 +2751,7 @@ struct AANoAliasCallSiteReturned final : AANoAliasImpl {
// redirecting requests to the callee argument.
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::returned(*F);
auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), FnAA.getState());
}
@ -2932,7 +2941,7 @@ struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
if (!Arg)
return indicatePessimisticFixpoint();
const IRPosition &ArgPos = IRPosition::argument(*Arg);
auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), ArgAA.getState());
}
@ -3561,8 +3570,8 @@ struct AADereferenceableFloating : AADereferenceableImpl {
const Value *Base =
stripAndAccumulateMinimalOffsets(A, *this, &V, DL, Offset, false);
const auto &AA =
A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
const auto &AA = A.getAAFor<AADereferenceable>(
*this, IRPosition::value(*Base), DepClassTy::REQUIRED);
int64_t DerefBytes = 0;
if (!Stripped && this == &AA) {
// Use IR information if we did not strip anything.
@ -3842,7 +3851,8 @@ struct AAAlignFloating : AAAlignImpl {
auto VisitValueCB = [&](Value &V, const Instruction *,
AAAlign::StateType &T, bool Stripped) -> bool {
const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
DepClassTy::REQUIRED);
if (!Stripped && this == &AA) {
int64_t Offset;
unsigned Alignment = 1;
@ -4023,7 +4033,7 @@ struct AANoReturnCallSite final : AANoReturnImpl {
AANoReturnImpl::initialize(A);
if (Function *F = getAssociatedFunction()) {
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos, DepClassTy::REQUIRED);
if (!FnAA.isAssumedNoReturn())
indicatePessimisticFixpoint();
}
@ -4037,7 +4047,7 @@ struct AANoReturnCallSite final : AANoReturnImpl {
// redirecting requests to the callee argument.
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), FnAA.getState());
}
@ -4239,7 +4249,8 @@ struct AACaptureUseTracker final : public CaptureTracker {
const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
// If we have a abstract no-capture attribute for the argument we can use
// it to justify a non-capture attribute here. This allows recursion!
auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
auto &ArgNoCaptureAA =
A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos, DepClassTy::REQUIRED);
if (ArgNoCaptureAA.isAssumedNoCapture())
return isCapturedIn(/* Memory */ false, /* Integer */ false,
/* Return */ false);
@ -4423,7 +4434,7 @@ struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
if (!Arg)
return indicatePessimisticFixpoint();
const IRPosition &ArgPos = IRPosition::argument(*Arg);
auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), ArgAA.getState());
}
@ -4517,7 +4528,7 @@ struct AAValueSimplifyImpl : AAValueSimplify {
// FIXME: Add a typecast support.
auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
QueryingAA, IRPosition::value(QueryingValue));
QueryingAA, IRPosition::value(QueryingValue), DepClassTy::REQUIRED);
Optional<Value *> QueryingValueSimplified =
ValueSimplifyAA.getAssumedSimplifiedValue(A);
@ -4651,7 +4662,8 @@ struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
if (Arg->hasByValAttr()) {
// TODO: We probably need to verify synchronization is not an issue, e.g.,
// there is no race by not copying a constant byval.
const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(),
DepClassTy::REQUIRED);
if (!MemAA.isAssumedReadOnly())
return indicatePessimisticFixpoint();
}
@ -4818,7 +4830,8 @@ struct AAValueSimplifyFloating : AAValueSimplifyImpl {
// The index is the operand that we assume is not null.
unsigned PtrIdx = Op0IsNull;
auto &PtrNonNullAA = A.getAAFor<AANonNull>(
*this, IRPosition::value(*ICmp->getOperand(PtrIdx)));
*this, IRPosition::value(*ICmp->getOperand(PtrIdx)),
DepClassTy::REQUIRED);
if (!PtrNonNullAA.isAssumedNonNull())
return false;
@ -4851,7 +4864,8 @@ struct AAValueSimplifyFloating : AAValueSimplifyImpl {
auto VisitValueCB = [&](Value &V, const Instruction *CtxI, bool &,
bool Stripped) -> bool {
auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V),
DepClassTy::REQUIRED);
if (!Stripped && this == &AA) {
// TODO: Look the instruction and check recursively.
@ -5107,11 +5121,13 @@ ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
unsigned ArgNo = CB->getArgOperandNo(&U);
const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
*this, IRPosition::callsite_argument(*CB, ArgNo));
*this, IRPosition::callsite_argument(*CB, ArgNo),
DepClassTy::REQUIRED);
// If a callsite argument use is nofree, we are fine.
const auto &ArgNoFreeAA = A.getAAFor<AANoFree>(
*this, IRPosition::callsite_argument(*CB, ArgNo));
*this, IRPosition::callsite_argument(*CB, ArgNo),
DepClassTy::REQUIRED);
if (!NoCaptureAA.isAssumedNoCapture() ||
!ArgNoFreeAA.isAssumedNoFree()) {
@ -5277,7 +5293,8 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
return false;
// Check that all call sites agree on a type.
auto &PrivCSArgAA = A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos);
auto &PrivCSArgAA =
A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
Optional<Type *> CSTy = PrivCSArgAA.getPrivatizableType();
LLVM_DEBUG({
@ -5394,8 +5411,8 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
if (CBArgNo != int(ArgNo))
continue;
const auto &CBArgPrivAA =
A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(CBArg));
const auto &CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
*this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
if (CBArgPrivAA.isValidState()) {
auto CBArgPrivTy = CBArgPrivAA.getPrivatizableType();
if (!CBArgPrivTy.hasValue())
@ -5441,7 +5458,8 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
Function *DCCallee = DC->getCalledFunction();
if (unsigned(DCArgNo) < DCCallee->arg_size()) {
const auto &DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
*this, IRPosition::argument(*DCCallee->getArg(DCArgNo)));
*this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
DepClassTy::REQUIRED);
if (DCArgPrivAA.isValidState()) {
auto DCArgPrivTy = DCArgPrivAA.getPrivatizableType();
if (!DCArgPrivTy.hasValue())
@ -5606,7 +5624,8 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
Argument *Arg = getAssociatedArgument();
// Query AAAlign attribute for alignment of associated argument to
// determine the best alignment of loads.
const auto &AlignAA = A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg));
const auto &AlignAA =
A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
// Callback to repair the associated function. A new alloca is placed at the
// beginning and initialized with the values passed through arguments. The
@ -5693,8 +5712,8 @@ struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
if (CI->isOne())
return Obj->getType()->getPointerElementType();
if (auto *Arg = dyn_cast<Argument>(Obj)) {
auto &PrivArgAA =
A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(*Arg));
auto &PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
*this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
if (PrivArgAA.isAssumedPrivatizablePtr())
return Obj->getType()->getPointerElementType();
}
@ -5731,19 +5750,21 @@ struct AAPrivatizablePtrCallSiteArgument final
return indicatePessimisticFixpoint();
const IRPosition &IRP = getIRPosition();
auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
auto &NoCaptureAA =
A.getAAFor<AANoCapture>(*this, IRP, DepClassTy::REQUIRED);
if (!NoCaptureAA.isAssumedNoCapture()) {
LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
return indicatePessimisticFixpoint();
}
auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP, DepClassTy::REQUIRED);
if (!NoAliasAA.isAssumedNoAlias()) {
LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
return indicatePessimisticFixpoint();
}
const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, IRP);
const auto &MemBehaviorAA =
A.getAAFor<AAMemoryBehavior>(*this, IRP, DepClassTy::REQUIRED);
if (!MemBehaviorAA.isAssumedReadOnly()) {
LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
return indicatePessimisticFixpoint();
@ -6015,7 +6036,8 @@ struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
// redirecting requests to the callee argument.
Argument *Arg = getAssociatedArgument();
const IRPosition &ArgPos = IRPosition::argument(*Arg);
auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
auto &ArgAA =
A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), ArgAA.getState());
}
@ -6104,7 +6126,8 @@ struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
// redirecting requests to the callee argument.
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
auto &FnAA =
A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::REQUIRED);
return clampStateAndIndicateChange(getState(), FnAA.getState());
}
@ -6130,7 +6153,7 @@ ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
// state is as optimistic as it gets.
if (const auto *CB = dyn_cast<CallBase>(&I)) {
const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
*this, IRPosition::callsite_function(*CB));
*this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED);
intersectAssumedBits(MemBehaviorAA.getAssumed());
return !isAtFixpoint();
}
@ -6653,8 +6676,8 @@ void AAMemoryLocationImpl::categorizePtrValue(
} else if (isa<AllocaInst>(V)) {
MLK = NO_LOCAL_MEM;
} else if (const auto *CB = dyn_cast<CallBase>(&V)) {
const auto &NoAliasAA =
A.getAAFor<AANoAlias>(*this, IRPosition::callsite_returned(*CB));
const auto &NoAliasAA = A.getAAFor<AANoAlias>(
*this, IRPosition::callsite_returned(*CB), DepClassTy::OPTIONAL);
if (NoAliasAA.isAssumedNoAlias())
MLK = NO_MALLOCED_MEM;
else
@ -6724,8 +6747,8 @@ AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
if (auto *CB = dyn_cast<CallBase>(&I)) {
// First check if we assume any memory is access is visible.
const auto &CBMemLocationAA =
A.getAAFor<AAMemoryLocation>(*this, IRPosition::callsite_function(*CB));
const auto &CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
*this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
<< " [" << CBMemLocationAA << "]\n");
@ -6872,7 +6895,8 @@ struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
// redirecting requests to the callee argument.
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AAMemoryLocation>(*this, FnPos);
auto &FnAA =
A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
bool Changed = false;
auto AccessPred = [&](const Instruction *I, const Value *Ptr,
AccessKind Kind, MemoryLocationsKind MLK) {
@ -7179,13 +7203,13 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
return false;
auto &LHSAA =
A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
auto &LHSAA = A.getAAFor<AAValueConstantRange>(
*this, IRPosition::value(*LHS), DepClassTy::REQUIRED);
QuerriedAAs.push_back(&LHSAA);
auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
auto &RHSAA =
A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
auto &RHSAA = A.getAAFor<AAValueConstantRange>(
*this, IRPosition::value(*RHS), DepClassTy::REQUIRED);
QuerriedAAs.push_back(&RHSAA);
auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
@ -7208,8 +7232,8 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
if (!OpV.getType()->isIntegerTy())
return false;
auto &OpAA =
A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(OpV));
auto &OpAA = A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(OpV),
DepClassTy::REQUIRED);
QuerriedAAs.push_back(&OpAA);
T.unionAssumed(
OpAA.getAssumed().castOp(CastI->getOpcode(), getState().getBitWidth()));
@ -7226,11 +7250,11 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
return false;
auto &LHSAA =
A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
auto &LHSAA = A.getAAFor<AAValueConstantRange>(
*this, IRPosition::value(*LHS), DepClassTy::REQUIRED);
QuerriedAAs.push_back(&LHSAA);
auto &RHSAA =
A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
auto &RHSAA = A.getAAFor<AAValueConstantRange>(
*this, IRPosition::value(*RHS), DepClassTy::REQUIRED);
QuerriedAAs.push_back(&RHSAA);
auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
@ -7279,8 +7303,8 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
if (!I || isa<CallBase>(I)) {
// If the value is not instruction, we query AA to Attributor.
const auto &AA =
A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(V));
const auto &AA = A.getAAFor<AAValueConstantRange>(
*this, IRPosition::value(V), DepClassTy::REQUIRED);
// Clamp operator is not used to utilize a program point CtxI.
T.unionAssumed(AA.getAssumedConstantRange(A, CtxI));
@ -7612,11 +7636,13 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl {
if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
return indicatePessimisticFixpoint();
auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS),
DepClassTy::REQUIRED);
if (!LHSAA.isValidState())
return indicatePessimisticFixpoint();
auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS),
DepClassTy::REQUIRED);
if (!RHSAA.isValidState())
return indicatePessimisticFixpoint();
@ -7674,11 +7700,13 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl {
return indicatePessimisticFixpoint();
// TODO: Use assumed simplified condition value
auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS),
DepClassTy::REQUIRED);
if (!LHSAA.isValidState())
return indicatePessimisticFixpoint();
auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS),
DepClassTy::REQUIRED);
if (!RHSAA.isValidState())
return indicatePessimisticFixpoint();
@ -7700,7 +7728,8 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl {
assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
Value *Src = CI->getOperand(0);
auto &SrcAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*Src));
auto &SrcAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*Src),
DepClassTy::REQUIRED);
if (!SrcAA.isValidState())
return indicatePessimisticFixpoint();
const DenseSet<APInt> &SrcAAPVS = SrcAA.getAssumedSet();
@ -7723,11 +7752,13 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl {
if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
return indicatePessimisticFixpoint();
auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS),
DepClassTy::REQUIRED);
if (!LHSAA.isValidState())
return indicatePessimisticFixpoint();
auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS),
DepClassTy::REQUIRED);
if (!RHSAA.isValidState())
return indicatePessimisticFixpoint();
@ -7766,7 +7797,7 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl {
for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
Value *IncomingValue = PHI->getIncomingValue(u);
auto &PotentialValuesAA = A.getAAFor<AAPotentialValues>(
*this, IRPosition::value(*IncomingValue));
*this, IRPosition::value(*IncomingValue), DepClassTy::REQUIRED);
if (!PotentialValuesAA.isValidState())
return indicatePessimisticFixpoint();
if (PotentialValuesAA.undefIsContained())
@ -7870,7 +7901,8 @@ struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
ChangeStatus updateImpl(Attributor &A) override {
Value &V = getAssociatedValue();
auto AssumedBefore = getAssumed();
auto &AA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(V));
auto &AA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(V),
DepClassTy::REQUIRED);
const auto &S = AA.getAssumed();
unionAssumed(S);
return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
@ -7963,7 +7995,8 @@ struct AANoUndefFloating : public AANoUndefImpl {
ChangeStatus updateImpl(Attributor &A) override {
auto VisitValueCB = [&](Value &V, const Instruction *CtxI,
AANoUndef::StateType &T, bool Stripped) -> bool {
const auto &AA = A.getAAFor<AANoUndef>(*this, IRPosition::value(V));
const auto &AA = A.getAAFor<AANoUndef>(*this, IRPosition::value(V),
DepClassTy::REQUIRED);
if (!Stripped && this == &AA) {
T.indicatePessimisticFixpoint();
} else {

View File

@ -703,8 +703,8 @@ private:
// Emit a load instruction and replace the use of the output value
// with it.
for (Instruction *UsrI : OutsideUsers) {
LoadInst *LoadI = new LoadInst(I.getType(), AllocaI,
I.getName() + ".seq.output.load", UsrI);
LoadInst *LoadI = new LoadInst(
I.getType(), AllocaI, I.getName() + ".seq.output.load", UsrI);
UsrI->replaceUsesOfWith(&I, LoadI);
}
}
@ -1955,8 +1955,8 @@ struct AAICVTrackerFunction : public AAICVTracker {
if (CalledFunction->isDeclaration())
return nullptr;
const auto &ICVTrackingAA =
A.getAAFor<AAICVTracker>(*this, IRPosition::callsite_returned(*CB));
const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
*this, IRPosition::callsite_returned(*CB), DepClassTy::REQUIRED);
if (ICVTrackingAA.isAssumedTracked())
return ICVTrackingAA.getUniqueReplacementValue(ICV);
@ -2072,7 +2072,7 @@ struct AAICVTrackerFunctionReturned : AAICVTracker {
ChangeStatus updateImpl(Attributor &A) override {
ChangeStatus Changed = ChangeStatus::UNCHANGED;
const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
*this, IRPosition::function(*getAnchorScope()));
*this, IRPosition::function(*getAnchorScope()), DepClassTy::REQUIRED);
if (!ICVTrackingAA.isAssumedTracked())
return indicatePessimisticFixpoint();
@ -2155,7 +2155,7 @@ struct AAICVTrackerCallSite : AAICVTracker {
ChangeStatus updateImpl(Attributor &A) override {
const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
*this, IRPosition::function(*getAnchorScope()));
*this, IRPosition::function(*getAnchorScope()), DepClassTy::REQUIRED);
// We don't have any information, so we assume it changes the ICV.
if (!ICVTrackingAA.isAssumedTracked())
@ -2211,7 +2211,8 @@ struct AAICVTrackerCallSiteReturned : AAICVTracker {
ChangeStatus updateImpl(Attributor &A) override {
ChangeStatus Changed = ChangeStatus::UNCHANGED;
const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
*this, IRPosition::returned(*getAssociatedFunction()));
*this, IRPosition::returned(*getAssociatedFunction()),
DepClassTy::REQUIRED);
// We don't have any information, so we assume it changes the ICV.
if (!ICVTrackingAA.isAssumedTracked())

View File

@ -83,66 +83,127 @@ entry:
}
define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %N, float* dereferenceable(4) %p, i64 %q) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
; CHECK-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8
; CHECK-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8
; CHECK-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double*
; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4
; CHECK-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2
; CHECK-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
; CHECK: omp.precond.then:
; CHECK-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
; CHECK-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4
; CHECK-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
; CHECK-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
; CHECK-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1)
; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]]
; CHECK-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
; CHECK-NEXT: br label [[COND_END:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ]
; CHECK-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
; CHECK-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
; CHECK-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
; CHECK: omp.inner.for.cond:
; CHECK-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ]
; CHECK-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
; CHECK-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]]
; CHECK-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]]
; CHECK: omp.inner.for.cond.cleanup:
; CHECK-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
; CHECK: omp.inner.for.body:
; CHECK-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
; CHECK-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4
; CHECK-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8
; CHECK-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]])
; CHECK-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
; CHECK: omp.body.continue:
; CHECK-NEXT: br label [[OMP_INNER_FOR_INC]]
; CHECK: omp.inner.for.inc:
; CHECK-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1
; CHECK-NEXT: br label [[OMP_INNER_FOR_COND]]
; CHECK: omp.inner.for.end:
; CHECK-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
; CHECK: omp.loop.exit:
; CHECK-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
; CHECK-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]])
; CHECK-NEXT: br label [[OMP_PRECOND_END]]
; CHECK: omp.precond.end:
; CHECK-NEXT: ret void
; IS________OPM-LABEL: define {{[^@]+}}@.omp_outlined.
; IS________OPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) {
; IS________OPM-NEXT: entry:
; IS________OPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8
; IS________OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
; IS________OPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
; IS________OPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
; IS________OPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
; IS________OPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8
; IS________OPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double*
; IS________OPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4
; IS________OPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3
; IS________OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2
; IS________OPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
; IS________OPM: omp.precond.then:
; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
; IS________OPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4
; IS________OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
; IS________OPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1)
; IS________OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
; IS________OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]]
; IS________OPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; IS________OPM: cond.true:
; IS________OPM-NEXT: br label [[COND_END:%.*]]
; IS________OPM: cond.false:
; IS________OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
; IS________OPM-NEXT: br label [[COND_END]]
; IS________OPM: cond.end:
; IS________OPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ]
; IS________OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
; IS________OPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
; IS________OPM: omp.inner.for.cond:
; IS________OPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ]
; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
; IS________OPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]]
; IS________OPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]]
; IS________OPM: omp.inner.for.cond.cleanup:
; IS________OPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
; IS________OPM: omp.inner.for.body:
; IS________OPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
; IS________OPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4
; IS________OPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8
; IS________OPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]])
; IS________OPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
; IS________OPM: omp.body.continue:
; IS________OPM-NEXT: br label [[OMP_INNER_FOR_INC]]
; IS________OPM: omp.inner.for.inc:
; IS________OPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1
; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND]]
; IS________OPM: omp.inner.for.end:
; IS________OPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
; IS________OPM: omp.loop.exit:
; IS________OPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
; IS________OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]])
; IS________OPM-NEXT: br label [[OMP_PRECOND_END]]
; IS________OPM: omp.precond.end:
; IS________OPM-NEXT: ret void
;
; IS________NPM-LABEL: define {{[^@]+}}@.omp_outlined.
; IS________NPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) {
; IS________NPM-NEXT: entry:
; IS________NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8
; IS________NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
; IS________NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
; IS________NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
; IS________NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
; IS________NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8
; IS________NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double*
; IS________NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4
; IS________NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3
; IS________NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2
; IS________NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
; IS________NPM: omp.precond.then:
; IS________NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
; IS________NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4
; IS________NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
; IS________NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
; IS________NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
; IS________NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1)
; IS________NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
; IS________NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]]
; IS________NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; IS________NPM: cond.true:
; IS________NPM-NEXT: br label [[COND_END:%.*]]
; IS________NPM: cond.false:
; IS________NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
; IS________NPM-NEXT: br label [[COND_END]]
; IS________NPM: cond.end:
; IS________NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ]
; IS________NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
; IS________NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
; IS________NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
; IS________NPM: omp.inner.for.cond:
; IS________NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ]
; IS________NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
; IS________NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]]
; IS________NPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]]
; IS________NPM: omp.inner.for.cond.cleanup:
; IS________NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
; IS________NPM: omp.inner.for.body:
; IS________NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
; IS________NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4
; IS________NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8
; IS________NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]])
; IS________NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
; IS________NPM: omp.body.continue:
; IS________NPM-NEXT: br label [[OMP_INNER_FOR_INC]]
; IS________NPM: omp.inner.for.inc:
; IS________NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1
; IS________NPM-NEXT: br label [[OMP_INNER_FOR_COND]]
; IS________NPM: omp.inner.for.end:
; IS________NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
; IS________NPM: omp.loop.exit:
; IS________NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
; IS________NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]])
; IS________NPM-NEXT: br label [[OMP_PRECOND_END]]
; IS________NPM: omp.precond.end:
; IS________NPM-NEXT: ret void
;
entry:
%q.addr = alloca i64, align 8