Index: llvm/include/llvm/Transforms/IPO/Attributor.h =================================================================== --- llvm/include/llvm/Transforms/IPO/Attributor.h +++ llvm/include/llvm/Transforms/IPO/Attributor.h @@ -130,6 +130,7 @@ struct AbstractAttribute; struct InformationCache; struct AAIsDead; +struct AAReachability; class Function; @@ -804,6 +805,21 @@ return Result; } + /// Return whether it is assumed that \p To is unreachable from \p From in + /// AAReachability. + bool getAssumedUnreachable(const Instruction &From, const Instruction &To) { + const BasicBlock *FromBB = From.getParent(); + const BasicBlock *ToBB = From.getParent(); + auto QueriedBBPair = std::make_pair(FromBB, ToBB); + if (AssumedUnreachableQueries.count(QueriedBBPair)) + return true; + if (!KnownReachableQueries.count(QueriedBBPair)) { + AssumedUnreachableQueries.insert(QueriedBBPair); + return true; + } + return false; + } + private: struct FunctionInfo { ~FunctionInfo(); @@ -867,9 +883,22 @@ DenseMap, bool> PotentiallyReachableMap; + /// A set for cached queries for AAReachability. For each query in this set, + /// it is assumed that the second BB is unreachable from the first BB. + DenseSet> + AssumedUnreachableQueries; + + /// A set for cached queries for AAReachability. For each query in this set, + /// it is known that the second BB is reachable from the first BB. + DenseSet> + KnownReachableQueries; + /// Give the Attributor access to the members so /// Attributor::identifyDefaultAbstractAttributes(...) can initialize them. friend struct Attributor; + + /// Give AAReachability access to the cached query sets. + friend struct AAReachability; }; /// The fixpoint analysis framework that orchestrates the attribute deduction. @@ -2475,7 +2504,10 @@ /// determines (and caches) reachability. bool isAssumedReachable(Attributor &A, const Instruction &From, const Instruction &To) const { - return A.getInfoCache().getPotentiallyReachable(From, To); + InformationCache &InfoCache = A.getInfoCache(); + if (!InfoCache.getPotentiallyReachable(From, To)) + return false; + return !InfoCache.getAssumedUnreachable(From, To); } /// Returns true if 'From' instruction is known to reach, 'To' instruction. @@ -2504,6 +2536,18 @@ /// Unique ID (due to the unique address) static const char ID; + +protected: + /// Getter for the set of cached queries in information cache + DenseSet> & + getAssumedUnreachableQueries(Attributor &A) { + return A.getInfoCache().AssumedUnreachableQueries; + } + + DenseSet> & + getKnownReachableQueries(Attributor &A) { + return A.getInfoCache().KnownReachableQueries; + } }; /// An abstract interface for all noalias attributes. Index: llvm/lib/Transforms/IPO/AttributorAttributes.cpp =================================================================== --- llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -2354,6 +2354,56 @@ AAReachabilityFunction(const IRPosition &IRP, Attributor &A) : AAReachabilityImpl(IRP, A) {} + /// See AbstractAttribute::initialize(...). + void initialize(Attributor &A) override {} + + /// See AbstractAttribute::updateImpl(...). + ChangeStatus updateImpl(Attributor &A) override { + ChangeStatus Changed = ChangeStatus::UNCHANGED; + const auto &FnLiveness = A.getAAFor(*this, getIRPosition()); + using QueryTy = std::pair; + DenseSet &AssumedUnreachableQueries = + getAssumedUnreachableQueries(A); + DenseSet &KnownReachableQueries = getKnownReachableQueries(A); + SmallVector ToBeErased; + for (const QueryTy &Query : AssumedUnreachableQueries) { + if (computeReachability(Query.first, Query.second, FnLiveness)) { + Changed = ChangeStatus::CHANGED; + ToBeErased.push_back(Query); + KnownReachableQueries.insert(Query); + } + } + for (const QueryTy &Query : ToBeErased) + AssumedUnreachableQueries.erase(Query); + return Changed; + } + + // Return true when we can prove that ToBB is reachable from FromBB using only + // assumed liveness information. + bool computeReachability(const BasicBlock *FromBB, const BasicBlock *ToBB, + const AAIsDead &FnLiveness) { + if (FromBB == ToBB) + return true; + SmallPtrSet VisitedBBs; + SmallVector Worklist; + Worklist.push_back(FromBB); + VisitedBBs.insert(FromBB); + while (!Worklist.empty()) { + const BasicBlock *BB = Worklist.pop_back_val(); + LLVM_DEBUG(dbgs() << "[AAReachability] Explore BB : " << *BB << "\n"); + if (BB == ToBB) + return true; + for (const_succ_iterator SuccIt = succ_begin(BB); SuccIt != succ_end(BB); + SuccIt = FnLiveness.getNextAssumedLiveSuccessor(SuccIt)) { + if (VisitedBBs.count(*SuccIt)) + continue; + Worklist.push_back(*SuccIt); + VisitedBBs.insert(*SuccIt); + } + } + return false; + } + /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(reachable); } }; Index: llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll @@ -14,7 +14,7 @@ define internal void @bar(%pair* byval %Data) { ; IS________OPM-LABEL: define {{[^@]+}}@bar ; IS________OPM-SAME: (%pair* noalias nonnull byval dereferenceable(8) [[DATA:%.*]]) -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call i8* @foo(%pair* nonnull dereferenceable(8) [[DATA]]) +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call i8* @foo(%pair* noalias nonnull dereferenceable(8) [[DATA]]) ; IS________OPM-NEXT: ret void ; ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@bar @@ -24,7 +24,7 @@ ; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]], align 4 ; IS__TUNIT_NPM-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], %pair* [[DATA_PRIV]], i32 0, i32 1 ; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* nonnull dereferenceable(8) [[DATA_PRIV]]) +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* noalias nonnull dereferenceable(8) [[DATA_PRIV]]) ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar @@ -34,7 +34,7 @@ ; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]], align 4 ; IS__CGSCC_NPM-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], %pair* [[DATA_PRIV]], i32 0, i32 1 ; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* nonnull align 8 dereferenceable(8) [[DATA_PRIV]]) +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* noalias nonnull align 8 dereferenceable(8) [[DATA_PRIV]]) ; IS__CGSCC_NPM-NEXT: ret void ; tail call i8* @foo(%pair* %Data) Index: llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll @@ -83,66 +83,66 @@ } define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %N, float* dereferenceable(4) %p, i64 %q) { -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@.omp_outlined. -; NOT_TUNIT_NPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) -; NOT_TUNIT_NPM-NEXT: entry: -; NOT_TUNIT_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 -; NOT_TUNIT_NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 -; NOT_TUNIT_NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 -; NOT_TUNIT_NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 -; NOT_TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 -; NOT_TUNIT_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] -; NOT_TUNIT_NPM: omp.precond.then: -; NOT_TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 -; NOT_TUNIT_NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 -; NOT_TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; NOT_TUNIT_NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 1, i32 1) -; NOT_TUNIT_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] -; NOT_TUNIT_NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; NOT_TUNIT_NPM: cond.true: -; NOT_TUNIT_NPM-NEXT: br label [[COND_END:%.*]] -; NOT_TUNIT_NPM: cond.false: -; NOT_TUNIT_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: br label [[COND_END]] -; NOT_TUNIT_NPM: cond.end: -; NOT_TUNIT_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] -; NOT_TUNIT_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 -; NOT_TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] -; NOT_TUNIT_NPM: omp.inner.for.cond: -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] -; NOT_TUNIT_NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] -; NOT_TUNIT_NPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] -; NOT_TUNIT_NPM: omp.inner.for.cond.cleanup: -; NOT_TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] -; NOT_TUNIT_NPM: omp.inner.for.body: -; NOT_TUNIT_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 -; NOT_TUNIT_NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 -; NOT_TUNIT_NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) -; NOT_TUNIT_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] -; NOT_TUNIT_NPM: omp.body.continue: -; NOT_TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_INC]] -; NOT_TUNIT_NPM: omp.inner.for.inc: -; NOT_TUNIT_NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 -; NOT_TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND]] -; NOT_TUNIT_NPM: omp.inner.for.end: -; NOT_TUNIT_NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] -; NOT_TUNIT_NPM: omp.loop.exit: -; NOT_TUNIT_NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; NOT_TUNIT_NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP12]]) -; NOT_TUNIT_NPM-NEXT: br label [[OMP_PRECOND_END]] -; NOT_TUNIT_NPM: omp.precond.end: -; NOT_TUNIT_NPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS________OPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 +; IS________OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 +; IS________OPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* +; IS________OPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 +; IS________OPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 +; IS________OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 +; IS________OPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +; IS________OPM: omp.precond.then: +; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS________OPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS________OPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 1, i32 1) +; IS________OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] +; IS________OPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS________OPM: cond.true: +; IS________OPM-NEXT: br label [[COND_END:%.*]] +; IS________OPM: cond.false: +; IS________OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: br label [[COND_END]] +; IS________OPM: cond.end: +; IS________OPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] +; IS________OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +; IS________OPM: omp.inner.for.cond: +; IS________OPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] +; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] +; IS________OPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] +; IS________OPM: omp.inner.for.cond.cleanup: +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] +; IS________OPM: omp.inner.for.body: +; IS________OPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 +; IS________OPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 +; IS________OPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 +; IS________OPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) +; IS________OPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +; IS________OPM: omp.body.continue: +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_INC]] +; IS________OPM: omp.inner.for.inc: +; IS________OPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND]] +; IS________OPM: omp.inner.for.end: +; IS________OPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +; IS________OPM: omp.loop.exit: +; IS________OPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS________OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, 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 readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) @@ -164,7 +164,7 @@ ; 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* nonnull align 8 dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 1, i32 1) +; IS__TUNIT_NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* noalias nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noalias nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noalias nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noalias nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 1, i32 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:%.*]] @@ -205,6 +205,67 @@ ; IS__TUNIT_NPM: omp.precond.end: ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) +; 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* nonnull align 8 dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* noalias nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noalias nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noalias nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noalias nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 1, i32 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: [[TMP10:%.*]] = load float, float* [[P]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 +; IS__CGSCC_NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], 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* nonnull align 8 dereferenceable(24) @0, i32 [[TMP12]]) +; IS__CGSCC_NPM-NEXT: br label [[OMP_PRECOND_END]] +; IS__CGSCC_NPM: omp.precond.end: +; IS__CGSCC_NPM-NEXT: ret void +; entry: %q.addr = alloca i64, align 8 %.omp.lb = alloca i32, align 4 Index: llvm/test/Transforms/Attributor/noalias.ll =================================================================== --- llvm/test/Transforms/Attributor/noalias.ll +++ llvm/test/Transforms/Attributor/noalias.ll @@ -313,7 +313,7 @@ define void @test10_helper_2(i8* noalias %a) { ; CHECK-LABEL: define {{[^@]+}}@test10_helper_2 ; CHECK-SAME: (i8* noalias [[A:%.*]]) -; CHECK-NEXT: tail call void @test10_helper_1(i8* [[A]]) +; CHECK-NEXT: tail call void @test10_helper_1(i8* noalias [[A]]) ; CHECK-NEXT: ret void ; tail call void @test10_helper_1(i8* %a) @@ -666,7 +666,7 @@ ; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) ; NOT_CGSCC_NPM-NEXT: br label [[IF_END]] ; NOT_CGSCC_NPM: if.end: -; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) +; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* noalias nofree writeonly [[P]]) ; NOT_CGSCC_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly @@ -678,7 +678,7 @@ ; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* noalias nofree writeonly [[P]]) ; IS__CGSCC____-NEXT: ret void ; %tobool = icmp eq i32 %c, 0 @@ -721,13 +721,13 @@ ; NOT_CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; NOT_CGSCC_NPM: if.then: ; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) -; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly align 4 [[P]]) +; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* noalias nofree writeonly align 4 [[P]]) ; NOT_CGSCC_NPM-NEXT: br label [[IF_END]] ; NOT_CGSCC_NPM: if.end: ; NOT_CGSCC_NPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0 ; NOT_CGSCC_NPM-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] ; NOT_CGSCC_NPM: if.then2: -; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) +; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) ; NOT_CGSCC_NPM-NEXT: br label [[IF_END3]] ; NOT_CGSCC_NPM: if.end3: ; NOT_CGSCC_NPM-NEXT: ret void @@ -739,13 +739,13 @@ ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS__CGSCC____: if.then: ; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: ; IS__CGSCC____-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] ; IS__CGSCC____: if.then2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) +; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) ; IS__CGSCC____-NEXT: br label [[IF_END3]] ; IS__CGSCC____: if.end3: ; IS__CGSCC____-NEXT: ret void @@ -898,10 +898,10 @@ ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; IS__CGSCC____: l1: -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: l2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) +; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) ; IS__CGSCC____-NEXT: ret void ; entry: Index: llvm/test/Transforms/Attributor/readattrs.ll =================================================================== --- llvm/test/Transforms/Attributor/readattrs.ll +++ llvm/test/Transforms/Attributor/readattrs.ll @@ -278,7 +278,7 @@ ; CHECK: Function Attrs: readonly ; CHECK-LABEL: define {{[^@]+}}@byval_not_readonly_1 ; CHECK-SAME: (i8* noalias nonnull byval dereferenceable(1) [[WRITTEN:%.*]]) -; CHECK-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]]) +; CHECK-NEXT: call void @escape_i8(i8* noalias nonnull dereferenceable(1) [[WRITTEN]]) ; CHECK-NEXT: ret void ; call void @escape_i8(i8* %written) @@ -306,7 +306,7 @@ ; CHECK: Function Attrs: readnone ; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_1 ; CHECK-SAME: (i8* noalias nonnull byval dereferenceable(1) [[WRITTEN:%.*]]) -; CHECK-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]]) +; CHECK-NEXT: call void @escape_i8(i8* noalias nonnull dereferenceable(1) [[WRITTEN]]) ; CHECK-NEXT: ret void ; call void @escape_i8(i8* %written) Index: llvm/test/Transforms/Attributor/undefined_behavior.ll =================================================================== --- llvm/test/Transforms/Attributor/undefined_behavior.ll +++ llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -768,45 +768,85 @@ ; Cases for single and multiple violation at a callsite define void @arg_nonnull_violation3_1(i1 %c) { -; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn -; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 -; IS__TUNIT____-SAME: (i1 [[C:%.*]]) -; IS__TUNIT____-NEXT: [[PTR:%.*]] = alloca i32, align 4 -; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__TUNIT____: t: -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__TUNIT____-NEXT: br label [[RET:%.*]] -; IS__TUNIT____: f: -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__TUNIT____-NEXT: br label [[RET]] -; IS__TUNIT____: ret: -; IS__TUNIT____-NEXT: ret void -; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__CGSCC____-NEXT: br label [[RET:%.*]] -; IS__CGSCC____: f: -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__CGSCC____-NEXT: br label [[RET]] -; IS__CGSCC____: ret: -; IS__CGSCC____-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 +; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_OPM: t: +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_OPM-NEXT: br label [[RET:%.*]] +; IS__TUNIT_OPM: f: +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_OPM-NEXT: br label [[RET]] +; IS__TUNIT_OPM: ret: +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 +; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_NPM: t: +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_NPM-NEXT: br label [[RET:%.*]] +; IS__TUNIT_NPM: f: +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_NPM-NEXT: br label [[RET]] +; IS__TUNIT_NPM: ret: +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_OPM: t: +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_OPM-NEXT: br label [[RET:%.*]] +; IS__CGSCC_OPM: f: +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_OPM-NEXT: br label [[RET]] +; IS__CGSCC_OPM: ret: +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_NPM: t: +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_NPM-NEXT: br label [[RET:%.*]] +; IS__CGSCC_NPM: f: +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_NPM-NEXT: br label [[RET]] +; IS__CGSCC_NPM: ret: +; IS__CGSCC_NPM-NEXT: ret void ; %ptr = alloca i32 br i1 %c, label %t, label %f @@ -827,37 +867,69 @@ } define void @arg_nonnull_violation3_2(i1 %c) { -; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn -; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 -; IS__TUNIT____-SAME: (i1 [[C:%.*]]) -; IS__TUNIT____-NEXT: [[PTR:%.*]] = alloca i32, align 4 -; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__TUNIT____: t: -; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__TUNIT____-NEXT: unreachable -; IS__TUNIT____: f: -; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__TUNIT____-NEXT: unreachable -; IS__TUNIT____: ret: -; IS__TUNIT____-NEXT: ret void -; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__CGSCC____-NEXT: unreachable -; IS__CGSCC____: f: -; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) -; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) -; IS__CGSCC____-NEXT: unreachable -; IS__CGSCC____: ret: -; IS__CGSCC____-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 +; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_OPM: t: +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_OPM-NEXT: unreachable +; IS__TUNIT_OPM: f: +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_OPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_OPM-NEXT: unreachable +; IS__TUNIT_OPM: ret: +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 +; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_NPM: t: +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_NPM-NEXT: unreachable +; IS__TUNIT_NPM: f: +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__TUNIT_NPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__TUNIT_NPM-NEXT: unreachable +; IS__TUNIT_NPM: ret: +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_OPM: t: +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_OPM-NEXT: unreachable +; IS__CGSCC_OPM: f: +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_OPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_OPM-NEXT: unreachable +; IS__CGSCC_OPM: ret: +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_NPM: t: +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_NPM-NEXT: unreachable +; IS__CGSCC_NPM: f: +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]]) +; IS__CGSCC_NPM-NEXT: call void @arg_nonnull_12_noundef_2(i32* noalias nocapture nofree nonnull writeonly align 536870912 null, i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree writeonly align 536870912 null) +; IS__CGSCC_NPM-NEXT: unreachable +; IS__CGSCC_NPM: ret: +; IS__CGSCC_NPM-NEXT: ret void ; %ptr = alloca i32 br i1 %c, label %t, label %f