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 @@ -2333,13 +2333,37 @@ void initialize(Attributor &A) override { AAWillReturn::initialize(A); - Function *F = getAnchorScope(); - if (!F || F->isDeclaration() || mayContainUnboundedCycle(*F, A)) - indicatePessimisticFixpoint(); + if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ true)) { + indicateOptimisticFixpoint(); + return; + } + } + + /// Check for `mustprogress` and `readonly` as they imply `willreturn`. + bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) { + // Check for `mustprogress` in the scope and the associated function which + // might be different if this is a call site. + if ((!getAnchorScope() || !getAnchorScope()->mustProgress()) && + (!getAssociatedFunction() || !getAssociatedFunction()->mustProgress())) + return false; + + const auto &MemAA = A.getAAFor(*this, getIRPosition(), + DepClassTy::NONE); + if (!MemAA.isAssumedReadOnly()) + return false; + if (KnownOnly && !MemAA.isKnownReadOnly()) + return false; + if (!MemAA.isKnownReadOnly()) + A.recordDependence(MemAA, *this, DepClassTy::OPTIONAL); + + return true; } /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { + if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) + return ChangeStatus::UNCHANGED; + auto CheckForWillReturn = [&](Instruction &I) { IRPosition IPos = IRPosition::callsite_function(cast(I)); const auto &WillReturnAA = @@ -2369,6 +2393,15 @@ AAWillReturnFunction(const IRPosition &IRP, Attributor &A) : AAWillReturnImpl(IRP, A) {} + /// See AbstractAttribute::initialize(...). + void initialize(Attributor &A) override { + AAWillReturnImpl::initialize(A); + + Function *F = getAnchorScope(); + if (!F || F->isDeclaration() || mayContainUnboundedCycle(*F, A)) + indicatePessimisticFixpoint(); + } + /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) } }; @@ -2380,7 +2413,7 @@ /// See AbstractAttribute::initialize(...). void initialize(Attributor &A) override { - AAWillReturn::initialize(A); + AAWillReturnImpl::initialize(A); Function *F = getAssociatedFunction(); if (!F || !A.isFunctionIPOAmendable(*F)) indicatePessimisticFixpoint(); @@ -2388,6 +2421,9 @@ /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { + if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) + return ChangeStatus::UNCHANGED; + // TODO: Once we have call site specific value information we can provide // call site specific liveness information and then it makes // sense to specialize attributes for call sites arguments instead of @@ -5603,9 +5639,9 @@ const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { Type *PointeeTy = PrivStructType->getElementType(u)->getPointerTo(); - Value *Ptr = constructPointer( - PointeeTy, PrivType, &Base, PrivStructLayout->getElementOffset(u), - IRB, DL); + Value *Ptr = + constructPointer(PointeeTy, PrivType, &Base, + PrivStructLayout->getElementOffset(u), IRB, DL); new StoreInst(F.getArg(ArgNo + u), Ptr, &IP); } } else if (auto *PrivArrayType = dyn_cast(PrivType)) { @@ -5613,8 +5649,8 @@ Type *PointeePtrTy = PointeeTy->getPointerTo(); uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { - Value *Ptr = constructPointer( - PointeePtrTy, PrivType, &Base, u * PointeeTySize, IRB, DL); + Value *Ptr = constructPointer(PointeePtrTy, PrivType, &Base, + u * PointeeTySize, IRB, DL); new StoreInst(F.getArg(ArgNo + u), Ptr, &IP); } } else { @@ -5655,8 +5691,8 @@ uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); Type *PointeePtrTy = PointeeTy->getPointerTo(); for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { - Value *Ptr = constructPointer( - PointeePtrTy, PrivType, Base, u * PointeeTySize, IRB, DL); + Value *Ptr = constructPointer(PointeePtrTy, PrivType, Base, + u * PointeeTySize, IRB, DL); LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP); L->setAlignment(Alignment); ReplacementValues.push_back(L); diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll @@ -65,5 +65,5 @@ ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll @@ -164,9 +164,9 @@ ; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR1]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR1]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR2]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR2]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll @@ -218,5 +218,5 @@ ; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll @@ -65,12 +65,12 @@ ;. ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } -; IS__TUNIT____: attributes #[[ATTR2]] = { willreturn } +; IS__TUNIT____: attributes #[[ATTR2]] = { readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } -; IS__CGSCC____: attributes #[[ATTR3]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { readnone willreturn } ;. ; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug) ; CHECK: [[META1:![0-9]+]] = !DIFile(filename: "test.c", directory: "") diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll @@ -265,5 +265,5 @@ ; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR3:[0-9]+]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR3:[0-9]+]] = { nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll @@ -110,7 +110,7 @@ ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } ;. ; CHECK: [[META0:![0-9]+]] = !{i64 -8, i64 43} ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll @@ -147,6 +147,6 @@ ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR3]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind readnone willreturn } ;. 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 @@ -155,5 +155,5 @@ ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/cb_range_disabled.ll b/llvm/test/Transforms/Attributor/cb_range_disabled.ll --- a/llvm/test/Transforms/Attributor/cb_range_disabled.ll +++ b/llvm/test/Transforms/Attributor/cb_range_disabled.ll @@ -134,7 +134,7 @@ ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } ;. ; NOT_CGSCC_NPM: [[META0:![0-9]+]] = !{i32 0, i32 101} ;. diff --git a/llvm/test/Transforms/Attributor/cb_range_enabled.ll b/llvm/test/Transforms/Attributor/cb_range_enabled.ll --- a/llvm/test/Transforms/Attributor/cb_range_enabled.ll +++ b/llvm/test/Transforms/Attributor/cb_range_enabled.ll @@ -128,7 +128,7 @@ ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } ;. ; CHECK: [[META0:![0-9]+]] = !{i32 0, i32 101} ; CHECK: [[META1:![0-9]+]] = !{i32 -20, i32 81} diff --git a/llvm/test/Transforms/Attributor/internal-noalias.ll b/llvm/test/Transforms/Attributor/internal-noalias.ll --- a/llvm/test/Transforms/Attributor/internal-noalias.ll +++ b/llvm/test/Transforms/Attributor/internal-noalias.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=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM +; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll --- a/llvm/test/Transforms/Attributor/noalias.ll +++ b/llvm/test/Transforms/Attributor/noalias.ll @@ -576,17 +576,29 @@ ; Function Attrs: nounwind optsize define internal fastcc double @strtox(i8* %s, i8** %p, i32 %prec) unnamed_addr { -; CHECK-LABEL: define {{[^@]+}}@strtox -; CHECK-SAME: (i8* [[S:%.*]]) unnamed_addr { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 -; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* -; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR10:[0-9]+]] -; CHECK-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) -; CHECK-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) -; CHECK-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) -; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) -; CHECK-NEXT: ret double [[CALL1]] +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@strtox +; NOT_CGSCC_NPM-SAME: (i8* [[S:%.*]]) unnamed_addr { +; NOT_CGSCC_NPM-NEXT: entry: +; NOT_CGSCC_NPM-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 +; NOT_CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* +; NOT_CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR10:[0-9]+]] +; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) +; NOT_CGSCC_NPM-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) +; NOT_CGSCC_NPM-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) +; NOT_CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) +; NOT_CGSCC_NPM-NEXT: ret double [[CALL1]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@strtox +; IS__CGSCC____-SAME: (i8* [[S:%.*]]) unnamed_addr { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* +; IS__CGSCC____-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR12:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) +; IS__CGSCC____-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) +; IS__CGSCC____-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) +; IS__CGSCC____-NEXT: ret double [[CALL1]] ; entry: %f = alloca %struct._IO_FILE, align 8 @@ -686,10 +698,10 @@ ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; 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 noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR12:[0-9]+]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13:[0-9]+]] ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]] ; IS__CGSCC____-NEXT: ret void ; %tobool = icmp eq i32 %c, 0 @@ -749,14 +761,14 @@ ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0 ; 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 noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR12]] -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] ; 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 noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] ; IS__CGSCC____-NEXT: br label [[IF_END3]] ; IS__CGSCC____: if.end3: ; IS__CGSCC____-NEXT: ret void @@ -791,7 +803,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_caller ; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { -; IS__CGSCC____-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR13]] ; IS__CGSCC____-NEXT: ret void ; tail call void @test16_sub(i32* %p, i32 %c, i32 %c) @@ -840,10 +852,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 writeonly [[P]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]] ; IS__CGSCC____-NEXT: br label [[L3:%.*]] ; IS__CGSCC____: l2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] ; IS__CGSCC____-NEXT: br label [[L3]] ; IS__CGSCC____: l3: ; IS__CGSCC____-NEXT: ret void @@ -911,10 +923,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]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: l2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -953,7 +965,8 @@ ; IS__CGSCC____: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR9]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR10]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR10]] = { readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR11]] = { readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR12]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR12]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/nocapture-1.ll b/llvm/test/Transforms/Attributor/nocapture-1.ll --- a/llvm/test/Transforms/Attributor/nocapture-1.ll +++ b/llvm/test/Transforms/Attributor/nocapture-1.ll @@ -623,7 +623,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureLaunder ; IS__CGSCC____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR18]] +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR20:[0-9]+]] ; IS__CGSCC____-NEXT: store i8 42, i8* [[B]], align 1 ; IS__CGSCC____-NEXT: ret void ; @@ -645,7 +645,7 @@ ; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@captureLaunder ; IS__CGSCC____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR10]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR18]] +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR20]] ; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g2, align 8 ; IS__CGSCC____-NEXT: ret void ; @@ -659,7 +659,7 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureStrip ; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR17]] +; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18:[0-9]+]] ; IS__TUNIT____-NEXT: store i8 42, i8* [[B]], align 1 ; IS__TUNIT____-NEXT: ret void ; @@ -682,7 +682,7 @@ ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@captureStrip ; IS__TUNIT____-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR1]] { -; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR17]] +; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]] ; IS__TUNIT____-NEXT: store i8* [[B]], i8** @g3, align 8 ; IS__TUNIT____-NEXT: ret void ; @@ -892,6 +892,7 @@ ; IS__TUNIT____: attributes #[[ATTR15]] = { nofree nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR16]] = { nounwind } ; IS__TUNIT____: attributes #[[ATTR17]] = { willreturn } +; IS__TUNIT____: attributes #[[ATTR18]] = { readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn writeonly } @@ -911,6 +912,7 @@ ; IS__CGSCC____: attributes #[[ATTR15:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind speculatable willreturn } ; IS__CGSCC____: attributes #[[ATTR16:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } ; IS__CGSCC____: attributes #[[ATTR17]] = { nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR18]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR18]] = { readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR19]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR20]] = { willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/nofree.ll b/llvm/test/Transforms/Attributor/nofree.ll --- a/llvm/test/Transforms/Attributor/nofree.ll +++ b/llvm/test/Transforms/Attributor/nofree.ll @@ -383,13 +383,13 @@ ; ; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_assume_pos ; IS__TUNIT____-SAME: (i8* nofree [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* nofree [[ARG3:%.*]], i8* [[ARG4:%.*]]) { -; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR11]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12:[0-9]+]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] ; IS__TUNIT____-NEXT: call void @unknown(i8* nofree [[ARG1]], i8* [[ARG2]], i8* nofree [[ARG3]], i8* [[ARG4]]) ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_assume_pos ; IS__CGSCC____-SAME: (i8* nofree [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* nofree [[ARG3:%.*]], i8* [[ARG4:%.*]]) { -; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13:[0-9]+]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] ; IS__CGSCC____-NEXT: call void @unknown(i8* nofree [[ARG1]], i8* [[ARG2]], i8* nofree [[ARG3]], i8* [[ARG4]]) ; IS__CGSCC____-NEXT: ret void ; @@ -480,7 +480,8 @@ ; IS__TUNIT____: attributes #[[ATTR8:[0-9]+]] = { nobuiltin nofree nounwind } ; IS__TUNIT____: attributes #[[ATTR9:[0-9]+]] = { nofree nosync nounwind willreturn } ; IS__TUNIT____: attributes #[[ATTR10:[0-9]+]] = { nounwind willreturn } -; IS__TUNIT____: attributes #[[ATTR11]] = { willreturn } +; IS__TUNIT____: attributes #[[ATTR11]] = { readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR12]] = { willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { noinline nounwind uwtable } @@ -494,7 +495,8 @@ ; IS__CGSCC_OPM: attributes #[[ATTR9:[0-9]+]] = { nobuiltin nofree nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR10:[0-9]+]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR11:[0-9]+]] = { nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR12]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR12]] = { readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR13]] = { willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nounwind } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { noinline nounwind uwtable } @@ -508,5 +510,6 @@ ; IS__CGSCC_NPM: attributes #[[ATTR9:[0-9]+]] = { nobuiltin nofree nounwind } ; IS__CGSCC_NPM: attributes #[[ATTR10:[0-9]+]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR12]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR12]] = { readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR13]] = { willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/nosync.ll b/llvm/test/Transforms/Attributor/nosync.ll --- a/llvm/test/Transforms/Attributor/nosync.ll +++ b/llvm/test/Transforms/Attributor/nosync.ll @@ -508,13 +508,13 @@ ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cos_test2 ; IS__TUNIT____-SAME: (float [[X:%.*]]) #[[ATTR15]] { -; IS__TUNIT____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR17]] +; IS__TUNIT____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR19:[0-9]+]] ; IS__TUNIT____-NEXT: ret float [[C]] ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cos_test2 ; IS__CGSCC____-SAME: (float [[X:%.*]]) #[[ATTR16:[0-9]+]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR18]] +; IS__CGSCC____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR20:[0-9]+]] ; IS__CGSCC____-NEXT: ret float [[C]] ; %c = call float @llvm.cos(float %x) @@ -540,6 +540,7 @@ ; IS__TUNIT____: attributes #[[ATTR16:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } ; IS__TUNIT____: attributes #[[ATTR17]] = { willreturn } ; IS__TUNIT____: attributes #[[ATTR18]] = { willreturn writeonly } +; IS__TUNIT____: attributes #[[ATTR19]] = { readnone willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind uwtable willreturn } @@ -561,6 +562,7 @@ ; IS__CGSCC_OPM: attributes #[[ATTR17:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR18]] = { willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR19]] = { willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR20]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind uwtable willreturn } @@ -582,4 +584,5 @@ ; IS__CGSCC_NPM: attributes #[[ATTR17:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR18]] = { willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR19]] = { willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR20]] = { readnone willreturn } ;. 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 @@ -923,10 +923,10 @@ ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR2]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR2]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR1]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR1]] = { readnone willreturn } ;. ; IS__TUNIT_OPM: [[RNG0]] = !{i32 1, i32 4} ; IS__TUNIT_OPM: [[RNG1]] = !{i32 3, i32 5} diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll --- a/llvm/test/Transforms/Attributor/range.ll +++ b/llvm/test/Transforms/Attributor/range.ll @@ -2496,12 +2496,12 @@ ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR3]] = { readonly willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR5]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR5]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR3]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR3]] = { readnone willreturn } ;. ; IS__TUNIT_OPM: [[RNG0]] = !{i32 0, i32 10} ; IS__TUNIT_OPM: [[RNG1]] = !{i32 10, i32 100} diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -518,7 +518,7 @@ ; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR9]] = { readnone } ; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind readonly } -; IS__CGSCC____: attributes #[[ATTR11]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR11]] = { readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR12]] = { willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR13]] = { readonly willreturn } ; IS__CGSCC____: attributes #[[ATTR14]] = { nounwind } 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 @@ -1617,7 +1617,7 @@ ; IS__CGSCC____: attributes #[[ATTR3]] = { noinline nounwind uwtable } ; IS__CGSCC____: attributes #[[ATTR4]] = { noreturn } ; IS__CGSCC____: attributes #[[ATTR5:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR6]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR6]] = { readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind readnone } ; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind readnone } ; IS__CGSCC____: attributes #[[ATTR9]] = { nounwind } diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -399,15 +399,15 @@ ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated ; IS__CGSCC_OPM-SAME: () #[[ATTR0:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR5]] -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR6:[0-9]+]] [ "preallocated"(token [[C]]) ] +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR6:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR7:[0-9]+]] [ "preallocated"(token [[C]]) ] ; IS__CGSCC_OPM-NEXT: ret i32* [[CALL]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated ; IS__CGSCC_NPM-SAME: () #[[ATTR0:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR4]] -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR5:[0-9]+]] [ "preallocated"(token [[C]]) ] +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR5:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR6:[0-9]+]] [ "preallocated"(token [[C]]) ] ; IS__CGSCC_NPM-NEXT: ret i32* [[CALL]] ; %c = call token @llvm.call.preallocated.setup(i32 1) @@ -564,13 +564,13 @@ ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_byval2 ; IS__CGSCC_OPM-SAME: () #[[ATTR3]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR7:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR8:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i8* [[C]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval2 ; IS__CGSCC_NPM-SAME: () #[[ATTR3]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR6:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR7:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret i8* [[C]] ; %c = call i8* @test_byval2(%struct.X* @S) @@ -827,15 +827,17 @@ ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR5]] = { willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR7]] = { readonly willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR5]] = { readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR6]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR8]] = { readonly willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR4]] = { willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR6]] = { readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR4]] = { readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR5]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR7]] = { readonly willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/willreturn.ll b/llvm/test/Transforms/Attributor/willreturn.ll --- a/llvm/test/Transforms/Attributor/willreturn.ll +++ b/llvm/test/Transforms/Attributor/willreturn.ll @@ -72,9 +72,9 @@ ; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] ; IS__CGSCC_OPM: 3: ; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 -; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR19:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR26:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 -; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR19]] +; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR26]] ; IS__CGSCC_OPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] ; IS__CGSCC_OPM-NEXT: ret i32 [[TMP8]] ; IS__CGSCC_OPM: 9: @@ -87,9 +87,9 @@ ; IS__CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] ; IS__CGSCC_NPM: 3: ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 -; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR21:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR28:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 -; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR21]] +; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR28]] ; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP8]] ; IS__CGSCC_NPM: 9: @@ -285,7 +285,7 @@ ; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] ; IS__TUNIT_OPM: rec: ; IS__TUNIT_OPM-NEXT: call void @sink() #[[ATTR11:[0-9]+]] -; IS__TUNIT_OPM-NEXT: call void @mutual_recursion2(i1 [[C]]) #[[ATTR16:[0-9]+]] +; IS__TUNIT_OPM-NEXT: call void @mutual_recursion2(i1 [[C]]) #[[ATTR23:[0-9]+]] ; IS__TUNIT_OPM-NEXT: br label [[END]] ; IS__TUNIT_OPM: end: ; IS__TUNIT_OPM-NEXT: ret void @@ -296,7 +296,7 @@ ; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] ; IS__TUNIT_NPM: rec: ; IS__TUNIT_NPM-NEXT: call void @sink() #[[ATTR11:[0-9]+]] -; IS__TUNIT_NPM-NEXT: call void @mutual_recursion2(i1 noundef [[C]]) #[[ATTR18:[0-9]+]] +; IS__TUNIT_NPM-NEXT: call void @mutual_recursion2(i1 noundef [[C]]) #[[ATTR25:[0-9]+]] ; IS__TUNIT_NPM-NEXT: br label [[END]] ; IS__TUNIT_NPM: end: ; IS__TUNIT_NPM-NEXT: ret void @@ -307,7 +307,7 @@ ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] ; IS__CGSCC_OPM: rec: ; IS__CGSCC_OPM-NEXT: call void @sink() #[[ATTR14:[0-9]+]] -; IS__CGSCC_OPM-NEXT: call void @mutual_recursion2(i1 [[C]]) #[[ATTR20:[0-9]+]] +; IS__CGSCC_OPM-NEXT: call void @mutual_recursion2(i1 [[C]]) #[[ATTR27:[0-9]+]] ; IS__CGSCC_OPM-NEXT: br label [[END]] ; IS__CGSCC_OPM: end: ; IS__CGSCC_OPM-NEXT: ret void @@ -318,7 +318,7 @@ ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] ; IS__CGSCC_NPM: rec: ; IS__CGSCC_NPM-NEXT: call void @sink() #[[ATTR14:[0-9]+]] -; IS__CGSCC_NPM-NEXT: call void @mutual_recursion2(i1 noundef [[C]]) #[[ATTR22:[0-9]+]] +; IS__CGSCC_NPM-NEXT: call void @mutual_recursion2(i1 noundef [[C]]) #[[ATTR29:[0-9]+]] ; IS__CGSCC_NPM-NEXT: br label [[END]] ; IS__CGSCC_NPM: end: ; IS__CGSCC_NPM-NEXT: ret void @@ -337,25 +337,25 @@ ; IS__TUNIT_OPM: Function Attrs: nofree noinline nosync nounwind uwtable ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@mutual_recursion2 ; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { -; IS__TUNIT_OPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR23]] ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: nofree noinline nosync nounwind uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@mutual_recursion2 ; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { -; IS__TUNIT_NPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR18]] +; IS__TUNIT_NPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR25]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind uwtable ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@mutual_recursion2 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { -; IS__CGSCC_OPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR20]] +; IS__CGSCC_OPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR27]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@mutual_recursion2 ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { -; IS__CGSCC_NPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR22]] +; IS__CGSCC_NPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR29]] ; IS__CGSCC_NPM-NEXT: ret void ; call void @mutual_recursion1(i1 %c) @@ -478,25 +478,25 @@ ; IS__TUNIT_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@call_floor2 ; IS__TUNIT_OPM-SAME: (float [[A:%.*]]) #[[ATTR0]] { -; IS__TUNIT_OPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR17:[0-9]+]] +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR24:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret float [[C]] ; ; IS__TUNIT_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@call_floor2 ; IS__TUNIT_NPM-SAME: (float [[A:%.*]]) #[[ATTR0]] { -; IS__TUNIT_NPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR19:[0-9]+]] +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR26:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret float [[C]] ; ; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@call_floor2 ; IS__CGSCC_OPM-SAME: (float [[A:%.*]]) #[[ATTR9:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR21:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR28:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret float [[C]] ; ; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@call_floor2 ; IS__CGSCC_NPM-SAME: (float [[A:%.*]]) #[[ATTR9:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR23:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR30:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret float [[C]] ; %c = tail call float @llvm.floor.f32(float %a) @@ -516,25 +516,25 @@ ; IS__TUNIT_OPM: Function Attrs: noinline nounwind uwtable ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@call_maybe_noreturn ; IS__TUNIT_OPM-SAME: () #[[ATTR6]] { -; IS__TUNIT_OPM-NEXT: tail call void @maybe_noreturn() #[[ATTR18:[0-9]+]] +; IS__TUNIT_OPM-NEXT: tail call void @maybe_noreturn() #[[ATTR25:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: noinline nounwind uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@call_maybe_noreturn ; IS__TUNIT_NPM-SAME: () #[[ATTR6]] { -; IS__TUNIT_NPM-NEXT: tail call void @maybe_noreturn() #[[ATTR20:[0-9]+]] +; IS__TUNIT_NPM-NEXT: tail call void @maybe_noreturn() #[[ATTR27:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@call_maybe_noreturn ; IS__CGSCC_OPM-SAME: () #[[ATTR7]] { -; IS__CGSCC_OPM-NEXT: tail call void @maybe_noreturn() #[[ATTR22:[0-9]+]] +; IS__CGSCC_OPM-NEXT: tail call void @maybe_noreturn() #[[ATTR29:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@call_maybe_noreturn ; IS__CGSCC_NPM-SAME: () #[[ATTR7]] { -; IS__CGSCC_NPM-NEXT: tail call void @maybe_noreturn() #[[ATTR24:[0-9]+]] +; IS__CGSCC_NPM-NEXT: tail call void @maybe_noreturn() #[[ATTR31:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret void ; tail call void @maybe_noreturn() @@ -553,25 +553,25 @@ ; IS__TUNIT_OPM: Function Attrs: noinline nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f1 ; IS__TUNIT_OPM-SAME: () #[[ATTR9:[0-9]+]] { -; IS__TUNIT_OPM-NEXT: tail call void @will_return() #[[ATTR17]] +; IS__TUNIT_OPM-NEXT: tail call void @will_return() #[[ATTR26:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: noinline nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f1 ; IS__TUNIT_NPM-SAME: () #[[ATTR9:[0-9]+]] { -; IS__TUNIT_NPM-NEXT: tail call void @will_return() #[[ATTR19]] +; IS__TUNIT_NPM-NEXT: tail call void @will_return() #[[ATTR28:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: noinline norecurse nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1 ; IS__CGSCC_OPM-SAME: () #[[ATTR11:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: tail call void @will_return() #[[ATTR21]] +; IS__CGSCC_OPM-NEXT: tail call void @will_return() #[[ATTR30:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: noinline norecurse nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1 ; IS__CGSCC_NPM-SAME: () #[[ATTR11:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: tail call void @will_return() #[[ATTR23]] +; IS__CGSCC_NPM-NEXT: tail call void @will_return() #[[ATTR32:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret void ; tail call void @will_return() @@ -640,7 +640,7 @@ ; IS__TUNIT_OPM: Function Attrs: nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@invoke_test ; IS__TUNIT_OPM-SAME: () #[[ATTR11]] personality i32 (...)* @__gxx_personality_v0 { -; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR17]] +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR26]] ; IS__TUNIT_OPM-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] ; IS__TUNIT_OPM: N: ; IS__TUNIT_OPM-NEXT: ret void @@ -652,7 +652,7 @@ ; IS__TUNIT_NPM: Function Attrs: nounwind willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@invoke_test ; IS__TUNIT_NPM-SAME: () #[[ATTR11]] personality i32 (...)* @__gxx_personality_v0 { -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR19]] +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR28]] ; IS__TUNIT_NPM-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] ; IS__TUNIT_NPM: N: ; IS__TUNIT_NPM-NEXT: ret void @@ -664,7 +664,7 @@ ; IS__CGSCC_OPM: Function Attrs: nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@invoke_test ; IS__CGSCC_OPM-SAME: () #[[ATTR14]] personality i32 (...)* @__gxx_personality_v0 { -; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR21]] +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR30]] ; IS__CGSCC_OPM-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] ; IS__CGSCC_OPM: N: ; IS__CGSCC_OPM-NEXT: ret void @@ -676,7 +676,7 @@ ; IS__CGSCC_NPM: Function Attrs: nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@invoke_test ; IS__CGSCC_NPM-SAME: () #[[ATTR14]] personality i32 (...)* @__gxx_personality_v0 { -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR23]] +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR32]] ; IS__CGSCC_NPM-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] ; IS__CGSCC_NPM: N: ; IS__CGSCC_NPM-NEXT: ret void @@ -1056,7 +1056,7 @@ ; IS__TUNIT_OPM: Function Attrs: noinline nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unreachable_exit_positive1 ; IS__TUNIT_OPM-SAME: () #[[ATTR9]] { -; IS__TUNIT_OPM-NEXT: tail call void @will_return() #[[ATTR17]] +; IS__TUNIT_OPM-NEXT: tail call void @will_return() #[[ATTR26]] ; IS__TUNIT_OPM-NEXT: ret void ; IS__TUNIT_OPM: unreachable_label: ; IS__TUNIT_OPM-NEXT: unreachable @@ -1064,7 +1064,7 @@ ; IS__TUNIT_NPM: Function Attrs: noinline nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unreachable_exit_positive1 ; IS__TUNIT_NPM-SAME: () #[[ATTR9]] { -; IS__TUNIT_NPM-NEXT: tail call void @will_return() #[[ATTR19]] +; IS__TUNIT_NPM-NEXT: tail call void @will_return() #[[ATTR28]] ; IS__TUNIT_NPM-NEXT: ret void ; IS__TUNIT_NPM: unreachable_label: ; IS__TUNIT_NPM-NEXT: unreachable @@ -1072,7 +1072,7 @@ ; IS__CGSCC_OPM: Function Attrs: noinline norecurse nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@unreachable_exit_positive1 ; IS__CGSCC_OPM-SAME: () #[[ATTR11]] { -; IS__CGSCC_OPM-NEXT: tail call void @will_return() #[[ATTR21]] +; IS__CGSCC_OPM-NEXT: tail call void @will_return() #[[ATTR30]] ; IS__CGSCC_OPM-NEXT: ret void ; IS__CGSCC_OPM: unreachable_label: ; IS__CGSCC_OPM-NEXT: unreachable @@ -1080,7 +1080,7 @@ ; IS__CGSCC_NPM: Function Attrs: noinline norecurse nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@unreachable_exit_positive1 ; IS__CGSCC_NPM-SAME: () #[[ATTR11]] { -; IS__CGSCC_NPM-NEXT: tail call void @will_return() #[[ATTR23]] +; IS__CGSCC_NPM-NEXT: tail call void @will_return() #[[ATTR32]] ; IS__CGSCC_NPM-NEXT: ret void ; IS__CGSCC_NPM: unreachable_label: ; IS__CGSCC_NPM-NEXT: unreachable @@ -2012,7 +2012,7 @@ ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@non_loop_cycle ; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR18]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR23:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR31:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 ; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; IS__CGSCC_OPM: if.then: @@ -2020,7 +2020,7 @@ ; IS__CGSCC_OPM: if.else: ; IS__CGSCC_OPM-NEXT: br label [[ENTRY2:%.*]] ; IS__CGSCC_OPM: entry1: -; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR23]] +; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR31]] ; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5 ; IS__CGSCC_OPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]] ; IS__CGSCC_OPM: if.then3: @@ -2028,7 +2028,7 @@ ; IS__CGSCC_OPM: if.else4: ; IS__CGSCC_OPM-NEXT: br label [[ENTRY2]] ; IS__CGSCC_OPM: entry2: -; IS__CGSCC_OPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR23]] +; IS__CGSCC_OPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR31]] ; IS__CGSCC_OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5 ; IS__CGSCC_OPM-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] ; IS__CGSCC_OPM: if.then7: @@ -2105,6 +2105,169 @@ ret void } +declare void @unknown() +declare void @readonly() readonly +declare void @readnone() readnone +declare void @unknown_mustprogress() mustprogress +declare void @readonly_mustprogress() readonly mustprogress + +define void @willreturn_mustprogress_caller_1() mustprogress { +; IS__TUNIT_OPM: Function Attrs: mustprogress +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 +; IS__TUNIT_OPM-SAME: () #[[ATTR18:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: call void @unknown() +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: mustprogress +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 +; IS__TUNIT_NPM-SAME: () #[[ATTR20:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: call void @unknown() +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: mustprogress +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 +; IS__CGSCC_OPM-SAME: () #[[ATTR21:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: call void @unknown() +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: mustprogress +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 +; IS__CGSCC_NPM-SAME: () #[[ATTR23:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: call void @unknown() +; IS__CGSCC_NPM-NEXT: ret void +; + call void @unknown() + ret void +} +define void @willreturn_mustprogress_caller_2() mustprogress { +; IS__TUNIT_OPM: Function Attrs: readonly willreturn mustprogress +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 +; IS__TUNIT_OPM-SAME: () #[[ATTR20:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: call void @readonly() #[[ATTR16:[0-9]+]] +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: readonly willreturn mustprogress +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 +; IS__TUNIT_NPM-SAME: () #[[ATTR22:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: call void @readonly() #[[ATTR18:[0-9]+]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: readonly willreturn mustprogress +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 +; IS__CGSCC_OPM-SAME: () #[[ATTR23:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: call void @readonly() #[[ATTR19:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: readonly willreturn mustprogress +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 +; IS__CGSCC_NPM-SAME: () #[[ATTR25:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: call void @readonly() #[[ATTR21:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret void +; + call void @readonly() + ret void +} +define void @willreturn_mustprogress_caller_3() mustprogress { +; IS__TUNIT_OPM: Function Attrs: nosync readnone willreturn mustprogress +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 +; IS__TUNIT_OPM-SAME: () #[[ATTR21:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: call void @readnone() +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: nosync readnone willreturn mustprogress +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 +; IS__TUNIT_NPM-SAME: () #[[ATTR23:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: call void @readnone() +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: nosync readnone willreturn mustprogress +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 +; IS__CGSCC_OPM-SAME: () #[[ATTR24:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: call void @readnone() +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nosync readnone willreturn mustprogress +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 +; IS__CGSCC_NPM-SAME: () #[[ATTR26:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: call void @readnone() +; IS__CGSCC_NPM-NEXT: ret void +; + call void @readnone() + ret void +} +define void @willreturn_mustprogress_callee_1() { +; CHECK-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_1() { +; CHECK-NEXT: call void @unknown_mustprogress() +; CHECK-NEXT: ret void +; + call void @unknown_mustprogress() + ret void +} +define void @willreturn_mustprogress_callee_2() { +; IS__TUNIT_OPM: Function Attrs: readonly willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 +; IS__TUNIT_OPM-SAME: () #[[ATTR22:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: call void @readonly_mustprogress() #[[ATTR22]] +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: readonly willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 +; IS__TUNIT_NPM-SAME: () #[[ATTR24:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: call void @readonly_mustprogress() #[[ATTR24]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 +; IS__CGSCC_OPM-SAME: () #[[ATTR25:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: call void @readonly_mustprogress() #[[ATTR25]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: readonly willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 +; IS__CGSCC_NPM-SAME: () #[[ATTR27:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: call void @readonly_mustprogress() #[[ATTR27]] +; IS__CGSCC_NPM-NEXT: ret void +; + call void @readonly_mustprogress() + ret void +} +define void @willreturn_mustprogress_callee_3() { +; CHECK-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_3() { +; CHECK-NEXT: call void @willreturn_mustprogress_callee_1() +; CHECK-NEXT: ret void +; + call void @willreturn_mustprogress_callee_1() + ret void +} +define void @willreturn_mustprogress_callee_4() { +; IS__TUNIT_OPM: Function Attrs: readonly willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 +; IS__TUNIT_OPM-SAME: () #[[ATTR22]] { +; IS__TUNIT_OPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR22]] +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: readonly willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 +; IS__TUNIT_NPM-SAME: () #[[ATTR24]] { +; IS__TUNIT_NPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR24]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 +; IS__CGSCC_OPM-SAME: () #[[ATTR25]] { +; IS__CGSCC_OPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR25]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: readonly willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 +; IS__CGSCC_NPM-SAME: () #[[ATTR27]] { +; IS__CGSCC_NPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR27]] +; IS__CGSCC_NPM-NEXT: ret void +; + call void @willreturn_mustprogress_callee_2() + ret void +} + attributes #0 = { nounwind uwtable noinline } attributes #1 = { uwtable noinline } ;. @@ -2124,9 +2287,17 @@ ; IS__TUNIT_OPM: attributes #[[ATTR13]] = { nofree noinline noreturn nosync nounwind readnone uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR14:[0-9]+]] = { noreturn nounwind } ; IS__TUNIT_OPM: attributes #[[ATTR15]] = { nofree nosync nounwind readnone } -; IS__TUNIT_OPM: attributes #[[ATTR16]] = { nofree nosync nounwind } -; IS__TUNIT_OPM: attributes #[[ATTR17]] = { willreturn } -; IS__TUNIT_OPM: attributes #[[ATTR18]] = { nounwind } +; IS__TUNIT_OPM: attributes #[[ATTR16]] = { readonly } +; IS__TUNIT_OPM: attributes #[[ATTR17:[0-9]+]] = { readnone } +; IS__TUNIT_OPM: attributes #[[ATTR18]] = { mustprogress } +; IS__TUNIT_OPM: attributes #[[ATTR19:[0-9]+]] = { readonly mustprogress } +; IS__TUNIT_OPM: attributes #[[ATTR20]] = { readonly willreturn mustprogress } +; IS__TUNIT_OPM: attributes #[[ATTR21]] = { nosync readnone willreturn mustprogress } +; IS__TUNIT_OPM: attributes #[[ATTR22]] = { readonly willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR23]] = { nofree nosync nounwind } +; IS__TUNIT_OPM: attributes #[[ATTR24]] = { readnone willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR25]] = { nounwind } +; IS__TUNIT_OPM: attributes #[[ATTR26]] = { willreturn } ;. ; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree noinline nosync nounwind readnone uwtable willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } @@ -2146,9 +2317,17 @@ ; IS__TUNIT_NPM: attributes #[[ATTR15:[0-9]+]] = { noreturn nounwind } ; IS__TUNIT_NPM: attributes #[[ATTR16]] = { nofree nosync nounwind readnone } ; IS__TUNIT_NPM: attributes #[[ATTR17]] = { nofree nosync nounwind readnone willreturn } -; IS__TUNIT_NPM: attributes #[[ATTR18]] = { nofree nosync nounwind } -; IS__TUNIT_NPM: attributes #[[ATTR19]] = { willreturn } -; IS__TUNIT_NPM: attributes #[[ATTR20]] = { nounwind } +; IS__TUNIT_NPM: attributes #[[ATTR18]] = { readonly } +; IS__TUNIT_NPM: attributes #[[ATTR19:[0-9]+]] = { readnone } +; IS__TUNIT_NPM: attributes #[[ATTR20]] = { mustprogress } +; IS__TUNIT_NPM: attributes #[[ATTR21:[0-9]+]] = { readonly mustprogress } +; IS__TUNIT_NPM: attributes #[[ATTR22]] = { readonly willreturn mustprogress } +; IS__TUNIT_NPM: attributes #[[ATTR23]] = { nosync readnone willreturn mustprogress } +; IS__TUNIT_NPM: attributes #[[ATTR24]] = { readonly willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR25]] = { nofree nosync nounwind } +; IS__TUNIT_NPM: attributes #[[ATTR26]] = { readnone willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR27]] = { nounwind } +; IS__TUNIT_NPM: attributes #[[ATTR28]] = { willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } @@ -2169,11 +2348,19 @@ ; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR17:[0-9]+]] = { noreturn nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR19]] = { nofree nosync nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR20]] = { nofree nosync nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR21]] = { willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR22]] = { nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR23]] = { nounwind readnone } +; IS__CGSCC_OPM: attributes #[[ATTR19]] = { readonly } +; IS__CGSCC_OPM: attributes #[[ATTR20:[0-9]+]] = { readnone } +; IS__CGSCC_OPM: attributes #[[ATTR21]] = { mustprogress } +; IS__CGSCC_OPM: attributes #[[ATTR22:[0-9]+]] = { readonly mustprogress } +; IS__CGSCC_OPM: attributes #[[ATTR23]] = { readonly willreturn mustprogress } +; IS__CGSCC_OPM: attributes #[[ATTR24]] = { nosync readnone willreturn mustprogress } +; IS__CGSCC_OPM: attributes #[[ATTR25]] = { readonly willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR26]] = { nofree nosync nounwind readnone } +; IS__CGSCC_OPM: attributes #[[ATTR27]] = { nofree nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR28]] = { readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR29]] = { nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR30]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR31]] = { nounwind readnone } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } @@ -2196,8 +2383,16 @@ ; IS__CGSCC_NPM: attributes #[[ATTR18:[0-9]+]] = { noreturn nounwind } ; IS__CGSCC_NPM: attributes #[[ATTR19]] = { nofree norecurse nosync nounwind readnone } ; IS__CGSCC_NPM: attributes #[[ATTR20]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR21]] = { nofree nosync nounwind readnone } -; IS__CGSCC_NPM: attributes #[[ATTR22]] = { nofree nosync nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR23]] = { willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR24]] = { nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR21]] = { readonly } +; IS__CGSCC_NPM: attributes #[[ATTR22:[0-9]+]] = { readnone } +; IS__CGSCC_NPM: attributes #[[ATTR23]] = { mustprogress } +; IS__CGSCC_NPM: attributes #[[ATTR24:[0-9]+]] = { readonly mustprogress } +; IS__CGSCC_NPM: attributes #[[ATTR25]] = { readonly willreturn mustprogress } +; IS__CGSCC_NPM: attributes #[[ATTR26]] = { nosync readnone willreturn mustprogress } +; IS__CGSCC_NPM: attributes #[[ATTR27]] = { readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR28]] = { nofree nosync nounwind readnone } +; IS__CGSCC_NPM: attributes #[[ATTR29]] = { nofree nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR30]] = { readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR31]] = { nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR32]] = { willreturn } ;.