diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -2808,6 +2808,20 @@ /// in the `updateImpl` method. virtual void initialize(Attributor &A) {} + /// A query AA is always scheduled as long as we do updates because it does + /// lazy computation that cannot be determined to be done from the outside. + /// To determine if we are done, query AAs also need to overwrite the + /// `hasNewQueries` interface. + virtual bool isQueryAA() const { return false; } + + /// Returns true if a query AA has received new queries since the last update + /// call. This means we cannot stop iterating as the new queries have been + /// answered optimistically and we do not know if their state is fix yet. + /// Only needs to be implemented by query AAs (see `isQueryAA`). + virtual bool hasNewQueries() const { + llvm_unreachable("A query AA needs to overwrite this function!"); + } + /// Return the internal abstract state for inspection. virtual StateType &getState() = 0; virtual const StateType &getState() const = 0; @@ -4615,6 +4629,9 @@ AAFunctionReachability(const IRPosition &IRP, Attributor &A) : Base(IRP) {} + /// See AbstractAttribute::isQueryAA. + bool isQueryAA() const override { return true; } + /// If the function represented by this possition can reach \p Fn. virtual bool canReach(Attributor &A, const Function &Fn) const = 0; diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -1438,10 +1438,12 @@ else MaxFixedPointIterations = SetFixpointIterations; + SmallVector QueryAAs; SmallVector ChangedAAs; SetVector Worklist, InvalidAAs; Worklist.insert(DG.SyntheticRoot.begin(), DG.SyntheticRoot.end()); + bool DoneIterating; do { // Remember the size to determine new attributes. size_t NumAAs = DG.SyntheticRoot.Deps.size(); @@ -1496,9 +1498,12 @@ // changed. for (AbstractAttribute *AA : Worklist) { const auto &AAState = AA->getState(); - if (!AAState.isAtFixpoint()) + if (!AAState.isAtFixpoint()) { if (updateAA(*AA) == ChangeStatus::CHANGED) ChangedAAs.push_back(AA); + else if (AA->isQueryAA()) + QueryAAs.push_back(AA); + } // Use the InvalidAAs vector to propagate invalid states fast transitively // without requiring updates. @@ -1514,10 +1519,18 @@ // Reset the work list and repopulate with the changed abstract attributes. // Note that dependent ones are added above. Worklist.clear(); + Worklist.insert(QueryAAs.begin(), QueryAAs.end()); Worklist.insert(ChangedAAs.begin(), ChangedAAs.end()); + QueryAAs.clear(); + + bool HasChangedAAs = !ChangedAAs.empty(); + DoneIterating = !HasChangedAAs && + !llvm::any_of(QueryAAs, [](AbstractAttribute *QueryAA) { + return QueryAA->hasNewQueries(); + }); - } while (!Worklist.empty() && (IterationCounter++ < MaxFixedPointIterations || - VerifyMaxFixpointIterations)); + } while (!DoneIterating && (IterationCounter++ < MaxFixedPointIterations || + VerifyMaxFixpointIterations)); if (IterationCounter > MaxFixedPointIterations && !Worklist.empty()) { auto Remark = [&](OptimizationRemarkMissed ORM) { @@ -1975,11 +1988,13 @@ auto &AAState = AA.getState(); ChangeStatus CS = ChangeStatus::UNCHANGED; bool UsedAssumedInformation = false; - if (!isAssumedDead(AA, nullptr, UsedAssumedInformation, - /* CheckBBLivenessOnly */ true)) + bool IsQueryAA = AA.isQueryAA(); + + if (IsQueryAA || !isAssumedDead(AA, nullptr, UsedAssumedInformation, + /* CheckBBLivenessOnly */ true)) CS = AA.update(*this); - if (DV.empty()) { + if (!IsQueryAA && DV.empty()) { // If the attribute did not query any non-fix information, the state // will not change and we can indicate that right away. AAState.indicateOptimisticFixpoint(); diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -9582,6 +9582,10 @@ /// If we can reach a function with a call to a unknown function we assume /// that we can reach any function. bool CanReachUnknownCallee = false; + + /// Flag to indicate this query set contains new queries not present during + /// the last update. + bool HasNewQueries = false; }; struct QueryResolver : public QuerySet { @@ -9589,6 +9593,9 @@ ArrayRef AAEdgesList) { ChangeStatus Change = ChangeStatus::UNCHANGED; + // All queries are now known, nothing is new anymore. + HasNewQueries = false; + for (auto *AAEdges : AAEdgesList) { if (AAEdges->hasUnknownCallee()) { if (!CanReachUnknownCallee) @@ -9614,6 +9621,10 @@ if (Cached.hasValue()) return Cached.getValue(); + // The query was not cached, thus it is new, remember that to avoid the + // fixpoint iteration to stop before we could properly update the query. + HasNewQueries = true; + // We need to assume that this function can't reach Fn to prevent // an infinite loop if this function is recursive. Unreachable.insert(&Fn); @@ -9726,6 +9737,16 @@ AAFunctionReachabilityFunction(const IRPosition &IRP, Attributor &A) : AAFunctionReachability(IRP, A) {} + /// See AbstractAttribute::hasNewQueries. + bool hasNewQueries() const override { + if (WholeFunction.HasNewQueries) + return true; + for (const auto &It : CBQueries) + if (It.second.HasNewQueries) + return true; + return false; + } + bool canReach(Attributor &A, const Function &Fn) const override { const AACallEdges &AAEdges = A.getAAFor(*this, getIRPosition(), DepClassTy::REQUIRED); diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll @@ -53,9 +53,8 @@ ; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef, i64 undef) ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: norecurse ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo -; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: [[P:%.*]] = alloca float, align 4 @@ -64,9 +63,8 @@ ; IS__CGSCC_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[P]], i64 noundef 4617315517961601024) ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: norecurse ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo -; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: [[P:%.*]] = alloca float, align 4 @@ -86,247 +84,125 @@ } define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %N, float* dereferenceable(4) %p, i64 %q) { -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@.omp_outlined. -; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { -; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 -; IS__TUNIT_OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 -; IS__TUNIT_OPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 -; IS__TUNIT_OPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 -; IS__TUNIT_OPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 -; IS__TUNIT_OPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 -; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* -; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 -; IS__TUNIT_OPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 -; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 -; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] -; IS__TUNIT_OPM: omp.precond.then: -; IS__TUNIT_OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 -; IS__TUNIT_OPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 -; IS__TUNIT_OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 -; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__TUNIT_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__TUNIT_OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] -; IS__TUNIT_OPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; IS__TUNIT_OPM: cond.true: -; IS__TUNIT_OPM-NEXT: br label [[COND_END:%.*]] -; IS__TUNIT_OPM: cond.false: -; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_OPM-NEXT: br label [[COND_END]] -; IS__TUNIT_OPM: cond.end: -; IS__TUNIT_OPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] -; IS__TUNIT_OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_OPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 -; IS__TUNIT_OPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] -; IS__TUNIT_OPM: omp.inner.for.cond: -; IS__TUNIT_OPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] -; IS__TUNIT_OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_OPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] -; IS__TUNIT_OPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] -; IS__TUNIT_OPM: omp.inner.for.cond.cleanup: -; IS__TUNIT_OPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] -; IS__TUNIT_OPM: omp.inner.for.body: -; IS__TUNIT_OPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 -; IS__TUNIT_OPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 -; IS__TUNIT_OPM-NEXT: call void @bar(i32 [[ADD10]], float 3.000000e+00, double [[TMP11]]) -; IS__TUNIT_OPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] -; IS__TUNIT_OPM: omp.body.continue: -; IS__TUNIT_OPM-NEXT: br label [[OMP_INNER_FOR_INC]] -; IS__TUNIT_OPM: omp.inner.for.inc: -; IS__TUNIT_OPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 -; IS__TUNIT_OPM-NEXT: br label [[OMP_INNER_FOR_COND]] -; IS__TUNIT_OPM: omp.inner.for.end: -; IS__TUNIT_OPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] -; IS__TUNIT_OPM: omp.loop.exit: -; IS__TUNIT_OPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__TUNIT_OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 [[TMP12]]) -; IS__TUNIT_OPM-NEXT: br label [[OMP_PRECOND_END]] -; IS__TUNIT_OPM: omp.precond.end: -; IS__TUNIT_OPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS________OPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree nonnull readnone 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: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 +; IS________OPM-NEXT: call void @bar(i32 [[ADD10]], float 3.000000e+00, 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__TUNIT_NPM-LABEL: define {{[^@]+}}@.omp_outlined. -; IS__TUNIT_NPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 -; IS__TUNIT_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 -; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 -; IS__TUNIT_NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 -; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 -; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] -; IS__TUNIT_NPM: omp.precond.then: -; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 -; IS__TUNIT_NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 -; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__TUNIT_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__TUNIT_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] -; IS__TUNIT_NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; IS__TUNIT_NPM: cond.true: -; IS__TUNIT_NPM-NEXT: br label [[COND_END:%.*]] -; IS__TUNIT_NPM: cond.false: -; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: br label [[COND_END]] -; IS__TUNIT_NPM: cond.end: -; IS__TUNIT_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] -; IS__TUNIT_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 -; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] -; IS__TUNIT_NPM: omp.inner.for.cond: -; IS__TUNIT_NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] -; IS__TUNIT_NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] -; IS__TUNIT_NPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] -; IS__TUNIT_NPM: omp.inner.for.cond.cleanup: -; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] -; IS__TUNIT_NPM: omp.inner.for.body: -; IS__TUNIT_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 -; IS__TUNIT_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 -; IS__TUNIT_NPM-NEXT: call void @bar(i32 [[ADD10]], float 3.000000e+00, double [[TMP11]]) -; IS__TUNIT_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] -; IS__TUNIT_NPM: omp.body.continue: -; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_INC]] -; IS__TUNIT_NPM: omp.inner.for.inc: -; IS__TUNIT_NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 -; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND]] -; IS__TUNIT_NPM: omp.inner.for.end: -; IS__TUNIT_NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] -; IS__TUNIT_NPM: omp.loop.exit: -; IS__TUNIT_NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__TUNIT_NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 [[TMP12]]) -; IS__TUNIT_NPM-NEXT: br label [[OMP_PRECOND_END]] -; IS__TUNIT_NPM: omp.precond.end: -; IS__TUNIT_NPM-NEXT: ret void -; -; IS__CGSCC_OPM: Function Attrs: norecurse -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@.omp_outlined. -; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) #[[ATTR0]] { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 -; IS__CGSCC_OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 -; IS__CGSCC_OPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 -; IS__CGSCC_OPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 -; IS__CGSCC_OPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 -; IS__CGSCC_OPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 -; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* -; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 -; IS__CGSCC_OPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 -; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 -; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] -; IS__CGSCC_OPM: omp.precond.then: -; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 -; IS__CGSCC_OPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 -; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 -; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__CGSCC_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__CGSCC_OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] -; IS__CGSCC_OPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; IS__CGSCC_OPM: cond.true: -; IS__CGSCC_OPM-NEXT: br label [[COND_END:%.*]] -; IS__CGSCC_OPM: cond.false: -; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_OPM-NEXT: br label [[COND_END]] -; IS__CGSCC_OPM: cond.end: -; IS__CGSCC_OPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] -; IS__CGSCC_OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_OPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 -; IS__CGSCC_OPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] -; IS__CGSCC_OPM: omp.inner.for.cond: -; IS__CGSCC_OPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] -; IS__CGSCC_OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_OPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] -; IS__CGSCC_OPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] -; IS__CGSCC_OPM: omp.inner.for.cond.cleanup: -; IS__CGSCC_OPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] -; IS__CGSCC_OPM: omp.inner.for.body: -; IS__CGSCC_OPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 -; IS__CGSCC_OPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 -; IS__CGSCC_OPM-NEXT: call void @bar(i32 [[ADD10]], float 3.000000e+00, double [[TMP11]]) -; IS__CGSCC_OPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] -; IS__CGSCC_OPM: omp.body.continue: -; IS__CGSCC_OPM-NEXT: br label [[OMP_INNER_FOR_INC]] -; IS__CGSCC_OPM: omp.inner.for.inc: -; IS__CGSCC_OPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 -; IS__CGSCC_OPM-NEXT: br label [[OMP_INNER_FOR_COND]] -; IS__CGSCC_OPM: omp.inner.for.end: -; IS__CGSCC_OPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] -; IS__CGSCC_OPM: omp.loop.exit: -; IS__CGSCC_OPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__CGSCC_OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 [[TMP12]]) -; IS__CGSCC_OPM-NEXT: br label [[OMP_PRECOND_END]] -; IS__CGSCC_OPM: omp.precond.end: -; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: norecurse -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@.omp_outlined. -; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) #[[ATTR0]] { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 -; IS__CGSCC_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 -; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* -; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 -; IS__CGSCC_NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 -; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 -; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] -; IS__CGSCC_NPM: omp.precond.then: -; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 -; IS__CGSCC_NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 -; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__CGSCC_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__CGSCC_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] -; IS__CGSCC_NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; IS__CGSCC_NPM: cond.true: -; IS__CGSCC_NPM-NEXT: br label [[COND_END:%.*]] -; IS__CGSCC_NPM: cond.false: -; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_NPM-NEXT: br label [[COND_END]] -; IS__CGSCC_NPM: cond.end: -; IS__CGSCC_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] -; IS__CGSCC_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 -; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] -; IS__CGSCC_NPM: omp.inner.for.cond: -; IS__CGSCC_NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] -; IS__CGSCC_NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__CGSCC_NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] -; IS__CGSCC_NPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] -; IS__CGSCC_NPM: omp.inner.for.cond.cleanup: -; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] -; IS__CGSCC_NPM: omp.inner.for.body: -; IS__CGSCC_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 -; IS__CGSCC_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 -; IS__CGSCC_NPM-NEXT: call void @bar(i32 [[ADD10]], float 3.000000e+00, double [[TMP11]]) -; IS__CGSCC_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] -; IS__CGSCC_NPM: omp.body.continue: -; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_INC]] -; IS__CGSCC_NPM: omp.inner.for.inc: -; IS__CGSCC_NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 -; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_COND]] -; IS__CGSCC_NPM: omp.inner.for.end: -; IS__CGSCC_NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] -; IS__CGSCC_NPM: omp.loop.exit: -; IS__CGSCC_NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__CGSCC_NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 [[TMP12]]) -; IS__CGSCC_NPM-NEXT: br label [[OMP_PRECOND_END]] -; IS__CGSCC_NPM: omp.precond.end: -; IS__CGSCC_NPM-NEXT: ret void +; IS________NPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS________NPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree nonnull readnone 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: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 +; IS________NPM-NEXT: call void @bar(i32 [[ADD10]], float 3.000000e+00, 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 @@ -411,8 +287,6 @@ !1 = !{i64 2, i64 -1, i64 -1, i1 true} !0 = !{!1} ;. -; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { norecurse } -;. ; CHECK: [[META0:![0-9]+]] = !{!1} ; CHECK: [[META1:![0-9]+]] = !{i64 2, i64 -1, i64 -1, i1 true} ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll @@ -61,11 +61,19 @@ } define %0 @caller(i1 %Q) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller -; CHECK-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: ret [[TMP0]] [[X]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller +; IS__TUNIT____-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1:[0-9]+]] +; IS__TUNIT____-NEXT: ret [[TMP0]] [[X]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller +; IS__CGSCC____-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1:[0-9]+]] +; IS__CGSCC____-NEXT: [[M:%.*]] = add i32 undef, undef +; IS__CGSCC____-NEXT: [[N:%.*]] = add i32 undef, undef +; IS__CGSCC____-NEXT: ret [[TMP0]] [[X]] ; %X = call %0 @foo(i1 %Q) %A = extractvalue %0 %X, 0 @@ -97,10 +105,10 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2 ; IS__CGSCC____-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { -; IS__CGSCC____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1]] +; IS__CGSCC____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC____-NEXT: [[A:%.*]] = extractvalue [[TMP0]] [[X]], 0 ; IS__CGSCC____-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1 -; IS__CGSCC____-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]]) #[[ATTR1]] ; IS__CGSCC____-NEXT: [[C:%.*]] = extractvalue [[TMP0]] [[Y]], 0 ; IS__CGSCC____-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1 ; IS__CGSCC____-NEXT: [[M:%.*]] = add i32 [[A]], [[C]] @@ -125,6 +133,6 @@ ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/cgscc_bugs.ll b/llvm/test/Transforms/Attributor/cgscc_bugs.ll --- a/llvm/test/Transforms/Attributor/cgscc_bugs.ll +++ b/llvm/test/Transforms/Attributor/cgscc_bugs.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=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 -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-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 @@ -11,16 +11,10 @@ %2 = type opaque define hidden %0* @f1(i64 %0, i64 %1) { -; IS__TUNIT____: Function Attrs: norecurse -; IS__TUNIT____-LABEL: define {{[^@]+}}@f1 -; IS__TUNIT____-SAME: (i64 [[TMP0:%.*]], i64 [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] { -; IS__TUNIT____-NEXT: [[TMP3:%.*]] = call { %0*, i64 } @f3(i64 [[TMP0]]) -; IS__TUNIT____-NEXT: ret %0* undef -; -; IS__CGSCC____-LABEL: define {{[^@]+}}@f1 -; IS__CGSCC____-SAME: (i64 [[TMP0:%.*]], i64 [[TMP1:%.*]]) { -; IS__CGSCC____-NEXT: [[TMP3:%.*]] = call { %0*, i64 } @f3(i64 [[TMP0]]) -; IS__CGSCC____-NEXT: ret %0* undef +; CHECK-LABEL: define {{[^@]+}}@f1 +; CHECK-SAME: (i64 [[TMP0:%.*]], i64 [[TMP1:%.*]]) { +; CHECK-NEXT: [[TMP3:%.*]] = call { %0*, i64 } @f3(i64 [[TMP0]]) +; CHECK-NEXT: ret %0* undef ; %3 = call { %0*, i64 } @f3(i64 %0) ret %0* undef @@ -31,7 +25,7 @@ ; IS__TUNIT____-SAME: (i64 [[TMP0:%.*]]) align 2 { ; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @f4() ; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64 -; IS__TUNIT____-NEXT: call void @f5(i64 [[TMP3]], i64 [[TMP0]]) #[[ATTR3:[0-9]+]] +; IS__TUNIT____-NEXT: call void @f5(i64 [[TMP3]], i64 [[TMP0]]) #[[ATTR2:[0-9]+]] ; IS__TUNIT____-NEXT: ret { %0*, i64 } undef ; ; IS__CGSCC____-LABEL: define {{[^@]+}}@f3 @@ -57,16 +51,16 @@ define internal void @f5(i64 %0, i64 %1) { ; IS__TUNIT____: Function Attrs: norecurse nounwind ; IS__TUNIT____-LABEL: define {{[^@]+}}@f5 -; IS__TUNIT____-SAME: (i64 [[TMP0:%.*]], i64 [[TMP1:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__TUNIT____-SAME: (i64 [[TMP0:%.*]], i64 [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__TUNIT____-NEXT: br label [[TMP3:%.*]] ; IS__TUNIT____: 3: -; IS__TUNIT____-NEXT: call void @f6(i64 [[TMP0]]) #[[ATTR3]] +; IS__TUNIT____-NEXT: call void @f6(i64 [[TMP0]]) #[[ATTR2]] ; IS__TUNIT____-NEXT: [[TMP4:%.*]] = icmp sgt i64 [[TMP1]], [[TMP0]] ; IS__TUNIT____-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]] ; IS__TUNIT____: 5: ; IS__TUNIT____-NEXT: ret void ; IS__TUNIT____: 6: -; IS__TUNIT____-NEXT: call void @f5(i64 [[TMP0]], i64 [[TMP1]]) #[[ATTR3]] +; IS__TUNIT____-NEXT: call void @f5(i64 [[TMP0]], i64 [[TMP1]]) #[[ATTR2]] ; IS__TUNIT____-NEXT: br label [[TMP3]] ; ; IS__CGSCC____: Function Attrs: nounwind @@ -101,11 +95,11 @@ define internal void @f6(i64 %0) { ; IS__TUNIT____: Function Attrs: norecurse nounwind ; IS__TUNIT____-LABEL: define {{[^@]+}}@f6 -; IS__TUNIT____-SAME: (i64 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-SAME: (i64 [[TMP0:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sgt i64 [[TMP0]], 0 ; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; IS__TUNIT____: 3: -; IS__TUNIT____-NEXT: call void @llvm.trap() #[[ATTR4:[0-9]+]] +; IS__TUNIT____-NEXT: call void @llvm.trap() #[[ATTR3:[0-9]+]] ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: 4: ; IS__TUNIT____-NEXT: ret void @@ -138,11 +132,10 @@ attributes #0 = { cold noreturn nounwind } ;. -; IS__TUNIT____: attributes #[[ATTR0]] = { norecurse } -; IS__TUNIT____: attributes #[[ATTR1]] = { norecurse nounwind } -; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { cold noreturn nounwind } -; IS__TUNIT____: attributes #[[ATTR3]] = { nounwind } -; IS__TUNIT____: attributes #[[ATTR4]] = { noreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { norecurse nounwind } +; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind } +; IS__TUNIT____: attributes #[[ATTR2]] = { nounwind } +; IS__TUNIT____: attributes #[[ATTR3]] = { noreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nounwind } ; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind } diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll --- a/llvm/test/Transforms/Attributor/nonnull.ll +++ b/llvm/test/Transforms/Attributor/nonnull.ll @@ -36,10 +36,10 @@ ; CHECK-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14:[0-9]+]] [ "nonnull"(i8* [[RET]]) ] +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13:[0-9]+]] [ "nonnull"(i8* [[RET]]) ] ; CHECK-NEXT: ret i8* [[RET]] ; CHECK: B: -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14]] [ "nonnull"(i8* [[RET]]) ] +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[RET]]) ] ; CHECK-NEXT: ret i8* [[RET]] ; br i1 %c, label %A, label %B @@ -57,10 +57,10 @@ ; CHECK-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14]] [ "dereferenceable"(i8* [[RET]], i32 4) ] +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ] ; CHECK-NEXT: ret i8* [[RET]] ; CHECK: B: -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14]] [ "dereferenceable"(i8* [[RET]], i32 4) ] +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ] ; CHECK-NEXT: ret i8* [[RET]] ; br i1 %c, label %A, label %B @@ -250,7 +250,7 @@ ; CHECK: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@test10 ; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14]] +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] ; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]] ; CHECK-NEXT: ret i8* [[B]] ; @@ -309,8 +309,8 @@ ; CHECK-LABEL: define {{[^@]+}}@test13_helper() { ; CHECK-NEXT: [[NONNULLPTR:%.*]] = tail call nonnull i8* @ret_nonnull() ; CHECK-NEXT: [[MAYBENULLPTR:%.*]] = tail call i8* @unknown() -; CHECK-NEXT: tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]]) #[[ATTR8:[0-9]+]] -; CHECK-NEXT: tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]]) #[[ATTR8]] +; CHECK-NEXT: tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]]) #[[ATTR7:[0-9]+]] +; CHECK-NEXT: tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]]) #[[ATTR7]] ; CHECK-NEXT: ret void ; %nonnullptr = tail call i8* @ret_nonnull() @@ -324,9 +324,9 @@ ; CHECK: Function Attrs: norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@test13 ; CHECK-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) #[[ATTR4:[0-9]+]] { -; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) #[[ATTR8]] -; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) #[[ATTR8]] -; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) #[[ATTR8]] +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) #[[ATTR7]] +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) #[[ATTR7]] +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) #[[ATTR7]] ; CHECK-NEXT: ret void ; call void @use_i8_ptr(i8* %a) @@ -363,11 +363,11 @@ ; CHECK-NEXT: br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]] ; CHECK: bb4: ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 1 -; CHECK-NEXT: [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR15:[0-9]+]] +; CHECK-NEXT: [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR14:[0-9]+]] ; CHECK-NEXT: [[TMP5C:%.*]] = getelementptr inbounds i32, i32* [[TMP5B]], i64 -1 ; CHECK-NEXT: br label [[BB9]] ; CHECK: bb6: -; CHECK-NEXT: [[TMP7:%.*]] = tail call i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR16:[0-9]+]] +; CHECK-NEXT: [[TMP7:%.*]] = tail call i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR14]] ; CHECK-NEXT: ret i32* [[TMP7]] ; CHECK: bb9: ; CHECK-NEXT: [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to i32*), [[BB:%.*]] ] @@ -403,7 +403,7 @@ ; CHECK-LABEL: define {{[^@]+}}@f2 ; CHECK-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5]] { ; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = tail call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR16]] +; CHECK-NEXT: [[TMP:%.*]] = tail call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]] ; CHECK-NEXT: ret i32* [[TMP]] ; bb: @@ -413,11 +413,11 @@ define dso_local noalias i32* @f3(i32* %arg) { ; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull readonly %arg) -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly +; CHECK: Function Attrs: argmemonly nofree nosync nounwind readonly ; CHECK-LABEL: define {{[^@]+}}@f3 -; CHECK-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR6:[0-9]+]] { +; CHECK-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5]] { ; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR16]] +; CHECK-NEXT: [[TMP:%.*]] = call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]] ; CHECK-NEXT: ret i32* [[TMP]] ; bb: @@ -451,14 +451,14 @@ define void @f16(i8* %a, i8 * %b, i8 %c) { ; CHECK: Function Attrs: nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@f16 -; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR7:[0-9]+]] { +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; CHECK: if.then: -; CHECK-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* nonnull [[B]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* nonnull [[B]]) #[[ATTR6]] ; CHECK-NEXT: ret void ; CHECK: if.else: -; CHECK-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* [[B]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* [[B]]) #[[ATTR6]] ; CHECK-NEXT: ret void ; %cmp = icmp eq i8 %c, 0 @@ -481,17 +481,17 @@ ; ; CHECK: Function Attrs: nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@f17 -; CHECK-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR7]] { +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR6]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; CHECK: if.then: -; CHECK-NEXT: tail call void @fun0() #[[ATTR7]] +; CHECK-NEXT: tail call void @fun0() #[[ATTR6]] ; CHECK-NEXT: br label [[CONT:%.*]] ; CHECK: if.else: -; CHECK-NEXT: tail call void @fun0() #[[ATTR7]] +; CHECK-NEXT: tail call void @fun0() #[[ATTR6]] ; CHECK-NEXT: br label [[CONT]] ; CHECK: cont: -; CHECK-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR6]] ; CHECK-NEXT: ret void ; %cmp = icmp eq i8 %c, 0 @@ -520,26 +520,26 @@ define void @f18(i8* %a, i8* %b, i8 %c) { ; CHECK: Function Attrs: nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@f18 -; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR7]] { +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR6]] { ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[C]], 0 ; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; CHECK: if.then: -; CHECK-NEXT: tail call void @fun0() #[[ATTR7]] +; CHECK-NEXT: tail call void @fun0() #[[ATTR6]] ; CHECK-NEXT: br label [[CONT:%.*]] ; CHECK: if.else: -; CHECK-NEXT: tail call void @fun0() #[[ATTR7]] +; CHECK-NEXT: tail call void @fun0() #[[ATTR6]] ; CHECK-NEXT: br label [[CONT]] ; CHECK: cont: ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[C]], 1 ; CHECK-NEXT: br i1 [[CMP2]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]] ; CHECK: cont.then: -; CHECK-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR6]] ; CHECK-NEXT: br label [[CONT2:%.*]] ; CHECK: cont.else: -; CHECK-NEXT: tail call void @fun0() #[[ATTR7]] +; CHECK-NEXT: tail call void @fun0() #[[ATTR6]] ; CHECK-NEXT: br label [[CONT2]] ; CHECK: cont2: -; CHECK-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR6]] ; CHECK-NEXT: ret void ; %cmp1 = icmp eq i8 %c, 0 @@ -569,17 +569,17 @@ define void @f19(i8* %a, i8* %b, i8 %c) { ; CHECK: Function Attrs: nounwind ; CHECK-LABEL: define {{[^@]+}}@f19 -; CHECK-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]]) #[[ATTR8]] { +; CHECK-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]]) #[[ATTR7]] { ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[C]], 0 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP_BODY:%.*]], label [[LOOP_EXIT:%.*]] ; CHECK: loop.body: -; CHECK-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR8]] -; CHECK-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR8]] +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR7]] ; CHECK-NEXT: br label [[LOOP_HEADER]] ; CHECK: loop.exit: -; CHECK-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR8]] +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR7]] ; CHECK-NEXT: ret void ; br label %loop.header @@ -715,7 +715,7 @@ define i8 @parent7(i8* %a) { ; CHECK-LABEL: define {{[^@]+}}@parent7 ; CHECK-SAME: (i8* nonnull [[A:%.*]]) { -; CHECK-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR17:[0-9]+]] +; CHECK-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR15:[0-9]+]] ; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]]) ; CHECK-NEXT: ret i8 [[RET]] ; @@ -733,7 +733,7 @@ define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){ ; CHECK: Function Attrs: nounwind ; CHECK-LABEL: define {{[^@]+}}@parent8 -; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #[[ATTR8]] personality i8* bitcast (i32 (...)* @esfp to i8*) { +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #[[ATTR7]] personality i8* bitcast (i32 (...)* @esfp to i8*) { ; CHECK-NEXT: entry: ; CHECK-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]]) ; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]] @@ -774,7 +774,7 @@ ; Should't be able to derive nonnull based on gep. ; CHECK: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@gep1_no_null_opt -; CHECK-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR10:[0-9]+]] { +; CHECK-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR9:[0-9]+]] { ; CHECK-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1 ; CHECK-NEXT: ret i32* [[Q]] ; @@ -827,8 +827,8 @@ define internal void @called_by_weak(i32* %a) { ; CHECK: Function Attrs: nounwind ; CHECK-LABEL: define {{[^@]+}}@called_by_weak -; CHECK-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR8]] +; CHECK-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) #[[ATTR7]] { +; CHECK-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR7]] ; CHECK-NEXT: ret void ; call void @use_i32_ptr(i32* %a) @@ -840,7 +840,7 @@ ; ; CHECK-LABEL: define {{[^@]+}}@weak_caller ; CHECK-SAME: (i32* nonnull [[A:%.*]]) { -; CHECK-NEXT: call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR8]] +; CHECK-NEXT: call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR7]] ; CHECK-NEXT: ret void ; call void @called_by_weak(i32* %a) @@ -852,7 +852,7 @@ ; CHECK: Function Attrs: norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@control ; CHECK-SAME: (i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] { -; CHECK-NEXT: call void @use_i32_ptr(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR8]] +; CHECK-NEXT: call void @use_i32_ptr(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR7]] ; CHECK-NEXT: ret void ; call void @use_i32_ptr(i32* %a) @@ -862,7 +862,7 @@ define internal void @naked(i32* dereferenceable(4) %a) naked { ; CHECK: Function Attrs: naked ; CHECK-LABEL: define {{[^@]+}}@naked -; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR11:[0-9]+]] { +; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] { ; CHECK-NEXT: call void @use_i32_ptr(i32* [[A]]) ; CHECK-NEXT: ret void ; @@ -874,7 +874,7 @@ ; ; CHECK: Function Attrs: noinline optnone ; CHECK-LABEL: define {{[^@]+}}@optnone -; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR12:[0-9]+]] { +; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR11:[0-9]+]] { ; CHECK-NEXT: call void @use_i32_ptr(i32* [[A]]) ; CHECK-NEXT: ret void ; @@ -885,7 +885,7 @@ ; CHECK-LABEL: define {{[^@]+}}@make_live ; CHECK-SAME: (i32* noundef nonnull align 16 dereferenceable(8) [[A:%.*]]) { ; CHECK-NEXT: call void @naked(i32* noundef nonnull align 16 dereferenceable(8) [[A]]) -; CHECK-NEXT: call void @control(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR8]] +; CHECK-NEXT: call void @control(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR7]] ; CHECK-NEXT: call void @optnone(i32* noundef nonnull align 16 dereferenceable(8) [[A]]) ; CHECK-NEXT: ret void ; @@ -908,32 +908,32 @@ ; ; IS________OPM: Function Attrs: nounwind ; IS________OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1 -; IS________OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR8]] { +; IS________OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] { ; IS________OPM-NEXT: en: ; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 ; IS________OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] ; IS________OPM: ex: -; IS________OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR8]] +; IS________OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR7]] ; IS________OPM-NEXT: ret i32 [[TMP5]] ; IS________OPM: hd: ; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ] -; IS________OPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR8]] +; IS________OPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR7]] ; IS________OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 ; IS________OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] ; IS________OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] ; ; IS________NPM: Function Attrs: nounwind willreturn ; IS________NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1 -; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] { +; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] { ; IS________NPM-NEXT: en: ; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 ; IS________NPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] ; IS________NPM: ex: -; IS________NPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR7]] +; IS________NPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR6]] ; IS________NPM-NEXT: ret i32 [[TMP5]] ; IS________NPM: hd: ; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ] -; IS________NPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR7]] +; IS________NPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR6]] ; IS________NPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 ; IS________NPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] ; IS________NPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] @@ -958,16 +958,16 @@ ; ; IS________OPM: Function Attrs: nounwind ; IS________OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b -; IS________OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR8]] { +; IS________OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] { ; IS________OPM-NEXT: en: ; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 ; IS________OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] ; IS________OPM: ex: -; IS________OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR8]] +; IS________OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR7]] ; IS________OPM-NEXT: ret i32 [[TMP5]] ; IS________OPM: hd: ; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ] -; IS________OPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR8]] +; IS________OPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR7]] ; IS________OPM-NEXT: br label [[HD2]] ; IS________OPM: hd2: ; IS________OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 @@ -976,16 +976,16 @@ ; ; IS________NPM: Function Attrs: nounwind willreturn ; IS________NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b -; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] { +; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] { ; IS________NPM-NEXT: en: ; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 ; IS________NPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] ; IS________NPM: ex: -; IS________NPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR7]] +; IS________NPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR6]] ; IS________NPM-NEXT: ret i32 [[TMP5]] ; IS________NPM: hd: ; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ] -; IS________NPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR7]] +; IS________NPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR6]] ; IS________NPM-NEXT: br label [[HD2]] ; IS________NPM: hd2: ; IS________NPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 @@ -1015,16 +1015,16 @@ ; ; CHECK: Function Attrs: nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2 -; CHECK-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] { +; CHECK-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] { ; CHECK-NEXT: en: ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 ; CHECK-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] ; CHECK: ex: -; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR8]] +; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR7]] ; CHECK-NEXT: ret i32 [[TMP5]] ; CHECK: hd: ; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ] -; CHECK-NEXT: tail call void @h(i32* nonnull [[A]]) #[[ATTR8]] +; CHECK-NEXT: tail call void @h(i32* nonnull [[A]]) #[[ATTR7]] ; CHECK-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] ; CHECK-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] @@ -1049,16 +1049,16 @@ ; ; CHECK: Function Attrs: nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b -; CHECK-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] { +; CHECK-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] { ; CHECK-NEXT: en: ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 ; CHECK-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] ; CHECK: ex: -; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR8]] +; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR7]] ; CHECK-NEXT: ret i32 [[TMP5]] ; CHECK: hd: ; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ] -; CHECK-NEXT: tail call void @h(i32* nonnull [[A]]) #[[ATTR8]] +; CHECK-NEXT: tail call void @h(i32* nonnull [[A]]) #[[ATTR7]] ; CHECK-NEXT: br label [[HD2]] ; CHECK: hd2: ; CHECK-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 @@ -1202,8 +1202,8 @@ define i8* @mybasename(i8* nofree readonly %str) { ; CHECK: Function Attrs: nofree nounwind readonly willreturn ; CHECK-LABEL: define {{[^@]+}}@mybasename -; CHECK-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR13:[0-9]+]] { -; CHECK-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR17]] +; CHECK-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR12:[0-9]+]] { +; CHECK-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR15]] ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null ; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]] @@ -1226,8 +1226,8 @@ ; ; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_pos ; CHECK-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]]) { -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14]] [ "nonnull"(i8* [[ARG]]) ] -; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR8]] +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[ARG]]) ] +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR7]] ; CHECK-NEXT: [[TMP1:%.*]] = call i8* @unknown() ; CHECK-NEXT: ret void ; @@ -1253,13 +1253,13 @@ ; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_neg ; CHECK-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call i8* @unknown() -; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]]) #[[ATTR8]] +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]]) #[[ATTR7]] ; CHECK-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ] -; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR8]] +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR7]] ; CHECK-NEXT: [[TMP2:%.*]] = call i8* @unknown() -; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR8]] +; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR7]] ; CHECK-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ] -; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR8]] +; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR7]] ; CHECK-NEXT: ret void ; call i8* @unknown() @@ -1318,16 +1318,14 @@ ; CHECK: attributes #[[ATTR3]] = { noreturn } ; CHECK: attributes #[[ATTR4]] = { norecurse nounwind } ; CHECK: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly } -; CHECK: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind readonly } -; CHECK: attributes #[[ATTR7]] = { nounwind willreturn } -; CHECK: attributes #[[ATTR8]] = { nounwind } -; CHECK: attributes #[[ATTR9:[0-9]+]] = { nounwind readonly willreturn } -; CHECK: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; CHECK: attributes #[[ATTR11]] = { naked } -; CHECK: attributes #[[ATTR12]] = { noinline optnone } -; CHECK: attributes #[[ATTR13]] = { nofree nounwind readonly willreturn } -; CHECK: attributes #[[ATTR14]] = { willreturn } -; CHECK: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind readonly } -; CHECK: attributes #[[ATTR16]] = { nofree nosync nounwind readonly } -; CHECK: attributes #[[ATTR17]] = { readonly willreturn } +; CHECK: attributes #[[ATTR6]] = { nounwind willreturn } +; CHECK: attributes #[[ATTR7]] = { nounwind } +; CHECK: attributes #[[ATTR8:[0-9]+]] = { nounwind readonly willreturn } +; CHECK: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } +; CHECK: attributes #[[ATTR10]] = { naked } +; CHECK: attributes #[[ATTR11]] = { noinline optnone } +; CHECK: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn } +; CHECK: attributes #[[ATTR13]] = { willreturn } +; CHECK: attributes #[[ATTR14]] = { nofree nosync nounwind readonly } +; CHECK: attributes #[[ATTR15]] = { readonly willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/openmp_parallel.ll b/llvm/test/Transforms/Attributor/openmp_parallel.ll --- a/llvm/test/Transforms/Attributor/openmp_parallel.ll +++ b/llvm/test/Transforms/Attributor/openmp_parallel.ll @@ -45,7 +45,7 @@ ; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB2]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float**, float**)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef, float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A_ADDR]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B_ADDR]]) ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: norecurse nounwind uwtable +; IS__CGSCC_OPM: Function Attrs: nounwind uwtable ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@func ; IS__CGSCC_OPM-SAME: (float* nocapture nofree [[A:%.*]], float* nofree [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: @@ -57,7 +57,7 @@ ; IS__CGSCC_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB2]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float**, float**)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[N_ADDR]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A_ADDR]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B_ADDR]]) ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: norecurse nounwind uwtable +; IS__CGSCC_NPM: Function Attrs: nounwind uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@func ; IS__CGSCC_NPM-SAME: (float* nocapture nofree [[A:%.*]], float* nofree [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: @@ -284,13 +284,9 @@ !1 = !{!2} !2 = !{i64 2, i64 -1, i64 -1, i1 true} ;. -; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { nounwind uwtable } -; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { alwaysinline nofree norecurse nounwind uwtable } -; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } -;. -; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { norecurse nounwind uwtable } -; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { alwaysinline nofree norecurse nounwind uwtable } -; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } +; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind uwtable } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { alwaysinline nofree norecurse nounwind uwtable } +; CHECK: attributes #[[ATTR2:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } ;. ; CHECK: [[META0:![0-9]+]] = !{i32 7, !"openmp", i32 50} ; CHECK: [[META1:![0-9]+]] = !{!2} diff --git a/llvm/test/Transforms/Attributor/potential.ll b/llvm/test/Transforms/Attributor/potential.ll --- a/llvm/test/Transforms/Attributor/potential.ll +++ b/llvm/test/Transforms/Attributor/potential.ll @@ -548,58 +548,34 @@ } define i32 @potential_test13_caller1() { -; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 -; IS__TUNIT_OPM-SAME: () #[[ATTR0]] { -; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]], !range [[RNG2]] -; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] -; -; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 -; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { -; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR1]], !range [[RNG2]] -; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] -; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 -; IS__CGSCC_OPM-SAME: () #[[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR3]], !range [[RNG2]] -; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS________OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 +; IS________OPM-SAME: () #[[ATTR0]] { +; IS________OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]], !range [[RNG2]] +; IS________OPM-NEXT: ret i32 [[RET]] ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 -; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]], !range [[RNG2]] -; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] +; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS________NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 +; IS________NPM-SAME: () #[[ATTR0]] { +; IS________NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR1]], !range [[RNG2]] +; IS________NPM-NEXT: ret i32 [[RET]] ; %ret = call i32 @potential_test13_callee(i32 0) ret i32 %ret } define i32 @potential_test13_caller2() { -; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 -; IS__TUNIT_OPM-SAME: () #[[ATTR0]] { -; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]], !range [[RNG2]] -; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] -; -; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 -; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { -; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR1]], !range [[RNG2]] -; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] -; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 -; IS__CGSCC_OPM-SAME: () #[[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR3]], !range [[RNG2]] -; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS________OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 +; IS________OPM-SAME: () #[[ATTR0]] { +; IS________OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]], !range [[RNG2]] +; IS________OPM-NEXT: ret i32 [[RET]] ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 -; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]], !range [[RNG2]] -; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] +; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS________NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 +; IS________NPM-SAME: () #[[ATTR0]] { +; IS________NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR1]], !range [[RNG2]] +; IS________NPM-NEXT: ret i32 [[RET]] ; %ret = call i32 @potential_test13_callee(i32 1) ret i32 %ret diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll --- a/llvm/test/Transforms/Attributor/returned.ll +++ b/llvm/test/Transforms/Attributor/returned.ll @@ -54,18 +54,18 @@ } define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 { -; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; 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: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR9:[0-9]+]] ; IS__TUNIT____-NEXT: ret i32 [[R]] ; -; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn +; 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:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR10:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR9:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: @@ -77,7 +77,7 @@ define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 { ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_r2 -; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] ; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] @@ -88,7 +88,7 @@ ; 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: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR10:[0-9]+]] +; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR9]] ; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR9]] ; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR9]] @@ -112,23 +112,23 @@ ; ; 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:[0-9]+]] { +; 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: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR10]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR9]] ; 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: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR11:[0-9]+]] -; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR10]] -; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR10]] -; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR10]] -; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR10]] -; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR10]] +; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR9]] ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: if.end12: ; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] @@ -136,7 +136,7 @@ ; 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]]) #[[ATTR10]] +; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR9]] ; IS__CGSCC____-NEXT: br label [[COND_END]] ; IS__CGSCC____: cond.end: ; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ] @@ -192,7 +192,7 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 { ; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable ; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_rX -; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR2:[0-9]+]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] ; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] @@ -203,10 +203,10 @@ ; 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: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR9]] ; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR9]] -; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR9]] ; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[B]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[B]], i32 undef) #[[ATTR9]] ; IS__TUNIT____-NEXT: br label [[RETURN]] @@ -329,18 +329,18 @@ } define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 { -; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r1 ; 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: [[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]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: ret double* [[R]] ; -; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r1 ; 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: [[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]]) #[[ATTR10]] +; 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]]) #[[ATTR9]] ; IS__CGSCC____-NEXT: ret double* [[R]] ; entry: @@ -352,7 +352,7 @@ 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* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR2]] { +; 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:%.*]] @@ -363,7 +363,7 @@ ; 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: [[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) #[[ATTR10]] +; 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) #[[ATTR9]] ; 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]]) #[[ATTR9]] ; 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) #[[ATTR9]] ; 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]]) #[[ATTR9]] @@ -387,23 +387,23 @@ ; ; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r2 -; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR3:[0-9]+]] { +; 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: [[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]]) #[[ATTR10]] +; 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]]) #[[ATTR9]] ; 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: [[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) #[[ATTR11]] -; 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]]) #[[ATTR10]] -; 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) #[[ATTR10]] -; 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]]) #[[ATTR10]] -; 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]]) #[[ATTR10]] -; 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) #[[ATTR10]] +; 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) #[[ATTR9]] +; 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]]) #[[ATTR9]] +; 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) #[[ATTR9]] +; 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]]) #[[ATTR9]] +; 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]]) #[[ATTR9]] +; 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) #[[ATTR9]] ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: if.end12: ; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq double* [[A]], [[B]] @@ -411,7 +411,7 @@ ; 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 nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] +; 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]]) #[[ATTR9]] ; IS__CGSCC____-NEXT: br label [[COND_END]] ; IS__CGSCC____: cond.end: ; IS__CGSCC____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ] @@ -472,17 +472,11 @@ ; } ; define i32* @rt0(i32* %a) #0 { -; IS__TUNIT____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn -; IS__TUNIT____-LABEL: define {{[^@]+}}@rt0 -; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3:[0-9]+]] { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: unreachable -; -; 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:%.*]]) #[[ATTR4:[0-9]+]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: unreachable +; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn +; CHECK-LABEL: define {{[^@]+}}@rt0 +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: unreachable ; entry: %v = load i32, i32* %a, align 4 @@ -499,17 +493,11 @@ ; } ; define i32* @rt1(i32* %a) #0 { -; IS__TUNIT____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn -; IS__TUNIT____-LABEL: define {{[^@]+}}@rt1 -; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-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:%.*]]) #[[ATTR4]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: unreachable +; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn +; CHECK-LABEL: define {{[^@]+}}@rt1 +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: unreachable ; entry: %v = load i32, i32* %a, align 4 @@ -522,18 +510,18 @@ ; TEST another SCC test ; define i32* @rt2_helper(i32* %a) #0 { -; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__TUNIT____-LABEL: define {{[^@]+}}@rt2_helper ; 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]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: ret i32* [[A]] ; -; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2_helper ; 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]]) #[[ATTR10]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR9]] ; IS__CGSCC____-NEXT: ret i32* [[A]] ; entry: @@ -544,12 +532,12 @@ define i32* @rt2(i32* %a, i32 *%b) #0 { ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__TUNIT____-LABEL: define {{[^@]+}}@rt2 -; IS__TUNIT____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "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* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: br label [[IF_END]] ; IS__TUNIT____: if.end: ; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ] @@ -557,12 +545,12 @@ ; ; 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:%.*]]) #[[ATTR3]] { +; 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____: if.then: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR11]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR9]] ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: ; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ] @@ -584,18 +572,18 @@ ; TEST another SCC test ; define i32* @rt3_helper(i32* %a, i32* %b) #0 { -; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3_helper ; 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 nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: ret i32* [[B]] ; -; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3_helper ; 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 nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR10]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR9]] ; IS__CGSCC____-NEXT: ret i32* [[B]] ; entry: @@ -606,12 +594,12 @@ 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* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR2]] { +; 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 nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: br label [[IF_END]] ; IS__TUNIT____: if.end: ; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ] @@ -619,12 +607,12 @@ ; ; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3 -; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR3]] { +; 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 nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR11]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR9]] ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: ; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ] @@ -655,17 +643,11 @@ declare void @unknown_fn(i32* (i32*)*) #0 define i32* @calls_unknown_fn(i32* %r) #0 { -; IS__TUNIT____: Function Attrs: noinline nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@calls_unknown_fn -; IS__TUNIT____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR4:[0-9]+]] { -; IS__TUNIT____-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR11:[0-9]+]] -; IS__TUNIT____-NEXT: ret i32* [[R]] -; -; 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:%.*]]) #[[ATTR5:[0-9]+]] { -; IS__CGSCC____-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR12:[0-9]+]] -; IS__CGSCC____-NEXT: ret i32* [[R]] +; CHECK: Function Attrs: noinline nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@calls_unknown_fn +; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR4:[0-9]+]] { +; CHECK-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR10:[0-9]+]] +; CHECK-NEXT: ret i32* [[R]] ; tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn) ret i32* %r @@ -686,36 +668,23 @@ ; Verify the maybe-redefined function is not annotated: ; define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 { -; IS__TUNIT____: Function Attrs: noinline nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn -; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] { -; 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:%.*]]) #[[ATTR5]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: ret i32* [[R]] +; CHECK: Function Attrs: noinline nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn +; CHECK-SAME: (i32* [[R:%.*]]) #[[ATTR4]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i32* [[R]] ; entry: ret i32* %r } define i32* @calls_maybe_redefined_fn(i32* %r) #0 { -; IS__TUNIT____: Function Attrs: noinline norecurse nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn -; IS__TUNIT____-SAME: (i32* returned [[R:%.*]]) #[[ATTR5:[0-9]+]] { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR11]] -; IS__TUNIT____-NEXT: ret i32* [[R]] -; -; IS__CGSCC____: Function Attrs: noinline norecurse nounwind uwtable -; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn -; IS__CGSCC____-SAME: (i32* returned [[R:%.*]]) #[[ATTR6:[0-9]+]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR12]] -; IS__CGSCC____-NEXT: ret i32* [[R]] +; CHECK: Function Attrs: noinline norecurse nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn +; CHECK-SAME: (i32* returned [[R:%.*]]) #[[ATTR5:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR10]] +; CHECK-NEXT: ret i32* [[R]] ; entry: %call = call i32* @maybe_redefined_fn(i32* %r) @@ -735,36 +704,23 @@ ; Verify the maybe-redefined function is not annotated: ; define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 { -; IS__TUNIT____: Function Attrs: noinline nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn2 -; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] { -; 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:%.*]]) #[[ATTR5]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: ret i32* [[R]] +; CHECK: Function Attrs: noinline nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn2 +; CHECK-SAME: (i32* [[R:%.*]]) #[[ATTR4]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i32* [[R]] ; entry: ret i32* %r } define i32* @calls_maybe_redefined_fn2(i32* %r) #0 { -; IS__TUNIT____: Function Attrs: noinline norecurse nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2 -; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR5]] { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR11]] -; IS__TUNIT____-NEXT: ret i32* [[CALL]] -; -; IS__CGSCC____: Function Attrs: noinline norecurse nounwind uwtable -; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2 -; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR6]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR12]] -; IS__CGSCC____-NEXT: ret i32* [[CALL]] +; CHECK: Function Attrs: noinline norecurse nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2 +; CHECK-SAME: (i32* [[R:%.*]]) #[[ATTR5]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR10]] +; CHECK-NEXT: ret i32* [[CALL]] ; entry: %call = call i32* @maybe_redefined_fn2(i32* %r) @@ -820,7 +776,7 @@ define double @recursion_select_and_phi(i32 %a, double %b) #0 { ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__TUNIT____-LABEL: define {{[^@]+}}@recursion_select_and_phi -; IS__TUNIT____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[DEC:%.*]] = add nsw i32 [[A]], -1 ; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0 @@ -833,13 +789,13 @@ ; ; 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:%.*]]) #[[ATTR3]] { +; 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: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR10]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR9]] ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: ; IS__CGSCC____-NEXT: ret double [[B]] @@ -1084,29 +1040,17 @@ declare i32* @unknown(i32*) define i32* @ret_arg_or_unknown(i32* %b) #0 { -; IS__TUNIT____: Function Attrs: noinline nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown -; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] { -; 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:%.*]]) #[[ATTR5]] { -; 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]] +; CHECK: Function Attrs: noinline nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown +; CHECK-SAME: (i32* [[B:%.*]]) #[[ATTR4]] { +; 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]] ; entry: %cmp = icmp eq i32* %b, null @@ -1121,35 +1065,20 @@ } define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 { -; IS__TUNIT____: Function Attrs: noinline nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi -; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] { -; 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:%.*]]) #[[ATTR5]] { -; 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]] +; CHECK: Function Attrs: noinline nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi +; CHECK-SAME: (i32* [[B:%.*]]) #[[ATTR4]] { +; 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]] ; entry: %cmp = icmp eq i32* %b, null @@ -1268,35 +1197,20 @@ declare void @noreturn() noreturn; define i32 @deadblockphi3(i32 %A, i1 %c) #0 { -; IS__TUNIT____: Function Attrs: noinline nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@deadblockphi3 -; IS__TUNIT____-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR4]] { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]] -; IS__TUNIT____: unreachablecall: -; IS__TUNIT____-NEXT: call void @noreturn() #[[ATTR6:[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:%.*]]) #[[ATTR5]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]] -; IS__CGSCC____: unreachablecall: -; IS__CGSCC____-NEXT: call void @noreturn() #[[ATTR7:[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]] +; CHECK: Function Attrs: noinline nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@deadblockphi3 +; CHECK-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR4]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]] +; CHECK: unreachablecall: +; CHECK-NEXT: call void @noreturn() #[[ATTR6:[0-9]+]] +; CHECK-NEXT: unreachable +; CHECK: unreachableblock2: +; CHECK-NEXT: unreachable +; CHECK: unreachableblock3: +; CHECK-NEXT: unreachable +; CHECK: r: +; CHECK-NEXT: ret i32 [[A]] ; entry: br i1 %c, label %r, label %unreachablecall @@ -1354,37 +1268,21 @@ ; We can use the return information of the weak function non_exact_4. ; FIXME: %c2 and %c3 should be replaced but not %c0 or %c1! define i32 @exact(i32* align 8 %a, i32* align 8 %b) { -; IS__TUNIT____: Function Attrs: norecurse -; IS__TUNIT____-LABEL: define {{[^@]+}}@exact -; IS__TUNIT____-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) #[[ATTR7:[0-9]+]] { -; IS__TUNIT____-NEXT: [[C0:%.*]] = call i32 @non_exact_0() -; IS__TUNIT____-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1) -; IS__TUNIT____-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2) -; IS__TUNIT____-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) -; IS__TUNIT____-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) -; IS__TUNIT____-NEXT: [[C3L:%.*]] = load i32, i32* [[A]], align 32 -; IS__TUNIT____-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 -; IS__TUNIT____-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] -; IS__TUNIT____-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2 -; IS__TUNIT____-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] -; IS__TUNIT____-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] -; IS__TUNIT____-NEXT: ret i32 [[ADD4]] -; -; IS__CGSCC____: Function Attrs: norecurse -; IS__CGSCC____-LABEL: define {{[^@]+}}@exact -; IS__CGSCC____-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) #[[ATTR8:[0-9]+]] { -; IS__CGSCC____-NEXT: [[C0:%.*]] = call i32 @non_exact_0() -; IS__CGSCC____-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1) -; IS__CGSCC____-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2) -; IS__CGSCC____-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) -; IS__CGSCC____-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) -; IS__CGSCC____-NEXT: [[C3L:%.*]] = load i32, i32* [[A]], align 32 -; IS__CGSCC____-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 -; IS__CGSCC____-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] -; IS__CGSCC____-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2 -; IS__CGSCC____-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] -; IS__CGSCC____-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] -; IS__CGSCC____-NEXT: ret i32 [[ADD4]] +; CHECK: Function Attrs: norecurse +; CHECK-LABEL: define {{[^@]+}}@exact +; CHECK-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) #[[ATTR7:[0-9]+]] { +; CHECK-NEXT: [[C0:%.*]] = call i32 @non_exact_0() +; CHECK-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1) +; 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* [[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]], 2 +; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] +; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] +; CHECK-NEXT: ret i32 [[ADD4]] ; %c0 = call i32 @non_exact_0() %c1 = call i32 @non_exact_1(i32 1) @@ -1475,8 +1373,8 @@ attributes #0 = { noinline nounwind uwtable } ;. ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn } -; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noinline norecurse nosync nounwind readnone uwtable } -; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noinline nosync nounwind readnone uwtable } +; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } +; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } ; IS__TUNIT____: attributes #[[ATTR3]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn } ; IS__TUNIT____: attributes #[[ATTR4]] = { noinline nounwind uwtable } ; IS__TUNIT____: attributes #[[ATTR5]] = { noinline norecurse nounwind uwtable } @@ -1484,22 +1382,19 @@ ; IS__TUNIT____: attributes #[[ATTR7]] = { norecurse } ; IS__TUNIT____: attributes #[[ATTR8:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR9]] = { nofree nosync nounwind readnone } -; IS__TUNIT____: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone } -; IS__TUNIT____: attributes #[[ATTR11]] = { nounwind } -; IS__TUNIT____: attributes #[[ATTR12:[0-9]+]] = { nounwind readnone } +; IS__TUNIT____: attributes #[[ATTR10]] = { nounwind } +; IS__TUNIT____: attributes #[[ATTR11:[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 willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } -; IS__CGSCC____: attributes #[[ATTR3]] = { nofree noinline nosync nounwind readnone uwtable } -; IS__CGSCC____: attributes #[[ATTR4]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn } -; IS__CGSCC____: attributes #[[ATTR5]] = { noinline nounwind uwtable } -; IS__CGSCC____: attributes #[[ATTR6]] = { noinline norecurse nounwind uwtable } -; IS__CGSCC____: attributes #[[ATTR7]] = { noreturn } -; IS__CGSCC____: attributes #[[ATTR8]] = { norecurse } -; IS__CGSCC____: attributes #[[ATTR9:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR10]] = { nofree nosync nounwind readnone } -; IS__CGSCC____: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC____: attributes #[[ATTR12]] = { nounwind } -; IS__CGSCC____: attributes #[[ATTR13:[0-9]+]] = { nounwind readnone } +; 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]] = { noinline norecurse nounwind uwtable } +; IS__CGSCC____: attributes #[[ATTR6]] = { noreturn } +; IS__CGSCC____: attributes #[[ATTR7]] = { norecurse } +; IS__CGSCC____: attributes #[[ATTR8:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR9]] = { nofree nosync nounwind readnone } +; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR11:[0-9]+]] = { nounwind readnone } ;. diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll --- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll @@ -755,41 +755,27 @@ ; } ; define i32 @local_alloca_simplifiable_3() { -; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3 -; IS__TUNIT_OPM-SAME: () #[[ATTR3:[0-9]+]] { -; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 -; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[A]], align 4 -; IS__TUNIT_OPM-NEXT: br label [[SPLIT:%.*]] -; IS__TUNIT_OPM: split: -; IS__TUNIT_OPM-NEXT: store i32 2, i32* [[A]], align 4 -; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i32, i32* [[A]], align 4 -; IS__TUNIT_OPM-NEXT: ret i32 [[L]] -; -; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3 -; IS__TUNIT_NPM-SAME: () #[[ATTR3:[0-9]+]] { -; IS__TUNIT_NPM-NEXT: br label [[SPLIT:%.*]] -; IS__TUNIT_NPM: split: -; IS__TUNIT_NPM-NEXT: ret i32 2 -; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3 -; IS__CGSCC_OPM-SAME: () #[[ATTR2:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 -; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[A]], align 4 -; IS__CGSCC_OPM-NEXT: br label [[SPLIT:%.*]] -; IS__CGSCC_OPM: split: -; IS__CGSCC_OPM-NEXT: store i32 2, i32* [[A]], align 4 -; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[A]], align 4 -; IS__CGSCC_OPM-NEXT: ret i32 [[L]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3 +; IS__TUNIT____-SAME: () #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__TUNIT____-NEXT: store i32 1, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: br label [[SPLIT:%.*]] +; IS__TUNIT____: split: +; IS__TUNIT____-NEXT: store i32 2, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i32, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: ret i32 [[L]] ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3 -; IS__CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: br label [[SPLIT:%.*]] -; IS__CGSCC_NPM: split: -; IS__CGSCC_NPM-NEXT: ret i32 2 +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3 +; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__CGSCC____-NEXT: store i32 1, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: br label [[SPLIT:%.*]] +; IS__CGSCC____: split: +; IS__CGSCC____-NEXT: store i32 2, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: ret i32 [[L]] ; %A = alloca i32, align 4 store i32 1, i32* %A @@ -807,12 +793,12 @@ define i32 @local_alloca_simplifiable_4() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@local_alloca_simplifiable_4 -; IS__TUNIT____-SAME: () #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-SAME: () #[[ATTR3]] { ; IS__TUNIT____-NEXT: ret i32 undef ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@local_alloca_simplifiable_4 -; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: ret i32 undef ; %A = alloca i32, align 4