Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -2121,6 +2121,15 @@ // The NoBuiltinAttr attached to the target FunctionDecl. const NoBuiltinAttr *NBA = nullptr; + // Some ABIs may result in additional accesses to arguments that may + // otherwise not be present. + auto AddPotentialArgAccess = [&]() { + llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory); + if (A.isValid()) + FuncAttrs.addMemoryAttr(A.getMemoryEffects() | + llvm::MemoryEffects::argMemOnly()); + }; + // Collect function IR attributes based on declaration-specific // information. // FIXME: handle sseregparm someday... @@ -2167,18 +2176,18 @@ // 'const', 'pure' and 'noalias' attributed functions are also nounwind. if (TargetDecl->hasAttr()) { - FuncAttrs.addAttribute(llvm::Attribute::ReadNone); + FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none()); FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); // gcc specifies that 'const' functions have greater restrictions than // 'pure' functions, so they also cannot have infinite loops. FuncAttrs.addAttribute(llvm::Attribute::WillReturn); } else if (TargetDecl->hasAttr()) { - FuncAttrs.addAttribute(llvm::Attribute::ReadOnly); + FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly()); FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); // gcc specifies that 'pure' functions cannot have infinite loops. FuncAttrs.addAttribute(llvm::Attribute::WillReturn); } else if (TargetDecl->hasAttr()) { - FuncAttrs.addAttribute(llvm::Attribute::ArgMemOnly); + FuncAttrs.addMemoryAttr(llvm::MemoryEffects::argMemOnly()); FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); } if (TargetDecl->hasAttr()) @@ -2356,8 +2365,7 @@ case ABIArgInfo::InAlloca: case ABIArgInfo::Indirect: { // inalloca and sret disable readnone and readonly - FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly) - .removeAttribute(llvm::Attribute::ReadNone); + AddPotentialArgAccess(); break; } @@ -2527,9 +2535,7 @@ Attrs.addAlignmentAttr(Align.getQuantity()); // byval disables readnone and readonly. - FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly) - .removeAttribute(llvm::Attribute::ReadNone); - + AddPotentialArgAccess(); break; } case ABIArgInfo::IndirectAliased: { @@ -2545,8 +2551,7 @@ case ABIArgInfo::InAlloca: // inalloca disables readnone and readonly. - FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly) - .removeAttribute(llvm::Attribute::ReadNone); + AddPotentialArgAccess(); continue; } Index: clang/lib/CodeGen/CGObjCMac.cpp =================================================================== --- clang/lib/CodeGen/CGObjCMac.cpp +++ clang/lib/CodeGen/CGObjCMac.cpp @@ -737,14 +737,17 @@ // Also it is safe to make it readnone, since we never load or store the // classref except by calling this function. llvm::Type *params[] = { Int8PtrPtrTy }; + llvm::LLVMContext &C = CGM.getLLVMContext(); + llvm::AttributeSet AS = llvm::AttributeSet::get(C, { + llvm::Attribute::get(C, llvm::Attribute::NonLazyBind), + llvm::Attribute::getWithMemoryEffects(C, llvm::MemoryEffects::none()), + llvm::Attribute::get(C, llvm::Attribute::NoUnwind), + }); llvm::FunctionCallee F = CGM.CreateRuntimeFunction( llvm::FunctionType::get(ClassnfABIPtrTy, params, false), "objc_loadClassref", llvm::AttributeList::get(CGM.getLLVMContext(), - llvm::AttributeList::FunctionIndex, - {llvm::Attribute::NonLazyBind, - llvm::Attribute::ReadNone, - llvm::Attribute::NoUnwind})); + llvm::AttributeList::FunctionIndex, AS)); if (!CGM.getTriple().isOSBinFormatCOFF()) cast(F.getCallee())->setLinkage( llvm::Function::ExternalWeakLinkage); Index: clang/lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- clang/lib/CodeGen/ItaniumCXXABI.cpp +++ clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1325,8 +1325,9 @@ llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false); // Mark the function as nounwind readonly. - llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind, - llvm::Attribute::ReadOnly }; + llvm::AttrBuilder FuncAttrs(CGF.getLLVMContext()); + FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); + FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly()); llvm::AttributeList Attrs = llvm::AttributeList::get( CGF.getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs); Index: clang/test/CodeGen/asm-attrs.c =================================================================== --- clang/test/CodeGen/asm-attrs.c +++ clang/test/CodeGen/asm-attrs.c @@ -10,9 +10,9 @@ // CHECK: call void asm sideeffect "foo7", {{.*}} [[NOATTRS]] // CHECK: call i32 asm "foo8", {{.*}} [[READNONE]] -// CHECK: attributes [[READNONE]] = { nounwind readnone } +// CHECK: attributes [[READNONE]] = { nounwind memory(none) } // CHECK: attributes [[NOATTRS]] = { nounwind } -// CHECK: attributes [[READONLY]] = { nounwind readonly } +// CHECK: attributes [[READONLY]] = { nounwind memory(read) } int g0, g1; Index: clang/test/CodeGen/builtin-sqrt.c =================================================================== --- clang/test/CodeGen/builtin-sqrt.c +++ clang/test/CodeGen/builtin-sqrt.c @@ -8,8 +8,8 @@ } // HAS_ERRNO: declare float @sqrtf(float noundef) [[ATTR:#[0-9]+]] -// HAS_ERRNO-NOT: attributes [[ATTR]] = {{{.*}} readnone +// HAS_ERRNO-NOT: attributes [[ATTR]] = {{{.*}} memory(none) // NO_ERRNO: declare float @llvm.sqrt.f32(float) [[ATTR:#[0-9]+]] -// NO_ERRNO: attributes [[ATTR]] = { nocallback nofree nosync nounwind readnone {{.*}}} +// NO_ERRNO: attributes [[ATTR]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } Index: clang/test/CodeGen/complex-builtins.c =================================================================== --- clang/test/CodeGen/complex-builtins.c +++ clang/test/CodeGen/complex-builtins.c @@ -197,9 +197,9 @@ // HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl(ptr noundef byval({ x86_fp80, x86_fp80 }) align 16) [[NOT_READNONE]] }; -// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// NO__ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} } // NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} } // HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} } -// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} } // HAS_ERRNO: attributes [[WILLRETURN_NOT_READNONE]] = { nounwind willreturn {{.*}} } Index: clang/test/CodeGen/complex-libcalls.c =================================================================== --- clang/test/CodeGen/complex-libcalls.c +++ clang/test/CodeGen/complex-libcalls.c @@ -197,9 +197,9 @@ // HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl(ptr noundef byval({ x86_fp80, x86_fp80 }) align 16) [[NOT_READNONE]] }; -// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// NO__ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} } // NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} } // HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} } -// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} } // HAS_ERRNO: attributes [[WILLRETURN_NOT_READNONE]] = { nounwind willreturn {{.*}} } Index: clang/test/CodeGen/function-attributes.c =================================================================== --- clang/test/CodeGen/function-attributes.c +++ clang/test/CodeGen/function-attributes.c @@ -111,9 +111,9 @@ // CHECK: attributes [[NUW]] = { nounwind optsize{{.*}} } // CHECK: attributes [[AI]] = { alwaysinline nounwind optsize{{.*}} } -// CHECK: attributes [[NUW_OS_RN]] = { nounwind optsize readnone{{.*}} } +// CHECK: attributes [[NUW_OS_RN]] = { nounwind optsize willreturn memory(none){{.*}} } // CHECK: attributes [[SR]] = { nounwind optsize{{.*}} "stackrealign"{{.*}} } // CHECK: attributes [[RT]] = { nounwind optsize returns_twice{{.*}} } // CHECK: attributes [[NR]] = { noreturn optsize } -// CHECK: attributes [[NUW_RN]] = { nounwind optsize readnone willreturn } +// CHECK: attributes [[NUW_RN]] = { nounwind optsize willreturn memory(none) } // CHECK: attributes [[RT_CALL]] = { optsize returns_twice } Index: clang/test/CodeGen/libcall-declarations.c =================================================================== --- clang/test/CodeGen/libcall-declarations.c +++ clang/test/CodeGen/libcall-declarations.c @@ -614,8 +614,8 @@ // CHECK-ERRNO: declare { double, double } @ctanh(double noundef, double noundef) [[NONCONST]] // CHECK-ERRNO: declare <2 x float> @ctanhf(<2 x float> noundef) [[NONCONST]] -// CHECK-NOERRNO: attributes [[NUWRN]] = { nounwind readnone{{.*}} } -// CHECK-NOERRNO: attributes [[NUWRO]] = { nounwind readonly{{.*}} } +// CHECK-NOERRNO: attributes [[NUWRN]] = { nounwind willreturn memory(none){{.*}} } +// CHECK-NOERRNO: attributes [[NUWRO]] = { nounwind willreturn memory(read){{.*}} } -// CHECK-ERRNO: attributes [[NUWRN]] = { nounwind readnone{{.*}} } -// CHECK-ERRNO: attributes [[NUWRO]] = { nounwind readonly{{.*}} } +// CHECK-ERRNO: attributes [[NUWRN]] = { nounwind willreturn memory(none){{.*}} } +// CHECK-ERRNO: attributes [[NUWRO]] = { nounwind willreturn memory(read){{.*}} } Index: clang/test/CodeGen/libcalls.c =================================================================== --- clang/test/CodeGen/libcalls.c +++ clang/test/CodeGen/libcalls.c @@ -124,5 +124,5 @@ } // CHECK-YES: attributes [[NUW]] = { nounwind "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+x87" } -// CHECK-NO-DAG: attributes [[NUW_RN]] = { nounwind readnone{{.*}} } -// CHECK-NO-DAG: attributes [[NUW_RNI]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +// CHECK-NO-DAG: attributes [[NUW_RN]] = { nounwind willreturn memory(none){{.*}} } +// CHECK-NO-DAG: attributes [[NUW_RNI]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } Index: clang/test/CodeGen/math-builtins.c =================================================================== --- clang/test/CodeGen/math-builtins.c +++ clang/test/CodeGen/math-builtins.c @@ -680,16 +680,16 @@ // HAS_ERRNO: declare fp128 @llvm.trunc.f128(fp128) [[READNONE_INTRINSIC]] }; -// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } -// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } +// NO__ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} } +// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} } // NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} } -// NO__ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} } +// NO__ERRNO: attributes [[PURE]] = { {{.*}}memory(read){{.*}} } // HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} } -// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } -// HAS_ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} } -// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} } +// HAS_ERRNO: attributes [[PURE]] = { {{.*}}memory(read){{.*}} } +// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} } -// HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } -// HAS_ERRNO_WIN: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} } +// HAS_ERRNO_WIN: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} } Index: clang/test/CodeGen/math-libcalls.c =================================================================== --- clang/test/CodeGen/math-libcalls.c +++ clang/test/CodeGen/math-libcalls.c @@ -704,18 +704,18 @@ // HAS_ERRNO: declare x86_fp80 @llvm.trunc.f80(x86_fp80) [[READNONE_INTRINSIC]] }; -// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } -// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } +// NO__ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} } +// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} } // NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} } -// NO__ERRNO: attributes [[READONLY]] = { {{.*}}readonly{{.*}} } +// NO__ERRNO: attributes [[READONLY]] = { {{.*}}memory(read){{.*}} } // HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} } -// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } -// HAS_ERRNO: attributes [[READONLY]] = { {{.*}}readonly{{.*}} } -// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} } +// HAS_ERRNO: attributes [[READONLY]] = { {{.*}}memory(read){{.*}} } +// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} } // HAS_MAYTRAP: attributes [[NOT_READNONE]] = { nounwind {{.*}} } -// HAS_MAYTRAP: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// HAS_MAYTRAP: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} } -// HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } -// HAS_ERRNO_WIN: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} } +// HAS_ERRNO_WIN: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} } Index: clang/test/CodeGen/ms-declspecs.c =================================================================== --- clang/test/CodeGen/ms-declspecs.c +++ clang/test/CodeGen/ms-declspecs.c @@ -41,4 +41,4 @@ // CHECK: attributes [[NUW]] = { nounwind{{.*}} } // CHECK: attributes [[NI]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NR]] = { noreturn } -// CHECK: attributes [[NA]] = { argmemonly nounwind{{.*}} } +// CHECK: attributes [[NA]] = { nounwind memory(argmem: readwrite){{.*}} } Index: clang/test/CodeGen/pragma-weak.c =================================================================== --- clang/test/CodeGen/pragma-weak.c +++ clang/test/CodeGen/pragma-weak.c @@ -202,4 +202,4 @@ int correct_linkage; // CHECK: attributes [[NI]] = { noinline nounwind{{.*}} } -// CHECK: attributes [[RN]] = { noinline nounwind optnone readnone{{.*}} } +// CHECK: attributes [[RN]] = { noinline nounwind optnone willreturn memory(none){{.*}} } Index: clang/test/CodeGen/struct-passing.c =================================================================== --- clang/test/CodeGen/struct-passing.c +++ clang/test/CodeGen/struct-passing.c @@ -23,5 +23,5 @@ // CHECK: declare void @f4({{.*}} byval({{.*}}) align 4) // CHECK: declare void @f5({{.*}} byval({{.*}}) align 4) -// CHECK: attributes [[RN]] = { nounwind readnone{{.*}} } -// CHECK: attributes [[RO]] = { nounwind readonly{{.*}} } +// CHECK: attributes [[RN]] = { nounwind willreturn memory(none){{.*}} } +// CHECK: attributes [[RO]] = { nounwind willreturn memory(read){{.*}} } Index: clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp =================================================================== --- clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp +++ clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp @@ -15,8 +15,8 @@ // CHECK: declare noundef i32 @_Z1tv() [[TF2:#[0-9]+]] // CHECK: attributes [[TF]] = { {{.*}} } -// CHECK: attributes [[NUW_RN]] = { nounwind readnone willreturn{{.*}} } -// CHECK: attributes [[NUW_RO]] = { nounwind readonly willreturn{{.*}} } +// CHECK: attributes [[NUW_RN]] = { nounwind willreturn memory(none){{.*}} } +// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read){{.*}} } // CHECK: attributes [[TF2]] = { {{.*}} } -// CHECK: attributes [[NUW_RN_CALL]] = { nounwind readnone willreturn } -// CHECK: attributes [[NUW_RO_CALL]] = { nounwind readonly willreturn } +// CHECK: attributes [[NUW_RN_CALL]] = { nounwind willreturn memory(none) } +// CHECK: attributes [[NUW_RO_CALL]] = { nounwind willreturn memory(read) } Index: clang/test/CodeGenCXX/dynamic-cast.cpp =================================================================== --- clang/test/CodeGenCXX/dynamic-cast.cpp +++ clang/test/CodeGenCXX/dynamic-cast.cpp @@ -20,5 +20,5 @@ // CHECK: declare ptr @__dynamic_cast(ptr, ptr, ptr, i64) [[NUW_RO:#[0-9]+]] -// CHECK: attributes [[NUW_RO]] = { nounwind readonly } +// CHECK: attributes [[NUW_RO]] = { nounwind memory(read) } // CHECK: attributes [[NR]] = { noreturn } Index: clang/test/CodeGenCXX/threadlocal_address.cpp =================================================================== --- clang/test/CodeGenCXX/threadlocal_address.cpp +++ clang/test/CodeGenCXX/threadlocal_address.cpp @@ -51,4 +51,4 @@ // CHECK-O1-NEXT: store i32 %[[INC]], ptr %[[J_ADDR]] // CHECK-O1-NEXT: ret i32 %[[INC]] // -// CHECK: attributes #[[ATTR_NUM]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +// CHECK: attributes #[[ATTR_NUM]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } Index: clang/test/CodeGenObjC/class-stubs.m =================================================================== --- clang/test/CodeGenObjC/class-stubs.m +++ clang/test/CodeGenObjC/class-stubs.m @@ -81,4 +81,4 @@ @end // -- calls to objc_loadClassRef() are readnone -// CHECK: attributes [[ATTRLIST]] = { nounwind nonlazybind readnone } +// CHECK: attributes [[ATTRLIST]] = { nounwind nonlazybind memory(none) } Index: clang/test/CodeGenOpenCL/builtins-amdgcn.cl =================================================================== --- clang/test/CodeGenOpenCL/builtins-amdgcn.cl +++ clang/test/CodeGenOpenCL/builtins-amdgcn.cl @@ -796,7 +796,7 @@ // CHECK-DAG: [[$WI_RANGE]] = !{i32 0, i32 1024} // CHECK-DAG: [[$WS_RANGE]] = !{i16 1, i16 1025} -// CHECK-DAG: attributes #[[$NOUNWIND_READONLY:[0-9]+]] = { nofree nounwind readonly } +// CHECK-DAG: attributes #[[$NOUNWIND_READONLY:[0-9]+]] = { nofree nounwind memory(read) } // CHECK-DAG: attributes #[[$READ_EXEC_ATTRS]] = { convergent } // CHECK-DAG: ![[$EXEC]] = !{!"exec"} // CHECK-DAG: ![[$EXEC_LO]] = !{!"exec_lo"} Index: clang/test/CodeGenOpenCL/fdeclare-opencl-builtins.cl =================================================================== --- clang/test/CodeGenOpenCL/fdeclare-opencl-builtins.cl +++ clang/test/CodeGenOpenCL/fdeclare-opencl-builtins.cl @@ -49,6 +49,6 @@ } // CHECK: attributes [[ATTR_CONST]] = -// CHECK-SAME: readnone +// CHECK-SAME: memory(none) // CHECK: attributes [[ATTR_PURE]] = -// CHECK-SAME: readonly +// CHECK-SAME: memory(read) Index: clang/test/OpenMP/barrier_codegen.cpp =================================================================== --- clang/test/OpenMP/barrier_codegen.cpp +++ clang/test/OpenMP/barrier_codegen.cpp @@ -45,7 +45,7 @@ // CLANGCG: declare i32 @__kmpc_global_thread_num(ptr) // IRBUILDER: ; Function Attrs: nounwind // IRBUILDER-NEXT: declare i32 @__kmpc_global_thread_num(ptr) # -// IRBUILDER_OPT: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly +// IRBUILDER_OPT: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) // IRBUILDER_OPT-NEXT: declare i32 @__kmpc_global_thread_num(ptr nocapture nofree readonly) # // CHECK: define {{.+}} [[TMAIN_INT]]( Index: clang/test/OpenMP/irbuilder_simd_aligned.cpp =================================================================== --- clang/test/OpenMP/irbuilder_simd_aligned.cpp +++ clang/test/OpenMP/irbuilder_simd_aligned.cpp @@ -164,7 +164,7 @@ //. // CHECK: attributes #0 = { mustprogress noinline nounwind optnone "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } // CHECK: attributes #1 = { noinline nounwind optnone "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } -// CHECK: attributes #2 = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } +// CHECK: attributes #2 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } //. // CHECK: !0 = !{i32 1, !"wchar_size", i32 4} // CHECK: !1 = !{i32 7, !"openmp", i32 50} Index: clang/test/Sema/libbuiltins-ctype-powerpc64.c =================================================================== --- clang/test/Sema/libbuiltins-ctype-powerpc64.c +++ clang/test/Sema/libbuiltins-ctype-powerpc64.c @@ -61,5 +61,5 @@ // CHECK: declare signext i32 @tolower(i32 noundef signext) [[NUW_RO:#[0-9]+]] // CHECK: declare signext i32 @toupper(i32 noundef signext) [[NUW_RO:#[0-9]+]] -// CHECK: attributes [[NUW_RO]] = { nounwind readonly{{.*}} } -// CHECK: attributes [[NUW_RO_CALL]] = { nounwind readonly willreturn } +// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read){{.*}} } +// CHECK: attributes [[NUW_RO_CALL]] = { nounwind willreturn memory(read) } Index: clang/test/Sema/libbuiltins-ctype-x86_64.c =================================================================== --- clang/test/Sema/libbuiltins-ctype-x86_64.c +++ clang/test/Sema/libbuiltins-ctype-x86_64.c @@ -61,5 +61,5 @@ // CHECK: declare i32 @tolower(i32 noundef) [[NUW_RO:#[0-9]+]] // CHECK: declare i32 @toupper(i32 noundef) [[NUW_RO:#[0-9]+]] -// CHECK: attributes [[NUW_RO]] = { nounwind readonly{{.*}} } -// CHECK: attributes [[NUW_RO_CALL]] = { nounwind readonly willreturn } +// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read){{.*}} } +// CHECK: attributes [[NUW_RO_CALL]] = { nounwind willreturn memory(read) } Index: llvm/include/llvm/AsmParser/LLToken.h =================================================================== --- llvm/include/llvm/AsmParser/LLToken.h +++ llvm/include/llvm/AsmParser/LLToken.h @@ -190,6 +190,11 @@ kw_argmem, kw_inaccessiblemem, + // Legacy memory attributes: + kw_argmemonly, + kw_inaccessiblememonly, + kw_inaccessiblemem_or_argmemonly, + kw_type, kw_opaque, Index: llvm/include/llvm/Frontend/OpenMP/OMPKinds.def =================================================================== --- llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -487,6 +487,7 @@ #define EnumAttr(Kind) Attribute::get(Ctx, Attribute::AttrKind::Kind) #define EnumAttrInt(Kind, N) Attribute::get(Ctx, Attribute::AttrKind::Kind, N) #define AllocSizeAttr(N, M) Attribute::getWithAllocSizeArgs(Ctx, N, M) +#define MemoryAttr(ME) Attribute::getWithMemoryEffects(Ctx, ME) #define AttributeSet(...) \ AttributeSet::get(Ctx, ArrayRef({__VA_ARGS__})) @@ -496,27 +497,29 @@ #define __OMP_ATTRS_SET(VarName, AttrSet) OMP_ATTRS_SET(VarName, AttrSet) -__OMP_ATTRS_SET(GetterAttrs, - OptimisticAttributes - ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(ReadOnly), - EnumAttr(NoSync), EnumAttr(NoFree), - EnumAttr(InaccessibleMemOnly), - EnumAttr(WillReturn)) - : AttributeSet(EnumAttr(NoUnwind))) -__OMP_ATTRS_SET(GetterArgWriteAttrs, - OptimisticAttributes - ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync), - EnumAttr(NoFree), - EnumAttr(InaccessibleMemOrArgMemOnly), - EnumAttr(WillReturn)) - : AttributeSet(EnumAttr(NoUnwind))) -__OMP_ATTRS_SET(SetterAttrs, - OptimisticAttributes - ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(WriteOnly), - EnumAttr(NoSync), EnumAttr(NoFree), - EnumAttr(InaccessibleMemOnly), - EnumAttr(WillReturn)) - : AttributeSet(EnumAttr(NoUnwind))) +__OMP_ATTRS_SET( + GetterAttrs, + OptimisticAttributes + ? AttributeSet( + EnumAttr(NoUnwind), EnumAttr(NoSync), EnumAttr(NoFree), + EnumAttr(WillReturn), + MemoryAttr(MemoryEffects::inaccessibleMemOnly(ModRefInfo::Ref))) + : AttributeSet(EnumAttr(NoUnwind))) +__OMP_ATTRS_SET( + GetterArgWriteAttrs, + OptimisticAttributes + ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync), EnumAttr(NoFree), + EnumAttr(WillReturn), + MemoryAttr(MemoryEffects::inaccessibleOrArgMemOnly())) + : AttributeSet(EnumAttr(NoUnwind))) +__OMP_ATTRS_SET( + SetterAttrs, + OptimisticAttributes + ? AttributeSet( + EnumAttr(NoUnwind), EnumAttr(NoSync), EnumAttr(NoFree), + EnumAttr(WillReturn), + MemoryAttr(MemoryEffects::inaccessibleMemOnly(ModRefInfo::Mod))) + : AttributeSet(EnumAttr(NoUnwind))) __OMP_ATTRS_SET(DefaultAttrs, OptimisticAttributes @@ -529,12 +532,13 @@ ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(Convergent)) : AttributeSet(EnumAttr(NoUnwind), EnumAttr(Convergent))) -__OMP_ATTRS_SET(InaccessibleArgOnlyAttrs, - OptimisticAttributes - ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync), - EnumAttr(InaccessibleMemOrArgMemOnly), - EnumAttr(WillReturn), EnumAttr(NoFree)) - : AttributeSet(EnumAttr(NoUnwind))) +__OMP_ATTRS_SET( + InaccessibleArgOnlyAttrs, + OptimisticAttributes + ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync), EnumAttr(NoFree), + EnumAttr(WillReturn), + MemoryAttr(MemoryEffects::inaccessibleOrArgMemOnly())) + : AttributeSet(EnumAttr(NoUnwind))) __OMP_ATTRS_SET(AlwaysInlineAttrs, OptimisticAttributes @@ -542,12 +546,13 @@ : AttributeSet(EnumAttr(AlwaysInline))) #if 0 -__OMP_ATTRS_SET(InaccessibleOnlyAttrs, - OptimisticAttributes - ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync), - EnumAttr(InaccessibleMemOnly), - EnumAttr(WillReturn), EnumAttr(NoFree)) - : AttributeSet(EnumAttr(NoUnwind))) +__OMP_ATTRS_SET( + InaccessibleOnlyAttrs, + OptimisticAttributes + ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync), EnumAttr(NoFree), + EnumAttr(WillReturn), + MemoryAttr(MemoryEffects::inaccessibleMemOnly())) + : AttributeSet(EnumAttr(NoUnwind))) #endif __OMP_ATTRS_SET(AllocAttrs, Index: llvm/include/llvm/IR/Attributes.h =================================================================== --- llvm/include/llvm/IR/Attributes.h +++ llvm/include/llvm/IR/Attributes.h @@ -146,6 +146,7 @@ static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty); static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty); static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind); + static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME); /// For a typed attribute, return the equivalent attribute with the type /// changed to \p ReplacementTy. @@ -379,6 +380,7 @@ Optional getVScaleRangeMax() const; UWTableKind getUWTableKind() const; AllocFnKind getAllocKind() const; + MemoryEffects getMemoryEffects() const; std::string getAsString(bool InAttrGrp = false) const; /// Return true if this attribute set belongs to the LLVMContext. @@ -878,6 +880,9 @@ AllocFnKind getAllocKind() const; + /// Returns memory effects of the function. + MemoryEffects getMemoryEffects() const; + /// Return the attributes at the index as a string. std::string getAsString(unsigned Index, bool InAttrGrp = false) const; Index: llvm/include/llvm/IR/Attributes.td =================================================================== --- llvm/include/llvm/IR/Attributes.td +++ llvm/include/llvm/IR/Attributes.td @@ -64,9 +64,6 @@ /// inline=always. def AlwaysInline : EnumAttr<"alwaysinline", [FnAttr]>; -/// Function can access memory only using pointers based on its arguments. -def ArgMemOnly : EnumAttr<"argmemonly", [FnAttr]>; - /// Callee is recognized as a builtin, despite nobuiltin attribute on its /// declaration. def Builtin : EnumAttr<"builtin", [FnAttr]>; @@ -106,14 +103,6 @@ /// symbol. def FnRetThunkExtern : EnumAttr<"fn_ret_thunk_extern", [FnAttr]>; -/// Function may only access memory that is inaccessible from IR. -def InaccessibleMemOnly : EnumAttr<"inaccessiblememonly", [FnAttr]>; - -/// Function may only access memory that is either inaccessible from the IR, -/// or pointed to by its pointer arguments. -def InaccessibleMemOrArgMemOnly : EnumAttr<"inaccessiblemem_or_argmemonly", - [FnAttr]>; - /// Pass structure in an alloca. def InAlloca : TypeAttr<"inalloca", [ParamAttr]>; @@ -218,10 +207,10 @@ def Preallocated : TypeAttr<"preallocated", [FnAttr, ParamAttr]>; /// Function does not access memory. -def ReadNone : EnumAttr<"readnone", [FnAttr, ParamAttr]>; +def ReadNone : EnumAttr<"readnone", [ParamAttr]>; /// Function only reads from memory. -def ReadOnly : EnumAttr<"readonly", [FnAttr, ParamAttr]>; +def ReadOnly : EnumAttr<"readonly", [ParamAttr]>; /// Return value is always equal to this argument. def Returned : EnumAttr<"returned", [ParamAttr]>; @@ -306,7 +295,7 @@ def WillReturn : EnumAttr<"willreturn", [FnAttr]>; /// Function only writes to memory. -def WriteOnly : EnumAttr<"writeonly", [FnAttr, ParamAttr]>; +def WriteOnly : EnumAttr<"writeonly", [ParamAttr]>; /// Zero extended before/after call. def ZExt : EnumAttr<"zeroext", [ParamAttr, RetAttr]>; Index: llvm/include/llvm/IR/Function.h =================================================================== --- llvm/include/llvm/IR/Function.h +++ llvm/include/llvm/IR/Function.h @@ -491,54 +491,35 @@ void setPresplitCoroutine() { addFnAttr(Attribute::PresplitCoroutine); } void setSplittedCoroutine() { removeFnAttr(Attribute::PresplitCoroutine); } + MemoryEffects getMemoryEffects() const; + void setMemoryEffects(MemoryEffects ME); + /// Determine if the function does not access memory. - bool doesNotAccessMemory() const { - return hasFnAttribute(Attribute::ReadNone); - } - void setDoesNotAccessMemory() { - addFnAttr(Attribute::ReadNone); - } + bool doesNotAccessMemory() const; + void setDoesNotAccessMemory(); /// Determine if the function does not access or only reads memory. - bool onlyReadsMemory() const { - return doesNotAccessMemory() || hasFnAttribute(Attribute::ReadOnly); - } - void setOnlyReadsMemory() { - addFnAttr(Attribute::ReadOnly); - } + bool onlyReadsMemory() const; + void setOnlyReadsMemory(); /// Determine if the function does not access or only writes memory. - bool onlyWritesMemory() const { - return doesNotAccessMemory() || hasFnAttribute(Attribute::WriteOnly); - } - void setOnlyWritesMemory() { - addFnAttr(Attribute::WriteOnly); - } + bool onlyWritesMemory() const; + void setOnlyWritesMemory(); /// Determine if the call can access memmory only using pointers based /// on its arguments. - bool onlyAccessesArgMemory() const { - return hasFnAttribute(Attribute::ArgMemOnly); - } - void setOnlyAccessesArgMemory() { addFnAttr(Attribute::ArgMemOnly); } + bool onlyAccessesArgMemory() const; + void setOnlyAccessesArgMemory(); /// Determine if the function may only access memory that is /// inaccessible from the IR. - bool onlyAccessesInaccessibleMemory() const { - return hasFnAttribute(Attribute::InaccessibleMemOnly); - } - void setOnlyAccessesInaccessibleMemory() { - addFnAttr(Attribute::InaccessibleMemOnly); - } + bool onlyAccessesInaccessibleMemory() const; + void setOnlyAccessesInaccessibleMemory(); /// Determine if the function may only access memory that is /// either inaccessible from the IR or pointed to by its arguments. - bool onlyAccessesInaccessibleMemOrArgMem() const { - return hasFnAttribute(Attribute::InaccessibleMemOrArgMemOnly); - } - void setOnlyAccessesInaccessibleMemOrArgMem() { - addFnAttr(Attribute::InaccessibleMemOrArgMemOnly); - } + bool onlyAccessesInaccessibleMemOrArgMem() const; + void setOnlyAccessesInaccessibleMemOrArgMem(); /// Determine if the function cannot return. bool doesNotReturn() const { Index: llvm/include/llvm/IR/InstrTypes.h =================================================================== --- llvm/include/llvm/IR/InstrTypes.h +++ llvm/include/llvm/IR/InstrTypes.h @@ -1847,47 +1847,37 @@ /// Return true if the call should not be inlined. bool isNoInline() const { return hasFnAttr(Attribute::NoInline); } void setIsNoInline() { addFnAttr(Attribute::NoInline); } + + MemoryEffects getMemoryEffects() const; + void setMemoryEffects(MemoryEffects ME); + /// Determine if the call does not access memory. - bool doesNotAccessMemory() const { return hasFnAttr(Attribute::ReadNone); } - void setDoesNotAccessMemory() { addFnAttr(Attribute::ReadNone); } + bool doesNotAccessMemory() const; + void setDoesNotAccessMemory(); /// Determine if the call does not access or only reads memory. - bool onlyReadsMemory() const { - return hasImpliedFnAttr(Attribute::ReadOnly); - } - - void setOnlyReadsMemory() { addFnAttr(Attribute::ReadOnly); } + bool onlyReadsMemory() const; + void setOnlyReadsMemory(); /// Determine if the call does not access or only writes memory. - bool onlyWritesMemory() const { - return hasImpliedFnAttr(Attribute::WriteOnly); - } - void setOnlyWritesMemory() { addFnAttr(Attribute::WriteOnly); } + bool onlyWritesMemory() const; + void setOnlyWritesMemory(); /// Determine if the call can access memmory only using pointers based /// on its arguments. - bool onlyAccessesArgMemory() const { - return hasFnAttr(Attribute::ArgMemOnly); - } - void setOnlyAccessesArgMemory() { addFnAttr(Attribute::ArgMemOnly); } + bool onlyAccessesArgMemory() const; + void setOnlyAccessesArgMemory(); /// Determine if the function may only access memory that is /// inaccessible from the IR. - bool onlyAccessesInaccessibleMemory() const { - return hasFnAttr(Attribute::InaccessibleMemOnly); - } - void setOnlyAccessesInaccessibleMemory() { - addFnAttr(Attribute::InaccessibleMemOnly); - } + bool onlyAccessesInaccessibleMemory() const; + void setOnlyAccessesInaccessibleMemory(); /// Determine if the function may only access memory that is /// either inaccessible from the IR or pointed to by its arguments. - bool onlyAccessesInaccessibleMemOrArgMem() const { - return hasFnAttr(Attribute::InaccessibleMemOrArgMemOnly); - } - void setOnlyAccessesInaccessibleMemOrArgMem() { - addFnAttr(Attribute::InaccessibleMemOrArgMemOnly); - } + bool onlyAccessesInaccessibleMemOrArgMem() const; + void setOnlyAccessesInaccessibleMemOrArgMem(); + /// Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } void setDoesNotReturn() { addFnAttr(Attribute::NoReturn); } @@ -2107,43 +2097,6 @@ return false; } - /// Is the function attribute S disallowed by some operand bundle on - /// this operand bundle user? - bool isFnAttrDisallowedByOpBundle(StringRef S) const { - // Operand bundles only possibly disallow memory access attributes. All - // String attributes are fine. - return false; - } - - /// Is the function attribute A disallowed by some operand bundle on - /// this operand bundle user? - bool isFnAttrDisallowedByOpBundle(Attribute::AttrKind A) const { - switch (A) { - default: - return false; - - case Attribute::InaccessibleMemOrArgMemOnly: - return hasReadingOperandBundles(); - - case Attribute::InaccessibleMemOnly: - return hasReadingOperandBundles(); - - case Attribute::ArgMemOnly: - return hasReadingOperandBundles(); - - case Attribute::ReadNone: - return hasReadingOperandBundles(); - - case Attribute::ReadOnly: - return hasClobberingOperandBundles(); - - case Attribute::WriteOnly: - return hasReadingOperandBundles(); - } - - llvm_unreachable("switch has a default case!"); - } - /// Used to keep track of an operand bundle. See the main comment on /// OperandBundleUser above. struct BundleOpInfo { @@ -2303,35 +2256,10 @@ if (Attrs.hasFnAttr(Kind)) return true; - // Operand bundles override attributes on the called function, but don't - // override attributes directly present on the call instruction. - if (isFnAttrDisallowedByOpBundle(Kind)) - return false; - return hasFnAttrOnCalledFunction(Kind); } template Attribute getFnAttrOnCalledFunction(AK Kind) const; - /// A specialized version of hasFnAttrImpl for when the caller wants to - /// know if an attribute's semantics are implied, not whether the attribute - /// is actually present. This distinction only exists when checking whether - /// something is readonly or writeonly since readnone implies both. The case - /// which motivates the specialized code is a callee with readnone, and an - /// operand bundle on the call which disallows readnone but not either - /// readonly or writeonly. - bool hasImpliedFnAttr(Attribute::AttrKind Kind) const { - assert((Kind == Attribute::ReadOnly || Kind == Attribute::WriteOnly) && - "use hasFnAttrImpl instead"); - if (Attrs.hasFnAttr(Kind) || Attrs.hasFnAttr(Attribute::ReadNone)) - return true; - - if (isFnAttrDisallowedByOpBundle(Kind)) - return false; - - return hasFnAttrOnCalledFunction(Kind) || - hasFnAttrOnCalledFunction(Attribute::ReadNone); - } - /// Determine whether the return value has the given attribute. Supports /// Attribute::AttrKind and StringRef as \p AttrKind types. template bool hasRetAttrImpl(AttrKind Kind) const { Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -740,30 +740,10 @@ return II && II->getIntrinsicID() == IID; } -static MemoryEffects getMemoryEffectsFromAttrs(AttributeSet Attrs) { - if (Attrs.hasAttribute(Attribute::ReadNone)) - return MemoryEffects::none(); - - ModRefInfo MR = ModRefInfo::ModRef; - if (Attrs.hasAttribute(Attribute::ReadOnly)) - MR = ModRefInfo::Ref; - else if (Attrs.hasAttribute(Attribute::WriteOnly)) - MR = ModRefInfo::Mod; - - if (Attrs.hasAttribute(Attribute::ArgMemOnly)) - return MemoryEffects::argMemOnly(MR); - if (Attrs.hasAttribute(Attribute::InaccessibleMemOnly)) - return MemoryEffects::inaccessibleMemOnly(MR); - if (Attrs.hasAttribute(Attribute::InaccessibleMemOrArgMemOnly)) - return MemoryEffects::inaccessibleOrArgMemOnly(MR); - return MemoryEffects(MR); -} - /// Returns the behavior when calling the given call site. MemoryEffects BasicAAResult::getMemoryEffects(const CallBase *Call, AAQueryInfo &AAQI) { - MemoryEffects Min = - getMemoryEffectsFromAttrs(Call->getAttributes().getFnAttrs()); + MemoryEffects Min = Call->getAttributes().getMemoryEffects(); if (const Function *F = dyn_cast(Call->getCalledOperand())) { MemoryEffects FuncME = AAQI.AAR.getMemoryEffects(F); @@ -791,7 +771,7 @@ MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef); } - return getMemoryEffectsFromAttrs(F->getAttributes().getFnAttrs()); + return F->getMemoryEffects(); } /// Returns true if this is a writeonly (i.e Mod only) parameter. Index: llvm/lib/AsmParser/LLLexer.cpp =================================================================== --- llvm/lib/AsmParser/LLLexer.cpp +++ llvm/lib/AsmParser/LLLexer.cpp @@ -649,6 +649,9 @@ KEYWORD(readwrite); KEYWORD(argmem); KEYWORD(inaccessiblemem); + KEYWORD(argmemonly); + KEYWORD(inaccessiblememonly); + KEYWORD(inaccessiblemem_or_argmemonly); KEYWORD(type); KEYWORD(opaque); Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -1472,6 +1472,31 @@ } } +static bool upgradeMemoryAttr(MemoryEffects &ME, lltok::Kind Kind) { + switch (Kind) { + case lltok::kw_readnone: + ME &= MemoryEffects::none(); + return true; + case lltok::kw_readonly: + ME &= MemoryEffects::readOnly(); + return true; + case lltok::kw_writeonly: + ME &= MemoryEffects::writeOnly(); + return true; + case lltok::kw_argmemonly: + ME &= MemoryEffects::argMemOnly(); + return true; + case lltok::kw_inaccessiblememonly: + ME &= MemoryEffects::inaccessibleMemOnly(); + return true; + case lltok::kw_inaccessiblemem_or_argmemonly: + ME &= MemoryEffects::inaccessibleOrArgMemOnly(); + return true; + default: + return false; + } +} + /// parseFnAttributeValuePairs /// ::= | '=' bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, @@ -1481,10 +1506,11 @@ B.clear(); + MemoryEffects ME = MemoryEffects::unknown(); while (true) { lltok::Kind Token = Lex.getKind(); if (Token == lltok::rbrace) - return HaveError; // Finished. + break; // Finished. if (Token == lltok::StringConstant) { if (parseStringAttribute(B)) @@ -1512,10 +1538,15 @@ if (Token == lltok::kw_builtin) BuiltinLoc = Loc; + if (upgradeMemoryAttr(ME, Token)) { + Lex.Lex(); + continue; + } + Attribute::AttrKind Attr = tokenToAttribute(Token); if (Attr == Attribute::None) { if (!InAttrGrp) - return HaveError; + break; return error(Lex.getLoc(), "unterminated attribute group"); } @@ -1528,6 +1559,10 @@ if (!Attribute::canUseAsFnAttr(Attr) && Attr != Attribute::Alignment) HaveError |= error(Loc, "this attribute does not apply to functions"); } + + if (ME != MemoryEffects::unknown()) + B.addMemoryAttr(ME); + return HaveError; } //===----------------------------------------------------------------------===// Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1718,8 +1718,8 @@ case Attribute::Convergent: return 1ULL << 46; case Attribute::SafeStack: return 1ULL << 47; case Attribute::NoRecurse: return 1ULL << 48; - case Attribute::InaccessibleMemOnly: return 1ULL << 49; - case Attribute::InaccessibleMemOrArgMemOnly: return 1ULL << 50; + // 1ULL << 49 is InaccessibleMemOnly, which is upgraded separately. + // 1ULL << 50 is InaccessibleMemOrArgMemOnly, which is upgraded separately. case Attribute::SwiftSelf: return 1ULL << 51; case Attribute::SwiftError: return 1ULL << 52; case Attribute::WriteOnly: return 1ULL << 53; @@ -1767,7 +1767,8 @@ /// been decoded from the given integer. This function must stay in sync with /// 'encodeLLVMAttributesForBitcode'. static void decodeLLVMAttributesForBitcode(AttrBuilder &B, - uint64_t EncodedAttrs) { + uint64_t EncodedAttrs, + uint64_t AttrIdx) { // The alignment is stored as a 16-bit raw value from bits 31--16. We shift // the bits above 31 down by 11 bits. unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; @@ -1776,8 +1777,43 @@ if (Alignment) B.addAlignmentAttr(Alignment); - addRawAttributeValue(B, ((EncodedAttrs & (0xfffffULL << 32)) >> 11) | - (EncodedAttrs & 0xffff)); + + uint64_t Attrs = ((EncodedAttrs & (0xfffffULL << 32)) >> 11) | + (EncodedAttrs & 0xffff); + + if (AttrIdx == AttributeList::FunctionIndex) { + // Upgrade old memory attributes. + MemoryEffects ME = MemoryEffects::unknown(); + if (Attrs & (1ULL << 9)) { + // ReadNone + Attrs &= ~(1ULL << 9); + ME &= MemoryEffects::none(); + } + if (Attrs & (1ULL << 10)) { + // ReadOnly + Attrs &= ~(1ULL << 10); + ME &= MemoryEffects::readOnly(); + } + if (Attrs & (1ULL << 49)) { + // InaccessibleMemOnly + Attrs &= ~(1ULL << 49); + ME &= MemoryEffects::inaccessibleMemOnly(); + } + if (Attrs & (1ULL << 50)) { + // InaccessibleMemOrArgMemOnly + Attrs &= ~(1ULL << 50); + ME &= MemoryEffects::inaccessibleOrArgMemOnly(); + } + if (Attrs & (1ULL << 53)) { + // WriteOnly + Attrs &= ~(1ULL << 53); + ME &= MemoryEffects::writeOnly(); + } + if (ME != MemoryEffects::unknown()) + B.addMemoryAttr(ME); + } + + addRawAttributeValue(B, Attrs); } Error BitcodeReader::parseAttributeBlock() { @@ -1824,7 +1860,7 @@ for (unsigned i = 0, e = Record.size(); i != e; i += 2) { AttrBuilder B(Context); - decodeLLVMAttributesForBitcode(B, Record[i+1]); + decodeLLVMAttributesForBitcode(B, Record[i+1], Record[i]); Attrs.push_back(AttributeList::get(Context, Record[i], B)); } @@ -1851,8 +1887,6 @@ return Attribute::Alignment; case bitc::ATTR_KIND_ALWAYS_INLINE: return Attribute::AlwaysInline; - case bitc::ATTR_KIND_ARGMEMONLY: - return Attribute::ArgMemOnly; case bitc::ATTR_KIND_BUILTIN: return Attribute::Builtin; case bitc::ATTR_KIND_BY_VAL: @@ -1869,10 +1903,6 @@ return Attribute::ElementType; case bitc::ATTR_KIND_FNRETTHUNK_EXTERN: return Attribute::FnRetThunkExtern; - case bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY: - return Attribute::InaccessibleMemOnly; - case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY: - return Attribute::InaccessibleMemOrArgMemOnly; case bitc::ATTR_KIND_INLINE_HINT: return Attribute::InlineHint; case bitc::ATTR_KIND_IN_REG: @@ -2039,6 +2069,31 @@ return Error::success(); } +static bool upgradeOldMemoryAttribute(MemoryEffects &ME, uint64_t EncodedKind) { + switch (EncodedKind) { + case bitc::ATTR_KIND_READ_NONE: + ME &= MemoryEffects::none(); + return true; + case bitc::ATTR_KIND_READ_ONLY: + ME &= MemoryEffects::readOnly(); + return true; + case bitc::ATTR_KIND_WRITEONLY: + ME &= MemoryEffects::writeOnly(); + return true; + case bitc::ATTR_KIND_ARGMEMONLY: + ME &= MemoryEffects::argMemOnly(); + return true; + case bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY: + ME &= MemoryEffects::inaccessibleMemOnly(); + return true; + case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY: + ME &= MemoryEffects::inaccessibleOrArgMemOnly(); + return true; + default: + return false; + } +} + Error BitcodeReader::parseAttributeGroupBlock() { if (Error Err = Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) return Err; @@ -2082,10 +2137,16 @@ uint64_t Idx = Record[1]; // Index of the object this attribute refers to. AttrBuilder B(Context); + MemoryEffects ME = MemoryEffects::unknown(); for (unsigned i = 2, e = Record.size(); i != e; ++i) { if (Record[i] == 0) { // Enum attribute Attribute::AttrKind Kind; - if (Error Err = parseAttrKind(Record[++i], &Kind)) + uint64_t EncodedKind = Record[++i]; + if (Idx == AttributeList::FunctionIndex && + upgradeOldMemoryAttribute(ME, EncodedKind)) + continue; + + if (Error Err = parseAttrKind(EncodedKind, &Kind)) return Err; // Upgrade old-style byval attribute to one with a type, even if it's @@ -2159,6 +2220,9 @@ } } + if (ME != MemoryEffects::unknown()) + B.addMemoryAttr(ME); + UpgradeAttributes(B); MAttributeGroups[GrpID] = AttributeList::get(Context, Idx, B); break; Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -620,8 +620,6 @@ return bitc::ATTR_KIND_ALLOC_SIZE; case Attribute::AlwaysInline: return bitc::ATTR_KIND_ALWAYS_INLINE; - case Attribute::ArgMemOnly: - return bitc::ATTR_KIND_ARGMEMONLY; case Attribute::Builtin: return bitc::ATTR_KIND_BUILTIN; case Attribute::ByVal: @@ -640,10 +638,6 @@ return bitc::ATTR_KIND_HOT; case Attribute::ElementType: return bitc::ATTR_KIND_ELEMENTTYPE; - case Attribute::InaccessibleMemOnly: - return bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY; - case Attribute::InaccessibleMemOrArgMemOnly: - return bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY; case Attribute::InlineHint: return bitc::ATTR_KIND_INLINE_HINT; case Attribute::InReg: Index: llvm/lib/CodeGen/MachineVerifier.cpp =================================================================== --- llvm/lib/CodeGen/MachineVerifier.cpp +++ llvm/lib/CodeGen/MachineVerifier.cpp @@ -61,6 +61,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/ModRef.h" #include "llvm/InitializePasses.h" #include "llvm/MC/LaneBitmask.h" #include "llvm/MC/MCAsmInfo.h" @@ -1474,10 +1475,9 @@ bool NoSideEffects = MI->getOpcode() == TargetOpcode::G_INTRINSIC; unsigned IntrID = IntrIDOp.getIntrinsicID(); if (IntrID != 0 && IntrID < Intrinsic::num_intrinsics) { - AttributeList Attrs - = Intrinsic::getAttributes(MF->getFunction().getContext(), - static_cast(IntrID)); - bool DeclHasSideEffects = !Attrs.hasFnAttr(Attribute::ReadNone); + AttributeList Attrs = Intrinsic::getAttributes( + MF->getFunction().getContext(), static_cast(IntrID)); + bool DeclHasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory(); if (NoSideEffects && DeclHasSideEffects) { report("G_INTRINSIC used with intrinsic that accesses memory", MI); break; Index: llvm/lib/IR/AttributeImpl.h =================================================================== --- llvm/lib/IR/AttributeImpl.h +++ llvm/lib/IR/AttributeImpl.h @@ -263,6 +263,7 @@ Optional getVScaleRangeMax() const; UWTableKind getUWTableKind() const; AllocFnKind getAllocKind() const; + MemoryEffects getMemoryEffects() const; std::string getAsString(bool InAttrGrp) const; Type *getAttributeType(Attribute::AttrKind Kind) const; Index: llvm/lib/IR/Attributes.cpp =================================================================== --- llvm/lib/IR/Attributes.cpp +++ llvm/lib/IR/Attributes.cpp @@ -211,6 +211,11 @@ return get(Context, UWTable, uint64_t(Kind)); } +Attribute Attribute::getWithMemoryEffects(LLVMContext &Context, + MemoryEffects ME) { + return get(Context, Memory, ME.toIntValue()); +} + Attribute Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const Optional &NumElemsArg) { @@ -831,6 +836,10 @@ return SetNode ? SetNode->getAllocKind() : AllocFnKind::Unknown; } +MemoryEffects AttributeSet::getMemoryEffects() const { + return SetNode ? SetNode->getMemoryEffects() : MemoryEffects::unknown(); +} + std::string AttributeSet::getAsString(bool InAttrGrp) const { return SetNode ? SetNode->getAsString(InAttrGrp) : ""; } @@ -1009,6 +1018,12 @@ return AllocFnKind::Unknown; } +MemoryEffects AttributeSetNode::getMemoryEffects() const { + if (auto A = findEnumAttribute(Attribute::Memory)) + return A->getMemoryEffects(); + return MemoryEffects::unknown(); +} + std::string AttributeSetNode::getAsString(bool InAttrGrp) const { std::string Str; for (iterator I = begin(), E = end(); I != E; ++I) { @@ -1561,6 +1576,10 @@ return getFnAttrs().getAllocKind(); } +MemoryEffects AttributeList::getMemoryEffects() const { + return getFnAttrs().getMemoryEffects(); +} + std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const { return getAttributes(Index).getAsString(InAttrGrp); } Index: llvm/lib/IR/Function.cpp =================================================================== --- llvm/lib/IR/Function.cpp +++ llvm/lib/IR/Function.cpp @@ -51,6 +51,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/ModRef.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/IR/SymbolTableListTraits.h" @@ -727,6 +728,65 @@ setPrologueData(Src->getPrologueData()); } +MemoryEffects Function::getMemoryEffects() const { + return getAttributes().getMemoryEffects(); +} +void Function::setMemoryEffects(MemoryEffects ME) { + addFnAttr(Attribute::getWithMemoryEffects(getContext(), ME)); +} + +/// Determine if the function does not access memory. +bool Function::doesNotAccessMemory() const { + return getMemoryEffects().doesNotAccessMemory(); +} +void Function::setDoesNotAccessMemory() { + setMemoryEffects(MemoryEffects::none()); +} + +/// Determine if the function does not access or only reads memory. +bool Function::onlyReadsMemory() const { + return getMemoryEffects().onlyReadsMemory(); +} +void Function::setOnlyReadsMemory() { + setMemoryEffects(getMemoryEffects() & MemoryEffects::readOnly()); +} + +/// Determine if the function does not access or only writes memory. +bool Function::onlyWritesMemory() const { + return getMemoryEffects().onlyWritesMemory(); +} +void Function::setOnlyWritesMemory() { + setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly()); +} + +/// Determine if the call can access memmory only using pointers based +/// on its arguments. +bool Function::onlyAccessesArgMemory() const { + return getMemoryEffects().onlyAccessesArgPointees(); +} +void Function::setOnlyAccessesArgMemory() { + setMemoryEffects(getMemoryEffects() & MemoryEffects::argMemOnly()); +} + +/// Determine if the function may only access memory that is +/// inaccessible from the IR. +bool Function::onlyAccessesInaccessibleMemory() const { + return getMemoryEffects().onlyAccessesInaccessibleMem(); +} +void Function::setOnlyAccessesInaccessibleMemory() { + setMemoryEffects(getMemoryEffects() & MemoryEffects::inaccessibleMemOnly()); +} + +/// Determine if the function may only access memory that is +/// either inaccessible from the IR or pointed to by its arguments. +bool Function::onlyAccessesInaccessibleMemOrArgMem() const { + return getMemoryEffects().onlyAccessesInaccessibleOrArgMem(); +} +void Function::setOnlyAccessesInaccessibleMemOrArgMem() { + setMemoryEffects(getMemoryEffects() & + MemoryEffects::inaccessibleOrArgMemOnly()); +} + /// Table of string intrinsic names indexed by enum value. static const char * const IntrinsicNameTable[] = { "not_intrinsic", Index: llvm/lib/IR/Instructions.cpp =================================================================== --- llvm/lib/IR/Instructions.cpp +++ llvm/lib/IR/Instructions.cpp @@ -30,6 +30,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/ModRef.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" @@ -375,10 +376,12 @@ template Attribute CallBase::getFnAttrOnCalledFunction(AK Kind) const { - // Operand bundles override attributes on the called function, but don't - // override attributes directly present on the call instruction. - if (isFnAttrDisallowedByOpBundle(Kind)) - return Attribute(); + if constexpr (std::is_same_v) { + // getMemoryEffects() correctly combines memory effects from the call-site, + // operand bundles and function. + assert(Kind != Attribute::Memory && "Use getMemoryEffects() instead"); + } + Value *V = getCalledOperand(); if (auto *CE = dyn_cast(V)) if (CE->getOpcode() == BitCast) @@ -518,6 +521,77 @@ getIntrinsicID() != Intrinsic::assume; } +MemoryEffects CallBase::getMemoryEffects() const { + MemoryEffects ME = getAttributes().getMemoryEffects(); + if (auto *Fn = dyn_cast(getCalledOperand())) { + MemoryEffects FnME = Fn->getMemoryEffects(); + if (hasOperandBundles()) { + // TODO: Add a method to get memory effects for operand bundles instead. + if (hasReadingOperandBundles()) + FnME |= MemoryEffects::readOnly(); + if (hasClobberingOperandBundles()) + FnME |= MemoryEffects::writeOnly(); + } + ME &= FnME; + } + return ME; +} +void CallBase::setMemoryEffects(MemoryEffects ME) { + addFnAttr(Attribute::getWithMemoryEffects(getContext(), ME)); +} + +/// Determine if the function does not access memory. +bool CallBase::doesNotAccessMemory() const { + return getMemoryEffects().doesNotAccessMemory(); +} +void CallBase::setDoesNotAccessMemory() { + setMemoryEffects(MemoryEffects::none()); +} + +/// Determine if the function does not access or only reads memory. +bool CallBase::onlyReadsMemory() const { + return getMemoryEffects().onlyReadsMemory(); +} +void CallBase::setOnlyReadsMemory() { + setMemoryEffects(getMemoryEffects() & MemoryEffects::readOnly()); +} + +/// Determine if the function does not access or only writes memory. +bool CallBase::onlyWritesMemory() const { + return getMemoryEffects().onlyWritesMemory(); +} +void CallBase::setOnlyWritesMemory() { + setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly()); +} + +/// Determine if the call can access memmory only using pointers based +/// on its arguments. +bool CallBase::onlyAccessesArgMemory() const { + return getMemoryEffects().onlyAccessesArgPointees(); +} +void CallBase::setOnlyAccessesArgMemory() { + setMemoryEffects(getMemoryEffects() & MemoryEffects::argMemOnly()); +} + +/// Determine if the function may only access memory that is +/// inaccessible from the IR. +bool CallBase::onlyAccessesInaccessibleMemory() const { + return getMemoryEffects().onlyAccessesInaccessibleMem(); +} +void CallBase::setOnlyAccessesInaccessibleMemory() { + setMemoryEffects(getMemoryEffects() & MemoryEffects::inaccessibleMemOnly()); +} + +/// Determine if the function may only access memory that is +/// either inaccessible from the IR or pointed to by its arguments. +bool CallBase::onlyAccessesInaccessibleMemOrArgMem() const { + return getMemoryEffects().onlyAccessesInaccessibleOrArgMem(); +} +void CallBase::setOnlyAccessesInaccessibleMemOrArgMem() { + setMemoryEffects(getMemoryEffects() & + MemoryEffects::inaccessibleOrArgMemOnly()); +} + //===----------------------------------------------------------------------===// // CallInst Implementation //===----------------------------------------------------------------------===// Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -2021,28 +2021,6 @@ "' does not apply to functions!", V); - Check(!(Attrs.hasFnAttr(Attribute::ReadNone) && - Attrs.hasFnAttr(Attribute::ReadOnly)), - "Attributes 'readnone and readonly' are incompatible!", V); - - Check(!(Attrs.hasFnAttr(Attribute::ReadNone) && - Attrs.hasFnAttr(Attribute::WriteOnly)), - "Attributes 'readnone and writeonly' are incompatible!", V); - - Check(!(Attrs.hasFnAttr(Attribute::ReadOnly) && - Attrs.hasFnAttr(Attribute::WriteOnly)), - "Attributes 'readonly and writeonly' are incompatible!", V); - - Check(!(Attrs.hasFnAttr(Attribute::ReadNone) && - Attrs.hasFnAttr(Attribute::InaccessibleMemOrArgMemOnly)), - "Attributes 'readnone and inaccessiblemem_or_argmemonly' are " - "incompatible!", - V); - - Check(!(Attrs.hasFnAttr(Attribute::ReadNone) && - Attrs.hasFnAttr(Attribute::InaccessibleMemOnly)), - "Attributes 'readnone and inaccessiblememonly' are incompatible!", V); - Check(!(Attrs.hasFnAttr(Attribute::NoInline) && Attrs.hasFnAttr(Attribute::AlwaysInline)), "Attributes 'noinline and alwaysinline' are incompatible!", V); Index: llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp +++ llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/ModRef.h" #include "llvm/IR/Module.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/CommandLine.h" @@ -992,7 +993,8 @@ } else { AttributeList Attr; LLVMContext &Ctx = M->getContext(); - Attr = Attr.addFnAttribute(Ctx, Attribute::ReadOnly); + Attr = Attr.addFnAttribute( + Ctx, Attribute::getWithMemoryEffects(Ctx, MemoryEffects::readOnly())); Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind); C = M->getOrInsertFunction(FuncName, FuncTy, Attr); } Index: llvm/lib/Target/AMDGPU/SIISelLowering.cpp =================================================================== --- llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -33,6 +33,7 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsR600.h" +#include "llvm/IR/ModRef.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/KnownBits.h" @@ -958,7 +959,8 @@ AMDGPU::lookupRsrcIntrinsic(IntrID)) { AttributeList Attr = Intrinsic::getAttributes(CI.getContext(), (Intrinsic::ID)IntrID); - if (Attr.hasFnAttr(Attribute::ReadNone)) + MemoryEffects ME = Attr.getMemoryEffects(); + if (ME.doesNotAccessMemory()) return false; SIMachineFunctionInfo *MFI = MF.getInfo(); @@ -974,7 +976,7 @@ } Info.flags |= MachineMemOperand::MODereferenceable; - if (Attr.hasFnAttr(Attribute::ReadOnly)) { + if (ME.onlyReadsMemory()) { unsigned DMaskLanes = 4; if (RsrcIntr->IsImage) { @@ -998,7 +1000,7 @@ // FIXME: What does alignment mean for an image? Info.opc = ISD::INTRINSIC_W_CHAIN; Info.flags |= MachineMemOperand::MOLoad; - } else if (Attr.hasFnAttr(Attribute::WriteOnly)) { + } else if (ME.onlyWritesMemory()) { Info.opc = ISD::INTRINSIC_VOID; Type *DataTy = CI.getArgOperand(0)->getType(); Index: llvm/lib/Target/Mips/Mips16HardFloat.cpp =================================================================== --- llvm/lib/Target/Mips/Mips16HardFloat.cpp +++ llvm/lib/Target/Mips/Mips16HardFloat.cpp @@ -12,6 +12,7 @@ #include "MipsTargetMachine.h" #include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/IR/ModRef.h" #include "llvm/IR/Module.h" #include "llvm/IR/Value.h" #include "llvm/Support/Debug.h" @@ -409,7 +410,8 @@ // functions will take place. // A = A.addFnAttribute(C, "__Mips16RetHelper"); - A = A.addFnAttribute(C, Attribute::ReadNone); + A = A.addFnAttribute( + C, Attribute::getWithMemoryEffects(C, MemoryEffects::none())); A = A.addFnAttribute(C, Attribute::NoInline); FunctionCallee F = (M->getOrInsertFunction(Name, A, MyVoid, T)); CallInst::Create(F, Params, "", &I); Index: llvm/lib/Transforms/IPO/AttributorAttributes.cpp =================================================================== --- llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -7287,13 +7287,28 @@ /// See AbstractAttribute::manifest(...). ChangeStatus manifest(Attributor &A) override { + // TODO: It would be better to merge this with AAMemoryLocation, so that + // we could determine read/write per location. This would also have the + // benefit of only one place trying to manifest the memory attribute. Function &F = cast(getAnchorValue()); - if (isAssumedReadNone()) { - F.removeFnAttr(Attribute::ArgMemOnly); - F.removeFnAttr(Attribute::InaccessibleMemOnly); - F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly); - } - return AAMemoryBehaviorImpl::manifest(A); + MemoryEffects ME = MemoryEffects::unknown(); + if (isAssumedReadNone()) + ME = MemoryEffects::none(); + else if (isAssumedReadOnly()) + ME = MemoryEffects::readOnly(); + else if (isAssumedWriteOnly()) + ME = MemoryEffects::writeOnly(); + + // Intersect with existing memory attribute, as we currently deduce the + // location and modref portion separately. + MemoryEffects ExistingME = F.getMemoryEffects(); + ME &= ExistingME; + if (ME == ExistingME) + return ChangeStatus::UNCHANGED; + + return IRAttributeManifest::manifestAttrs( + A, getIRPosition(), Attribute::getWithMemoryEffects(F.getContext(), ME), + /*ForceReplace*/ true); } /// See AbstractAttribute::trackStatistics() @@ -7333,6 +7348,31 @@ return clampStateAndIndicateChange(getState(), FnAA.getState()); } + /// See AbstractAttribute::manifest(...). + ChangeStatus manifest(Attributor &A) override { + // TODO: Deduplicate this with AAMemoryBehaviorFunction. + CallBase &CB = cast(getAnchorValue()); + MemoryEffects ME = MemoryEffects::unknown(); + if (isAssumedReadNone()) + ME = MemoryEffects::none(); + else if (isAssumedReadOnly()) + ME = MemoryEffects::readOnly(); + else if (isAssumedWriteOnly()) + ME = MemoryEffects::writeOnly(); + + // Intersect with existing memory attribute, as we currently deduce the + // location and modref portion separately. + MemoryEffects ExistingME = CB.getMemoryEffects(); + ME &= ExistingME; + if (ME == ExistingME) + return ChangeStatus::UNCHANGED; + + return IRAttributeManifest::manifestAttrs( + A, getIRPosition(), + Attribute::getWithMemoryEffects(CB.getContext(), ME), + /*ForceReplace*/ true); + } + /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { if (isAssumedReadNone()) @@ -7602,36 +7642,54 @@ // unlikely this will cause real performance problems. If we are deriving // attributes for the anchor function we even remove the attribute in // addition to ignoring it. + // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM / + // MemoryEffects::Other as a possible location. bool UseArgMemOnly = true; Function *AnchorFn = IRP.getAnchorScope(); if (AnchorFn && A.isRunOn(*AnchorFn)) UseArgMemOnly = !AnchorFn->hasLocalLinkage(); SmallVector Attrs; - IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions); + IRP.getAttrs({Attribute::Memory}, Attrs, IgnoreSubsumingPositions); for (const Attribute &Attr : Attrs) { - switch (Attr.getKindAsEnum()) { - case Attribute::ReadNone: + // TODO: We can map MemoryEffects to Attributor locations more precisely. + MemoryEffects ME = Attr.getMemoryEffects(); + if (ME.doesNotAccessMemory()) { State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM); - break; - case Attribute::InaccessibleMemOnly: + continue; + } + if (ME.onlyAccessesInaccessibleMem()) { State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true)); - break; - case Attribute::ArgMemOnly: + continue; + } + if (ME.onlyAccessesArgPointees()) { if (UseArgMemOnly) State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true)); - else - IRP.removeAttrs({Attribute::ArgMemOnly}); - break; - case Attribute::InaccessibleMemOrArgMemOnly: + else { + // Remove location information, only keep read/write info. + ME = MemoryEffects(ME.getModRef()); + IRAttributeManifest::manifestAttrs( + A, IRP, + Attribute::getWithMemoryEffects(IRP.getAnchorValue().getContext(), + ME), + /*ForceReplace*/ true); + } + continue; + } + if (ME.onlyAccessesInaccessibleOrArgMem()) { if (UseArgMemOnly) State.addKnownBits(inverseLocation( NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true)); - else - IRP.removeAttrs({Attribute::InaccessibleMemOrArgMemOnly}); - break; - default: - llvm_unreachable("Unexpected attribute!"); + else { + // Remove location information, only keep read/write info. + ME = MemoryEffects(ME.getModRef()); + IRAttributeManifest::manifestAttrs( + A, IRP, + Attribute::getWithMemoryEffects(IRP.getAnchorValue().getContext(), + ME), + /*ForceReplace*/ true); + } + continue; } } } @@ -7639,41 +7697,53 @@ /// See AbstractAttribute::getDeducedAttributes(...). void getDeducedAttributes(LLVMContext &Ctx, SmallVectorImpl &Attrs) const override { + // TODO: We can map Attributor locations to MemoryEffects more precisely. assert(Attrs.size() == 0); - if (isAssumedReadNone()) { - Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone)); - } else if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) { - if (isAssumedInaccessibleMemOnly()) - Attrs.push_back(Attribute::get(Ctx, Attribute::InaccessibleMemOnly)); + if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) { + if (isAssumedReadNone()) + Attrs.push_back( + Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none())); + else if (isAssumedInaccessibleMemOnly()) + Attrs.push_back(Attribute::getWithMemoryEffects( + Ctx, MemoryEffects::inaccessibleMemOnly())); else if (isAssumedArgMemOnly()) - Attrs.push_back(Attribute::get(Ctx, Attribute::ArgMemOnly)); - else if (isAssumedInaccessibleOrArgMemOnly()) Attrs.push_back( - Attribute::get(Ctx, Attribute::InaccessibleMemOrArgMemOnly)); + Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly())); + else if (isAssumedInaccessibleOrArgMemOnly()) + Attrs.push_back(Attribute::getWithMemoryEffects( + Ctx, MemoryEffects::inaccessibleOrArgMemOnly())); } assert(Attrs.size() <= 1); } /// See AbstractAttribute::manifest(...). ChangeStatus manifest(Attributor &A) override { + // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could + // provide per-location modref information here. const IRPosition &IRP = getIRPosition(); - // Check if we would improve the existing attributes first. - SmallVector DeducedAttrs; + SmallVector DeducedAttrs; getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs); - if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) { - return IRP.hasAttr(Attr.getKindAsEnum(), - /* IgnoreSubsumingPositions */ true); - })) + if (DeducedAttrs.size() != 1) return ChangeStatus::UNCHANGED; + MemoryEffects ME = DeducedAttrs[0].getMemoryEffects(); + + // Intersect with existing memory attribute, as we currently deduce the + // location and modref portion separately. + SmallVector ExistingAttrs; + IRP.getAttrs({Attribute::Memory}, ExistingAttrs, + /* IgnoreSubsumingPositions */ true); + if (ExistingAttrs.size() == 1) { + MemoryEffects ExistingME = ExistingAttrs[0].getMemoryEffects(); + ME &= ExistingME; + if (ME == ExistingME) + return ChangeStatus::UNCHANGED; + } - // Clear existing attributes. - IRP.removeAttrs(AttrKinds); - if (isAssumedReadNone()) - IRP.removeAttrs(AAMemoryBehaviorImpl::AttrKinds); - - // Use the generic manifest method. - return IRAttribute::manifest(A); + return IRAttributeManifest::manifestAttrs( + A, IRP, + Attribute::getWithMemoryEffects(IRP.getAnchorValue().getContext(), ME), + /*ForceReplace*/ true); } /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...). @@ -7796,15 +7866,8 @@ /// Used to allocate access sets. BumpPtrAllocator &Allocator; - - /// The set of IR attributes AAMemoryLocation deals with. - static const Attribute::AttrKind AttrKinds[4]; }; -const Attribute::AttrKind AAMemoryLocationImpl::AttrKinds[] = { - Attribute::ReadNone, Attribute::InaccessibleMemOnly, Attribute::ArgMemOnly, - Attribute::InaccessibleMemOrArgMemOnly}; - void AAMemoryLocationImpl::categorizePtrValue( Attributor &A, const Instruction &I, const Value &Ptr, AAMemoryLocation::StateType &State, bool &Changed) { Index: llvm/lib/Transforms/IPO/FunctionAttrs.cpp =================================================================== --- llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -69,10 +69,7 @@ #define DEBUG_TYPE "function-attrs" -STATISTIC(NumArgMemOnly, "Number of functions marked argmemonly"); -STATISTIC(NumReadNone, "Number of functions marked readnone"); -STATISTIC(NumReadOnly, "Number of functions marked readonly"); -STATISTIC(NumWriteOnly, "Number of functions marked writeonly"); +STATISTIC(NumMemoryAttr, "Number of functions with improved memory attribute"); STATISTIC(NumNoCapture, "Number of arguments marked nocapture"); STATISTIC(NumReturned, "Number of arguments marked returned"); STATISTIC(NumReadNoneArg, "Number of arguments marked readnone"); @@ -253,79 +250,14 @@ return; } - ModRefInfo MR = ME.getModRef(); - for (Function *F : SCCNodes) { - if (F->doesNotAccessMemory()) - // Already perfect! - continue; - - if (ME.doesNotAccessMemory()) { - // For readnone, remove all other memory attributes. - AttributeMask AttrsToRemove; - AttrsToRemove.addAttribute(Attribute::ReadOnly); - AttrsToRemove.addAttribute(Attribute::WriteOnly); - AttrsToRemove.addAttribute(Attribute::ArgMemOnly); - AttrsToRemove.addAttribute(Attribute::InaccessibleMemOnly); - AttrsToRemove.addAttribute(Attribute::InaccessibleMemOrArgMemOnly); - - ++NumReadNone; - F->removeFnAttrs(AttrsToRemove); - F->addFnAttr(Attribute::ReadNone); - Changed.insert(F); - continue; - } - - // Add argmemonly, inaccessiblememonly, or inaccessible_or_argmemonly - // attributes if possible. - AttributeMask AttrsToRemove; - AttrsToRemove.addAttribute(Attribute::ArgMemOnly); - AttrsToRemove.addAttribute(Attribute::InaccessibleMemOnly); - AttrsToRemove.addAttribute(Attribute::InaccessibleMemOrArgMemOnly); - if (ME.onlyAccessesArgPointees()) { - if (!F->onlyAccessesArgMemory()) { - NumArgMemOnly++; - F->removeFnAttrs(AttrsToRemove); - F->addFnAttr(Attribute::ArgMemOnly); - Changed.insert(F); - } - } else if (ME.onlyAccessesInaccessibleMem()) { - if (!F->onlyAccessesInaccessibleMemory()) { - F->removeFnAttrs(AttrsToRemove); - F->addFnAttr(Attribute::InaccessibleMemOnly); - Changed.insert(F); - } - } else if (ME.onlyAccessesInaccessibleOrArgMem() && - !F->onlyAccessesInaccessibleMemOrArgMem()) { - F->removeFnAttrs(AttrsToRemove); - F->addFnAttr(Attribute::InaccessibleMemOrArgMemOnly); + MemoryEffects OldME = F->getMemoryEffects(); + MemoryEffects NewME = ME & OldME; + if (NewME != OldME) { + ++NumMemoryAttr; + F->setMemoryEffects(NewME); Changed.insert(F); } - - // The SCC contains functions both writing and reading from memory. We - // cannot add readonly or writeonline attributes. - if (MR == ModRefInfo::ModRef) - continue; - - if (F->onlyReadsMemory() && MR == ModRefInfo::Ref) - continue; - - if (F->onlyWritesMemory() && MR == ModRefInfo::Mod) - continue; - - Changed.insert(F); - - // Add in the new attribute. - if (MR == ModRefInfo::Mod) { - ++NumWriteOnly; - F->removeFnAttr(Attribute::ReadOnly); - F->addFnAttr(Attribute::WriteOnly); - } else { - ++NumReadOnly; - assert(MR == ModRefInfo::Ref); - F->removeFnAttr(Attribute::WriteOnly); - F->addFnAttr(Attribute::ReadOnly); - } } } Index: llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -1234,19 +1234,22 @@ // Initialize DataFlowSanitizer runtime functions and declare them in the module void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) { + LLVMContext &C = M.getContext(); { AttributeList AL; - AL = AL.addFnAttribute(M.getContext(), Attribute::NoUnwind); - AL = AL.addFnAttribute(M.getContext(), Attribute::ReadOnly); - AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt); + AL = AL.addFnAttribute(C, Attribute::NoUnwind); + AL = AL.addFnAttribute( + C, Attribute::getWithMemoryEffects(C, MemoryEffects::readOnly())); + AL = AL.addRetAttribute(C, Attribute::ZExt); DFSanUnionLoadFn = Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy, AL); } { AttributeList AL; - AL = AL.addFnAttribute(M.getContext(), Attribute::NoUnwind); - AL = AL.addFnAttribute(M.getContext(), Attribute::ReadOnly); - AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt); + AL = AL.addFnAttribute(C, Attribute::NoUnwind); + AL = AL.addFnAttribute( + C, Attribute::getWithMemoryEffects(C, MemoryEffects::readOnly())); + AL = AL.addRetAttribute(C, Attribute::ZExt); DFSanLoadLabelAndOriginFn = Mod->getOrInsertFunction( "__dfsan_load_label_and_origin", DFSanLoadLabelAndOriginFnTy, AL); } @@ -1470,8 +1473,7 @@ } } - ReadOnlyNoneAttrs.addAttribute(Attribute::ReadOnly) - .addAttribute(Attribute::ReadNone); + ReadOnlyNoneAttrs.addAttribute(Attribute::Memory); // First, change the ABI of every function in the module. ABI-listed // functions keep their original ABI and get a wrapper function. Index: llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -4074,12 +4074,9 @@ // will become a non-readonly function after it is instrumented by us. To // prevent this code from being optimized out, mark that function // non-readonly in advance. + // TODO: We can likely do better than dropping memory() completely here. AttributeMask B; - B.addAttribute(Attribute::ReadOnly) - .addAttribute(Attribute::ReadNone) - .addAttribute(Attribute::WriteOnly) - .addAttribute(Attribute::ArgMemOnly) - .addAttribute(Attribute::Speculatable); + B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable); Call->removeFnAttrs(B); if (Function *Func = Call->getCalledFunction()) { @@ -5769,13 +5766,9 @@ MemorySanitizerVisitor Visitor(F, *this, TLI); - // Clear out readonly/readnone attributes. + // Clear out memory attributes. AttributeMask B; - B.addAttribute(Attribute::ReadOnly) - .addAttribute(Attribute::ReadNone) - .addAttribute(Attribute::WriteOnly) - .addAttribute(Attribute::ArgMemOnly) - .addAttribute(Attribute::Speculatable); + B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable); F.removeFnAttrs(B); return Visitor.runOnFunction(); Index: llvm/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp +++ llvm/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp @@ -80,10 +80,9 @@ Instruction *LibCall = Call->clone(); Builder.Insert(LibCall); - // Add attribute "readnone" so that backend can use a native sqrt instruction - // for this call. - Call->removeFnAttr(Attribute::WriteOnly); - Call->addFnAttr(Attribute::ReadNone); + // Add memory(none) attribute, so that the backend can use a native sqrt + // instruction for this call. + Call->setDoesNotAccessMemory(); // Insert a FP compare instruction and use it as the CurrBB branch condition. Builder.SetInsertPoint(CurrBBTerm); Index: llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp =================================================================== --- llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1430,10 +1430,7 @@ // machine model for purposes of optimization. We have to strip these on // both function declarations and call sites. static constexpr Attribute::AttrKind FnAttrsToStrip[] = - {Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly, - Attribute::ArgMemOnly, Attribute::InaccessibleMemOnly, - Attribute::InaccessibleMemOrArgMemOnly, - Attribute::NoSync, Attribute::NoFree}; + {Attribute::Memory, Attribute::NoSync, Attribute::NoFree}; // Create new attribute set containing only attributes which can be transferred // from original call to the safepoint. Index: llvm/lib/Transforms/Scalar/SCCP.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SCCP.cpp +++ llvm/lib/Transforms/Scalar/SCCP.cpp @@ -590,21 +590,28 @@ } } - // If we replaced an argument, the argmemonly and - // inaccessiblemem_or_argmemonly attributes do not hold any longer. Remove - // them from both the function and callsites. + // If we replaced an argument, we may now also access a global (currently + // classified as "other" memory). Update memory attribute to reflect this. if (ReplacedPointerArg) { - AttributeMask AttributesToRemove; - AttributesToRemove.addAttribute(Attribute::ArgMemOnly); - AttributesToRemove.addAttribute(Attribute::InaccessibleMemOrArgMemOnly); - F.removeFnAttrs(AttributesToRemove); - + auto UpdateAttrs = [&](AttributeList AL) { + MemoryEffects ME = AL.getMemoryEffects(); + if (ME == MemoryEffects::unknown()) + return AL; + + ME |= MemoryEffects(MemoryEffects::Other, + ME.getModRef(MemoryEffects::ArgMem)); + return AL.addFnAttribute( + F.getContext(), + Attribute::getWithMemoryEffects(F.getContext(), ME)); + }; + + F.setAttributes(UpdateAttrs(F.getAttributes())); for (User *U : F.users()) { auto *CB = dyn_cast(U); if (!CB || CB->getCalledFunction() != &F) continue; - CB->removeFnAttrs(AttributesToRemove); + CB->setAttributes(UpdateAttrs(CB->getAttributes())); } } MadeChanges |= ReplacedPointerArg; Index: llvm/lib/Transforms/Utils/BuildLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -75,11 +75,6 @@ static bool setOnlyWritesMemory(Function &F) { if (F.onlyWritesMemory()) // writeonly or readnone return false; - // Turn readonly and writeonly into readnone. - if (F.hasFnAttribute(Attribute::ReadOnly)) { - F.removeFnAttr(Attribute::ReadOnly); - return setDoesNotAccessMemory(F); - } ++NumWriteOnly; F.setOnlyWritesMemory(); return true; Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp =================================================================== --- llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -904,24 +904,18 @@ // Those attributes cannot be propagated safely. Explicitly list them // here so we get a warning if new attributes are added. case Attribute::AllocSize: - case Attribute::ArgMemOnly: case Attribute::Builtin: case Attribute::Convergent: - case Attribute::InaccessibleMemOnly: - case Attribute::InaccessibleMemOrArgMemOnly: case Attribute::JumpTable: case Attribute::Naked: case Attribute::NoBuiltin: case Attribute::NoMerge: case Attribute::NoReturn: case Attribute::NoSync: - case Attribute::ReadNone: - case Attribute::ReadOnly: case Attribute::ReturnsTwice: case Attribute::Speculatable: case Attribute::StackAlignment: case Attribute::WillReturn: - case Attribute::WriteOnly: case Attribute::AllocKind: case Attribute::PresplitCoroutine: case Attribute::Memory: @@ -984,6 +978,8 @@ case Attribute::NoUndef: case Attribute::NonNull: case Attribute::Preallocated: + case Attribute::ReadNone: + case Attribute::ReadOnly: case Attribute::Returned: case Attribute::SExt: case Attribute::StructRet: @@ -993,6 +989,7 @@ case Attribute::ZExt: case Attribute::ImmArg: case Attribute::ByRef: + case Attribute::WriteOnly: // These are not really attributes. case Attribute::None: case Attribute::EndAttrKinds: Index: llvm/test/Analysis/BasicAA/cs-cs.ll =================================================================== --- llvm/test/Analysis/BasicAA/cs-cs.ll +++ llvm/test/Analysis/BasicAA/cs-cs.ll @@ -429,19 +429,19 @@ } -; CHECK: attributes #0 = { argmemonly nocallback nofree nounwind willreturn writeonly } -; CHECK-NEXT: attributes #1 = { argmemonly nocallback nofree nounwind willreturn } -; CHECK-NEXT: attributes #2 = { argmemonly nosync nounwind willreturn } -; CHECK-NEXT: attributes #3 = { noinline nounwind readonly } -; CHECK-NEXT: attributes #4 = { noinline nounwind writeonly } +; CHECK: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } +; CHECK-NEXT: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +; CHECK-NEXT: attributes #2 = { nosync nounwind willreturn memory(argmem: readwrite) } +; CHECK-NEXT: attributes #3 = { noinline nounwind memory(read) } +; CHECK-NEXT: attributes #4 = { noinline nounwind memory(write) } ; CHECK-NEXT: attributes #5 = { nounwind ssp } -; CHECK-NEXT: attributes #6 = { inaccessiblememonly nounwind } -; CHECK-NEXT: attributes #7 = { inaccessiblemem_or_argmemonly nounwind } -; CHECK-NEXT: attributes #8 = { argmemonly nounwind } -; CHECK-NEXT: attributes #9 = { readonly } -; CHECK-NEXT: attributes #10 = { inaccessiblememonly } -; CHECK-NEXT: attributes #11 = { inaccessiblemem_or_argmemonly } -; CHECK-NEXT: attributes #12 = { argmemonly } +; CHECK-NEXT: attributes #6 = { nounwind memory(inaccessiblemem: readwrite) } +; CHECK-NEXT: attributes #7 = { nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK-NEXT: attributes #8 = { nounwind memory(argmem: readwrite) } +; CHECK-NEXT: attributes #9 = { memory(read) } +; CHECK-NEXT: attributes #10 = { memory(inaccessiblemem: readwrite) } +; CHECK-NEXT: attributes #11 = { memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK-NEXT: attributes #12 = { memory(argmem: readwrite) } attributes #0 = { argmemonly nounwind } attributes #1 = { noinline nounwind readonly } Index: llvm/test/Analysis/BasicAA/intrinsics.ll =================================================================== --- llvm/test/Analysis/BasicAA/intrinsics.ll +++ llvm/test/Analysis/BasicAA/intrinsics.ll @@ -22,6 +22,6 @@ declare <8 x i16> @llvm.masked.load.v8i16.p0v8i16(<8 x i16>*, i32, <8 x i1>, <8 x i16>) nounwind readonly declare void @llvm.masked.store.v8i16.p0v8i16(<8 x i16>, <8 x i16>*, i32, <8 x i1>) nounwind -; CHECK: attributes #0 = { argmemonly nocallback nofree nosync nounwind readonly willreturn } -; CHECK: attributes #1 = { argmemonly nocallback nofree nosync nounwind willreturn writeonly } +; CHECK: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) } +; CHECK: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: write) } ; CHECK: attributes [[ATTR]] = { nounwind } Index: llvm/test/Analysis/BasicAA/pure-const-dce.ll =================================================================== --- llvm/test/Analysis/BasicAA/pure-const-dce.ll +++ llvm/test/Analysis/BasicAA/pure-const-dce.ll @@ -50,5 +50,5 @@ declare i32 @TestNone(i32) -; CHECK: attributes [[READNONE]] = { readnone } -; CHECK: attributes [[READONLY]] = { readonly } +; CHECK: attributes [[READNONE]] = { memory(none) } +; CHECK: attributes [[READONLY]] = { memory(read) } Index: llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll =================================================================== --- llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll +++ llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll @@ -72,14 +72,14 @@ declare void @callee(i32* %p) nounwind declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1) nounwind -; CHECK: attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #1 = { argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly } -; CHECK: attributes #2 = { nofree nosync nounwind readnone } +; CHECK: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } +; CHECK: attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CHECK: attributes #2 = { nofree nosync nounwind memory(none) } ; CHECK: attributes #3 = { nounwind } -; CHECK: attributes #4 = { mustprogress nofree nosync nounwind readnone willreturn } -; CHECK: attributes #5 = { argmemonly mustprogress nofree nosync nounwind willreturn } -; CHECK: attributes #6 = { argmemonly mustprogress nofree norecurse nosync nounwind willreturn } -; CHECK: attributes #7 = { argmemonly nocallback nofree nounwind willreturn } +; CHECK: attributes #4 = { mustprogress nofree nosync nounwind willreturn memory(none) } +; CHECK: attributes #5 = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CHECK: attributes #6 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CHECK: attributes #7 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } ; Root note. !0 = !{ } Index: llvm/test/Analysis/TypeBasedAliasAnalysis/intrinsics.ll =================================================================== --- llvm/test/Analysis/TypeBasedAliasAnalysis/intrinsics.ll +++ llvm/test/Analysis/TypeBasedAliasAnalysis/intrinsics.ll @@ -22,8 +22,8 @@ declare <8 x i16> @llvm.masked.load.v8i16.p0v8i16(<8 x i16>*, i32, <8 x i1>, <8 x i16>) nounwind readonly declare void @llvm.masked.store.v8i16.p0v8i16(<8 x i16>, <8 x i16>*, i32, <8 x i1>) nounwind -; CHECK: attributes #0 = { argmemonly nocallback nofree nosync nounwind readonly willreturn } -; CHECK: attributes #1 = { argmemonly nocallback nofree nosync nounwind willreturn writeonly } +; CHECK: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) } +; CHECK: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: write) } ; CHECK: attributes [[NUW]] = { nounwind } !0 = !{!"tbaa root"} Index: llvm/test/Assembler/aarch64-intrinsics-attributes.ll =================================================================== --- llvm/test/Assembler/aarch64-intrinsics-attributes.ll +++ llvm/test/Assembler/aarch64-intrinsics-attributes.ll @@ -23,4 +23,4 @@ declare @llvm.aarch64.sve.dup.nxv4i32(, , i32) ; CHECK: attributes [[NOFREE_NOUNWIND_WILLRETURN]] = { nofree nounwind willreturn } -; CHECK: attributes [[NO_CALLBACK_NOFREE_NOSYNC_NOUNWIND_READNONE_WILLRETURN]] = { nocallback nofree nosync nounwind readnone willreturn } +; CHECK: attributes [[NO_CALLBACK_NOFREE_NOSYNC_NOUNWIND_READNONE_WILLRETURN]] = { nocallback nofree nosync nounwind willreturn memory(none) } Index: llvm/test/Assembler/masked-load-store-intrinsics-attributes.ll =================================================================== --- llvm/test/Assembler/masked-load-store-intrinsics-attributes.ll +++ llvm/test/Assembler/masked-load-store-intrinsics-attributes.ll @@ -15,6 +15,6 @@ ; CHECK: declare void @llvm.masked.compressstore.v8i32(<8 x i32>, ptr nocapture, <8 x i1>) [[ARGMEMONLY_NOCALLBACK_NOFREE_NOSYNC_NOUNWIND_WILLRETURN_WRITEONLY:#[0-9]+]] declare void @llvm.masked.compressstore.v8i32(<8 x i32>, ptr, <8 x i1>) -; CHECK: attributes [[ARGMEMONLY_NOCALLBACK_NOFREE_NOSYNC_NOUNWIND_READONLY_WILLRETURN]] = { argmemonly nocallback nofree nosync nounwind readonly willreturn } -; CHECK: attributes [[ARGMEMONLY_NOCALLBACK_NOFREE_NOSYNC_NOUNWIND_WILLRETURN_WRITEONLY]] = { argmemonly nocallback nofree nosync nounwind willreturn writeonly } -; CHECK: attributes [[NOCALLBACK_NOFREE_NOSYNC_NOUNWIND_READONLY_WILLRETURN]] = { nocallback nofree nosync nounwind readonly willreturn } +; CHECK: attributes [[ARGMEMONLY_NOCALLBACK_NOFREE_NOSYNC_NOUNWIND_READONLY_WILLRETURN]] = { nocallback nofree nosync nounwind willreturn memory(argmem: read) } +; CHECK: attributes [[ARGMEMONLY_NOCALLBACK_NOFREE_NOSYNC_NOUNWIND_WILLRETURN_WRITEONLY]] = { nocallback nofree nosync nounwind willreturn memory(argmem: write) } +; CHECK: attributes [[NOCALLBACK_NOFREE_NOSYNC_NOUNWIND_READONLY_WILLRETURN]] = { nocallback nofree nosync nounwind willreturn memory(read) } Index: llvm/test/Bindings/llvm-c/debug_info.ll =================================================================== --- llvm/test/Bindings/llvm-c/debug_info.ll +++ llvm/test/Bindings/llvm-c/debug_info.ll @@ -12,13 +12,13 @@ ; CHECK-NEXT: call void @llvm.dbg.value(metadata i64 0, metadata !41, metadata !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)), !dbg !44 ; CHECK-NEXT: } -; CHECK: ; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +; CHECK: ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) ; CHECK-NEXT: declare void @llvm.dbg.declare(metadata, metadata, metadata) #0 -; CHECK: ; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +; CHECK: ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) ; CHECK-NEXT: declare void @llvm.dbg.value(metadata, metadata, metadata) #0 -; CHECK: attributes #0 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CHECK: attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CHECK: !llvm.dbg.cu = !{!0} ; CHECK-NEXT: !FooType = !{!28} Index: llvm/test/Bitcode/attributes-3.3.ll =================================================================== --- llvm/test/Bitcode/attributes-3.3.ll +++ llvm/test/Bitcode/attributes-3.3.ll @@ -213,8 +213,8 @@ ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } -; CHECK: attributes #2 = { readnone } -; CHECK: attributes #3 = { readonly } +; CHECK: attributes #2 = { memory(none) } +; CHECK: attributes #3 = { memory(read) } ; CHECK: attributes #4 = { noinline } ; CHECK: attributes #5 = { alwaysinline } ; CHECK: attributes #6 = { optsize } Index: llvm/test/Bitcode/attributes.ll =================================================================== --- llvm/test/Bitcode/attributes.ll +++ llvm/test/Bitcode/attributes.ll @@ -540,8 +540,8 @@ ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } -; CHECK: attributes #2 = { readnone } -; CHECK: attributes #3 = { readonly } +; CHECK: attributes #2 = { memory(none) } +; CHECK: attributes #3 = { memory(read) } ; CHECK: attributes #4 = { noinline } ; CHECK: attributes #5 = { alwaysinline } ; CHECK: attributes #6 = { optsize } @@ -564,13 +564,13 @@ ; CHECK: attributes #23 = { noinline optnone } ; CHECK: attributes #24 = { jumptable } ; CHECK: attributes #25 = { convergent } -; CHECK: attributes #26 = { argmemonly } +; CHECK: attributes #26 = { memory(argmem: readwrite) } ; CHECK: attributes #27 = { norecurse } -; CHECK: attributes #28 = { inaccessiblememonly } -; CHECK: attributes #29 = { inaccessiblemem_or_argmemonly } +; CHECK: attributes #28 = { memory(inaccessiblemem: readwrite) } +; CHECK: attributes #29 = { memory(argmem: readwrite, inaccessiblemem: readwrite) } ; CHECK: attributes #30 = { allocsize(0) } ; CHECK: attributes #31 = { allocsize(0,1) } -; CHECK: attributes #32 = { writeonly } +; CHECK: attributes #32 = { memory(write) } ; CHECK: attributes #33 = { speculatable } ; CHECK: attributes #34 = { sanitize_hwaddress } ; CHECK: attributes #35 = { shadowcallstack } Index: llvm/test/Bitcode/compatibility-3.6.ll =================================================================== --- llvm/test/Bitcode/compatibility-3.6.ll +++ llvm/test/Bitcode/compatibility-3.6.ll @@ -1168,8 +1168,8 @@ ; CHECK: attributes #15 = { nounwind } ; CHECK: attributes #16 = { noinline optnone } ; CHECK: attributes #17 = { optsize } -; CHECK: attributes #18 = { readnone } -; CHECK: attributes #19 = { readonly } +; CHECK: attributes #18 = { memory(none) } +; CHECK: attributes #19 = { memory(read) } ; CHECK: attributes #20 = { returns_twice } ; CHECK: attributes #21 = { sanitize_address } ; CHECK: attributes #22 = { sanitize_memory } @@ -1179,12 +1179,12 @@ ; CHECK: attributes #26 = { sspstrong } ; CHECK: attributes #27 = { uwtable } ; CHECK: attributes #28 = { "cpu"="cortex-a8" } -; CHECK: attributes #29 = { nocallback nofree nosync nounwind readnone willreturn } +; CHECK: attributes #29 = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK: attributes #30 = { nocallback nofree nosync nounwind willreturn } -; CHECK: attributes #31 = { argmemonly nounwind readonly } -; CHECK: attributes #32 = { argmemonly nounwind } -; CHECK: attributes #33 = { nounwind readonly } -; CHECK: attributes #34 = { inaccessiblemem_or_argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #31 = { nounwind memory(argmem: read) } +; CHECK: attributes #32 = { nounwind memory(argmem: readwrite) } +; CHECK: attributes #33 = { nounwind memory(read) } +; CHECK: attributes #34 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) } ; CHECK: attributes #35 = { builtin } ;; Metadata Index: llvm/test/Bitcode/compatibility-3.7.ll =================================================================== --- llvm/test/Bitcode/compatibility-3.7.ll +++ llvm/test/Bitcode/compatibility-3.7.ll @@ -1229,8 +1229,8 @@ ; CHECK: attributes #16 = { nounwind } ; CHECK: attributes #17 = { noinline optnone } ; CHECK: attributes #18 = { optsize } -; CHECK: attributes #19 = { readnone } -; CHECK: attributes #20 = { readonly } +; CHECK: attributes #19 = { memory(none) } +; CHECK: attributes #20 = { memory(read) } ; CHECK: attributes #21 = { returns_twice } ; CHECK: attributes #22 = { safestack } ; CHECK: attributes #23 = { sanitize_address } @@ -1242,12 +1242,12 @@ ; CHECK: attributes #29 = { "thunk" } ; CHECK: attributes #30 = { uwtable } ; CHECK: attributes #31 = { "cpu"="cortex-a8" } -; CHECK: attributes #32 = { nocallback nofree nosync nounwind readnone willreturn } +; CHECK: attributes #32 = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK: attributes #33 = { nocallback nofree nosync nounwind willreturn } -; CHECK: attributes #34 = { argmemonly nounwind readonly } -; CHECK: attributes #35 = { argmemonly nounwind } -; CHECK: attributes #36 = { nounwind readonly } -; CHECK: attributes #37 = { inaccessiblemem_or_argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #34 = { nounwind memory(argmem: read) } +; CHECK: attributes #35 = { nounwind memory(argmem: readwrite) } +; CHECK: attributes #36 = { nounwind memory(read) } +; CHECK: attributes #37 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) } ; CHECK: attributes #38 = { builtin } ;; Metadata Index: llvm/test/Bitcode/compatibility-3.8.ll =================================================================== --- llvm/test/Bitcode/compatibility-3.8.ll +++ llvm/test/Bitcode/compatibility-3.8.ll @@ -1536,8 +1536,8 @@ ; CHECK: attributes #16 = { nounwind } ; CHECK: attributes #17 = { noinline optnone } ; CHECK: attributes #18 = { optsize } -; CHECK: attributes #19 = { readnone } -; CHECK: attributes #20 = { readonly } +; CHECK: attributes #19 = { memory(none) } +; CHECK: attributes #20 = { memory(read) } ; CHECK: attributes #21 = { returns_twice } ; CHECK: attributes #22 = { safestack } ; CHECK: attributes #23 = { sanitize_address } @@ -1550,14 +1550,14 @@ ; CHECK: attributes #30 = { uwtable } ; CHECK: attributes #31 = { "cpu"="cortex-a8" } ; CHECK: attributes #32 = { norecurse } -; CHECK: attributes #33 = { inaccessiblememonly } -; CHECK: attributes #34 = { inaccessiblemem_or_argmemonly } -; CHECK: attributes #35 = { nocallback nofree nosync nounwind readnone willreturn } +; CHECK: attributes #33 = { memory(inaccessiblemem: readwrite) } +; CHECK: attributes #34 = { memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK: attributes #35 = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK: attributes #36 = { nocallback nofree nosync nounwind willreturn } -; CHECK: attributes #37 = { argmemonly nounwind readonly } -; CHECK: attributes #38 = { argmemonly nounwind } -; CHECK: attributes #39 = { nounwind readonly } -; CHECK: attributes #40 = { inaccessiblemem_or_argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #37 = { nounwind memory(argmem: read) } +; CHECK: attributes #38 = { nounwind memory(argmem: readwrite) } +; CHECK: attributes #39 = { nounwind memory(read) } +; CHECK: attributes #40 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) } ; CHECK: attributes #41 = { builtin } ;; Metadata Index: llvm/test/Bitcode/compatibility-3.9.ll =================================================================== --- llvm/test/Bitcode/compatibility-3.9.ll +++ llvm/test/Bitcode/compatibility-3.9.ll @@ -1609,8 +1609,8 @@ ; CHECK: attributes #16 = { nounwind } ; CHECK: attributes #17 = { noinline optnone } ; CHECK: attributes #18 = { optsize } -; CHECK: attributes #19 = { readnone } -; CHECK: attributes #20 = { readonly } +; CHECK: attributes #19 = { memory(none) } +; CHECK: attributes #20 = { memory(read) } ; CHECK: attributes #21 = { returns_twice } ; CHECK: attributes #22 = { safestack } ; CHECK: attributes #23 = { sanitize_address } @@ -1623,15 +1623,15 @@ ; CHECK: attributes #30 = { uwtable } ; CHECK: attributes #31 = { "cpu"="cortex-a8" } ; CHECK: attributes #32 = { norecurse } -; CHECK: attributes #33 = { inaccessiblememonly } -; CHECK: attributes #34 = { inaccessiblemem_or_argmemonly } -; CHECK: attributes #35 = { nocallback nofree nosync nounwind readnone willreturn } +; CHECK: attributes #33 = { memory(inaccessiblemem: readwrite) } +; CHECK: attributes #34 = { memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK: attributes #35 = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK: attributes #36 = { nocallback nofree nosync nounwind willreturn } -; CHECK: attributes #37 = { argmemonly nounwind readonly } -; CHECK: attributes #38 = { argmemonly nounwind } -; CHECK: attributes #39 = { nounwind readonly } -; CHECK: attributes #40 = { writeonly } -; CHECK: attributes #41 = { inaccessiblemem_or_argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #37 = { nounwind memory(argmem: read) } +; CHECK: attributes #38 = { nounwind memory(argmem: readwrite) } +; CHECK: attributes #39 = { nounwind memory(read) } +; CHECK: attributes #40 = { memory(write) } +; CHECK: attributes #41 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) } ; CHECK: attributes #42 = { builtin } ;; Metadata Index: llvm/test/Bitcode/compatibility-4.0.ll =================================================================== --- llvm/test/Bitcode/compatibility-4.0.ll +++ llvm/test/Bitcode/compatibility-4.0.ll @@ -1634,8 +1634,8 @@ ; CHECK: attributes #16 = { nounwind } ; CHECK: attributes #17 = { noinline optnone } ; CHECK: attributes #18 = { optsize } -; CHECK: attributes #19 = { readnone } -; CHECK: attributes #20 = { readonly } +; CHECK: attributes #19 = { memory(none) } +; CHECK: attributes #20 = { memory(read) } ; CHECK: attributes #21 = { returns_twice } ; CHECK: attributes #22 = { safestack } ; CHECK: attributes #23 = { sanitize_address } @@ -1648,15 +1648,15 @@ ; CHECK: attributes #30 = { uwtable } ; CHECK: attributes #31 = { "cpu"="cortex-a8" } ; CHECK: attributes #32 = { norecurse } -; CHECK: attributes #33 = { inaccessiblememonly } -; CHECK: attributes #34 = { inaccessiblemem_or_argmemonly } -; CHECK: attributes #35 = { nocallback nofree nosync nounwind readnone willreturn } +; CHECK: attributes #33 = { memory(inaccessiblemem: readwrite) } +; CHECK: attributes #34 = { memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK: attributes #35 = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK: attributes #36 = { nocallback nofree nosync nounwind willreturn } -; CHECK: attributes #37 = { argmemonly nounwind readonly } -; CHECK: attributes #38 = { argmemonly nounwind } -; CHECK: attributes #39 = { nounwind readonly } -; CHECK: attributes #40 = { writeonly } -; CHECK: attributes #41 = { inaccessiblemem_or_argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #37 = { nounwind memory(argmem: read) } +; CHECK: attributes #38 = { nounwind memory(argmem: readwrite) } +; CHECK: attributes #39 = { nounwind memory(read) } +; CHECK: attributes #40 = { memory(write) } +; CHECK: attributes #41 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) } ; CHECK: attributes #42 = { builtin } ;; Metadata Index: llvm/test/Bitcode/compatibility-5.0.ll =================================================================== --- llvm/test/Bitcode/compatibility-5.0.ll +++ llvm/test/Bitcode/compatibility-5.0.ll @@ -1649,8 +1649,8 @@ ; CHECK: attributes #16 = { nounwind } ; CHECK: attributes #17 = { noinline optnone } ; CHECK: attributes #18 = { optsize } -; CHECK: attributes #19 = { readnone } -; CHECK: attributes #20 = { readonly } +; CHECK: attributes #19 = { memory(none) } +; CHECK: attributes #20 = { memory(read) } ; CHECK: attributes #21 = { returns_twice } ; CHECK: attributes #22 = { safestack } ; CHECK: attributes #23 = { sanitize_address } @@ -1663,16 +1663,16 @@ ; CHECK: attributes #30 = { uwtable } ; CHECK: attributes #31 = { "cpu"="cortex-a8" } ; CHECK: attributes #32 = { norecurse } -; CHECK: attributes #33 = { inaccessiblememonly } -; CHECK: attributes #34 = { inaccessiblemem_or_argmemonly } -; CHECK: attributes #35 = { nocallback nofree nosync nounwind readnone willreturn } -; CHECK: attributes #36 = { nocallback nofree nosync nounwind willreturn } -; CHECK: attributes #37 = { argmemonly nounwind readonly } -; CHECK: attributes #38 = { argmemonly nounwind } -; CHECK: attributes #39 = { nounwind readonly } -; CHECK: attributes #40 = { writeonly } +; CHECK: attributes #33 = { memory(inaccessiblemem: readwrite) } +; CHECK: attributes #34 = { memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK: attributes #35 = { nocallback nofree nosync nounwind willreturn memory(none) } +; CHECK: attributes #36 = { nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #37 = { nounwind memory(argmem: read) } +; CHECK: attributes #38 = { nounwind memory(argmem: readwrite) } +; CHECK: attributes #39 = { nounwind memory(read) } +; CHECK: attributes #40 = { memory(write) } ; CHECK: attributes #41 = { speculatable } -; CHECK: attributes #42 = { inaccessiblemem_or_argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #42 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) } ; CHECK: attributes #43 = { builtin } ;; Metadata Index: llvm/test/Bitcode/compatibility-6.0.ll =================================================================== --- llvm/test/Bitcode/compatibility-6.0.ll +++ llvm/test/Bitcode/compatibility-6.0.ll @@ -1660,8 +1660,8 @@ ; CHECK: attributes #16 = { nounwind } ; CHECK: attributes #17 = { noinline optnone } ; CHECK: attributes #18 = { optsize } -; CHECK: attributes #19 = { readnone } -; CHECK: attributes #20 = { readonly } +; CHECK: attributes #19 = { memory(none) } +; CHECK: attributes #20 = { memory(read) } ; CHECK: attributes #21 = { returns_twice } ; CHECK: attributes #22 = { safestack } ; CHECK: attributes #23 = { sanitize_address } @@ -1674,16 +1674,16 @@ ; CHECK: attributes #30 = { uwtable } ; CHECK: attributes #31 = { "cpu"="cortex-a8" } ; CHECK: attributes #32 = { norecurse } -; CHECK: attributes #33 = { inaccessiblememonly } -; CHECK: attributes #34 = { inaccessiblemem_or_argmemonly } -; CHECK: attributes #35 = { nocallback nofree nosync nounwind readnone willreturn } +; CHECK: attributes #33 = { memory(inaccessiblemem: readwrite) } +; CHECK: attributes #34 = { memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK: attributes #35 = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK: attributes #36 = { nocallback nofree nosync nounwind willreturn } -; CHECK: attributes #37 = { argmemonly nounwind readonly } -; CHECK: attributes #38 = { argmemonly nounwind } -; CHECK: attributes #39 = { nounwind readonly } -; CHECK: attributes #40 = { writeonly } +; CHECK: attributes #37 = { nounwind memory(argmem: read) } +; CHECK: attributes #38 = { nounwind memory(argmem: readwrite) } +; CHECK: attributes #39 = { nounwind memory(read) } +; CHECK: attributes #40 = { memory(write) } ; CHECK: attributes #41 = { speculatable } -; CHECK: attributes #42 = { inaccessiblemem_or_argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #42 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) } ; CHECK: attributes #43 = { builtin } ;; Metadata Index: llvm/test/Bitcode/compatibility.ll =================================================================== --- llvm/test/Bitcode/compatibility.ll +++ llvm/test/Bitcode/compatibility.ll @@ -1985,8 +1985,8 @@ ; CHECK: attributes #16 = { nounwind } ; CHECK: attributes #17 = { noinline optnone } ; CHECK: attributes #18 = { optsize } -; CHECK: attributes #19 = { readnone } -; CHECK: attributes #20 = { readonly } +; CHECK: attributes #19 = { memory(none) } +; CHECK: attributes #20 = { memory(read) } ; CHECK: attributes #21 = { returns_twice } ; CHECK: attributes #22 = { safestack } ; CHECK: attributes #23 = { sanitize_address } @@ -1999,15 +1999,15 @@ ; CHECK: attributes #30 = { uwtable } ; CHECK: attributes #31 = { "cpu"="cortex-a8" } ; CHECK: attributes #32 = { norecurse } -; CHECK: attributes #33 = { inaccessiblememonly } -; CHECK: attributes #34 = { inaccessiblemem_or_argmemonly } -; CHECK: attributes #35 = { nocallback nofree nosync nounwind readnone willreturn } +; CHECK: attributes #33 = { memory(inaccessiblemem: readwrite) } +; CHECK: attributes #34 = { memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK: attributes #35 = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK: attributes #36 = { nocallback nofree nosync nounwind willreturn } -; CHECK: attributes #37 = { argmemonly nounwind readonly } -; CHECK: attributes #38 = { argmemonly nounwind } -; CHECK: attributes #39 = { nounwind readonly } -; CHECK: attributes #40 = { inaccessiblemem_or_argmemonly nocallback nofree nosync nounwind willreturn } -; CHECK: attributes #41 = { writeonly } +; CHECK: attributes #37 = { nounwind memory(argmem: read) } +; CHECK: attributes #38 = { nounwind memory(argmem: readwrite) } +; CHECK: attributes #39 = { nounwind memory(read) } +; CHECK: attributes #40 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK: attributes #41 = { memory(write) } ; CHECK: attributes #42 = { speculatable } ; CHECK: attributes #43 = { strictfp } ; CHECK: attributes #44 = { nosanitize_coverage } Index: llvm/test/Bitcode/ptest-new.ll =================================================================== --- llvm/test/Bitcode/ptest-new.ll +++ llvm/test/Bitcode/ptest-new.ll @@ -23,4 +23,4 @@ declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) nounwind readnone ; CHECK: attributes #0 = { nounwind } -; CHECK: attributes #1 = { nounwind readnone } +; CHECK: attributes #1 = { nounwind memory(none) } Index: llvm/test/Bitcode/ptest-old.ll =================================================================== --- llvm/test/Bitcode/ptest-old.ll +++ llvm/test/Bitcode/ptest-old.ll @@ -24,4 +24,4 @@ declare i32 @llvm.x86.sse41.ptestnzc(<4 x float>, <4 x float>) nounwind readnone ; CHECK: attributes #0 = { nounwind } -; CHECK: attributes #1 = { nounwind readnone } +; CHECK: attributes #1 = { nounwind memory(none) } Index: llvm/test/Bitcode/upgrade-frame-pointer.ll =================================================================== --- llvm/test/Bitcode/upgrade-frame-pointer.ll +++ llvm/test/Bitcode/upgrade-frame-pointer.ll @@ -27,7 +27,7 @@ ;; Other attributes (e.g. readnone) are unaffected. ; CHECK: attributes #0 = { "frame-pointer"="all" } -; CHECK: attributes #1 = { readnone "frame-pointer"="all" } +; CHECK: attributes #1 = { memory(none) "frame-pointer"="all" } ; CHECK: attributes #2 = { "frame-pointer"="non-leaf" } -; CHECK: attributes #3 = { readnone "frame-pointer"="non-leaf" } +; CHECK: attributes #3 = { memory(none) "frame-pointer"="non-leaf" } ; CHECK: attributes #4 = { "frame-pointer"="none" } Index: llvm/test/Bitcode/upgrade-invariant-group-barrier.ll =================================================================== --- llvm/test/Bitcode/upgrade-invariant-group-barrier.ll +++ llvm/test/Bitcode/upgrade-invariant-group-barrier.ll @@ -13,9 +13,9 @@ ret void } -; CHECK: Function Attrs: inaccessiblememonly nocallback nofree nosync nounwind speculatable willreturn +; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite) ; CHECK: declare i8* @llvm.launder.invariant.group.p0i8(i8*) -; CHECK: Function Attrs: inaccessiblememonly nocallback nofree nosync nounwind speculatable willreturn +; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite) ; CHECK: declare i16* @llvm.launder.invariant.group.p0i16(i16*) declare i8* @llvm.invariant.group.barrier(i8*) declare i8* @llvm.invariant.group.barrier.p0i8(i8*) Index: llvm/test/CodeGen/AMDGPU/addrspacecast-constantexpr.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/addrspacecast-constantexpr.ll +++ llvm/test/CodeGen/AMDGPU/addrspacecast-constantexpr.ll @@ -226,10 +226,10 @@ attributes #0 = { argmemonly nounwind } attributes #1 = { nounwind } ;. -; AKF_HSA: attributes #[[ATTR0:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } +; AKF_HSA: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } ; AKF_HSA: attributes #[[ATTR1]] = { nounwind } ;. -; ATTRIBUTOR_HSA: attributes #[[ATTR0:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } +; ATTRIBUTOR_HSA: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } ; ATTRIBUTOR_HSA: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ; ATTRIBUTOR_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ;. Index: llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll +++ llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll @@ -928,7 +928,7 @@ attributes #5 = { nounwind sanitize_address "amdgpu-no-implicitarg-ptr" } ;. -; AKF_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } +; AKF_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind speculatable willreturn memory(none) } ; AKF_HSA: attributes #[[ATTR1]] = { nounwind "target-cpu"="fiji" } ; AKF_HSA: attributes #[[ATTR2]] = { nounwind "target-cpu"="gfx900" } ; AKF_HSA: attributes #[[ATTR3]] = { nounwind } @@ -936,7 +936,7 @@ ; AKF_HSA: attributes #[[ATTR5]] = { nounwind sanitize_address } ; AKF_HSA: attributes #[[ATTR6:[0-9]+]] = { nounwind sanitize_address "amdgpu-no-implicitarg-ptr" } ;. -; ATTRIBUTOR_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } +; ATTRIBUTOR_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind speculatable willreturn memory(none) } ; ATTRIBUTOR_HSA: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } ; ATTRIBUTOR_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } ; ATTRIBUTOR_HSA: attributes #[[ATTR3]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "target-cpu"="fiji" "uniform-work-group-size"="false" } Index: llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll +++ llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll @@ -642,11 +642,11 @@ attributes #1 = { nounwind } ;. -; AKF_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } +; AKF_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind speculatable willreturn memory(none) } ; AKF_HSA: attributes #[[ATTR1]] = { nounwind } ; AKF_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-stack-objects" } ;. -; ATTRIBUTOR_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } +; ATTRIBUTOR_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind speculatable willreturn memory(none) } ; ATTRIBUTOR_HSA: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ; ATTRIBUTOR_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ; ATTRIBUTOR_HSA: attributes #[[ATTR3]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } Index: llvm/test/CodeGen/AMDGPU/annotate-kernel-features.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/annotate-kernel-features.ll +++ llvm/test/CodeGen/AMDGPU/annotate-kernel-features.ll @@ -414,10 +414,10 @@ ; NOHSA: attributes #[[ATTR8]] = { nounwind "amdgpu-work-item-id-y" "amdgpu-work-item-id-z" "uniform-work-group-size"="false" } ; NOHSA: attributes #[[ATTR9]] = { nounwind "amdgpu-work-group-id-y" "amdgpu-work-group-id-z" "amdgpu-work-item-id-y" "amdgpu-work-item-id-z" "uniform-work-group-size"="false" } ;. -; AKF_CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } +; AKF_CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind speculatable willreturn memory(none) } ; AKF_CHECK: attributes #[[ATTR1]] = { nounwind } ;. -; ATTRIBUTOR_CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } +; ATTRIBUTOR_CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind speculatable willreturn memory(none) } ; ATTRIBUTOR_CHECK: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ; ATTRIBUTOR_CHECK: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ; ATTRIBUTOR_CHECK: attributes #[[ATTR3]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } Index: llvm/test/CodeGen/AMDGPU/inline-attr.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/inline-attr.ll +++ llvm/test/CodeGen/AMDGPU/inline-attr.ll @@ -6,14 +6,14 @@ ; GCN: define amdgpu_kernel void @caller(float addrspace(1)* nocapture %p) local_unnamed_addr #1 { ; GCN: %mul.i = fmul float %load, 1.500000e+01 -; UNSAFE: attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn "unsafe-fp-math"="true" } -; UNSAFE: attributes #1 = { argmemonly mustprogress nofree norecurse nosync nounwind willreturn "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="true" } +; UNSAFE: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "unsafe-fp-math"="true" } +; UNSAFE: attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="true" } -; NOINFS: attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn "no-infs-fp-math"="true" } -; NOINFS: attributes #1 = { argmemonly mustprogress nofree norecurse nosync nounwind willreturn "less-precise-fpmad"="false" "no-infs-fp-math"="true" "no-nans-fp-math"="false" "unsafe-fp-math"="false" } +; NOINFS: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "no-infs-fp-math"="true" } +; NOINFS: attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) "less-precise-fpmad"="false" "no-infs-fp-math"="true" "no-nans-fp-math"="false" "unsafe-fp-math"="false" } -; NONANS: attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn "no-nans-fp-math"="true" } -; NONANS: attributes #1 = { argmemonly mustprogress nofree norecurse nosync nounwind willreturn "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="true" "unsafe-fp-math"="false" } +; NONANS: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "no-nans-fp-math"="true" } +; NONANS: attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="true" "unsafe-fp-math"="false" } define float @foo(float %x) #0 { entry: Index: llvm/test/CodeGen/AMDGPU/pal-simple-indirect-call.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/pal-simple-indirect-call.ll +++ llvm/test/CodeGen/AMDGPU/pal-simple-indirect-call.ll @@ -69,8 +69,8 @@ attributes #0 = { nounwind readnone speculatable willreturn } ;. -; AKF_GCN: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } +; AKF_GCN: attributes #[[ATTR0:[0-9]+]] = { nounwind speculatable willreturn memory(none) } ;. ; ATTRIBUTOR_GCN: attributes #[[ATTR0]] = { "uniform-work-group-size"="false" } -; ATTRIBUTOR_GCN: attributes #[[ATTR1:[0-9]+]] = { nounwind readnone speculatable willreturn } +; ATTRIBUTOR_GCN: attributes #[[ATTR1:[0-9]+]] = { nounwind speculatable willreturn memory(none) } ;. Index: llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll +++ llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll @@ -791,5 +791,5 @@ ; GCN-PRELINK: declare float @_Z11native_sqrtf(float) local_unnamed_addr #[[$NOUNWIND_READONLY]] ; GCN-PRELINK: attributes #[[$NOUNWIND]] = { nounwind } -; GCN-PRELINK: attributes #[[$NOUNWIND_READONLY]] = { nofree nounwind readonly } +; GCN-PRELINK: attributes #[[$NOUNWIND_READONLY]] = { nofree nounwind memory(read) } attributes #0 = { nounwind } Index: llvm/test/CodeGen/AMDGPU/uniform-work-group-recursion-test.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/uniform-work-group-recursion-test.ll +++ llvm/test/CodeGen/AMDGPU/uniform-work-group-recursion-test.ll @@ -101,7 +101,7 @@ attributes #0 = { nounwind readnone } attributes #1 = { "uniform-work-group-size"="true" } ;. -; CHECK: attributes #[[ATTR0]] = { nounwind readnone "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; CHECK: attributes #[[ATTR1]] = { nounwind readnone "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } +; CHECK: attributes #[[ATTR0]] = { nounwind memory(none) "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; CHECK: attributes #[[ATTR1]] = { nounwind memory(none) "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } ; CHECK: attributes #[[ATTR2]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } ;. Index: llvm/test/Feature/OperandBundles/function-attrs.ll =================================================================== --- llvm/test/Feature/OperandBundles/function-attrs.ll +++ llvm/test/Feature/OperandBundles/function-attrs.ll @@ -43,8 +43,8 @@ ret void } -; CHECK: attributes #0 = { nofree readonly } -; CHECK: attributes #1 = { nofree nosync readnone } -; CHECK: attributes #2 = { writeonly } +; CHECK: attributes #0 = { nofree memory(read) } +; CHECK: attributes #1 = { nofree nosync memory(none) } +; CHECK: attributes #2 = { memory(write) } ; CHECK: attributes #3 = { nofree } ; CHECK: attributes #4 = { nofree nosync } Index: llvm/test/Feature/intrinsics.ll =================================================================== --- llvm/test/Feature/intrinsics.ll +++ llvm/test/Feature/intrinsics.ll @@ -69,5 +69,5 @@ ret void } -; CHECK: attributes #0 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CHECK: attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CHECK: attributes #1 = { cold noreturn nounwind } Index: llvm/test/Instrumentation/DataFlowSanitizer/basic.ll =================================================================== --- llvm/test/Instrumentation/DataFlowSanitizer/basic.ll +++ llvm/test/Instrumentation/DataFlowSanitizer/basic.ll @@ -35,10 +35,10 @@ ; CHECK: declare void @__dfsan_mem_transfer_callback(i[[#SBITS]]*, i64) ; CHECK: declare void @__dfsan_cmp_callback(i[[#SBITS]]) -; CHECK: ; Function Attrs: nounwind readonly +; CHECK: ; Function Attrs: nounwind memory(read) ; CHECK-NEXT: declare zeroext i[[#SBITS]] @__dfsan_union_load(i[[#SBITS]]*, i64) -; CHECK: ; Function Attrs: nounwind readonly +; CHECK: ; Function Attrs: nounwind memory(read) ; CHECK-NEXT: declare zeroext i64 @__dfsan_load_label_and_origin(i8*, i64) ; CHECK: declare void @__dfsan_unimplemented(i8*) Index: llvm/test/Instrumentation/MemorySanitizer/attributes.ll =================================================================== --- llvm/test/Instrumentation/MemorySanitizer/attributes.ll +++ llvm/test/Instrumentation/MemorySanitizer/attributes.ll @@ -44,11 +44,8 @@ ret void } -; CHECK-NOT: readnone -; CHECK-NOT: readonly -; CHECK-NOT: writeonly -; CHECK-NOT: argmemonly +; CHECK-NOT: memory( ; CHECK-NOT: speculatable -; CHECK: Function Attrs: nocallback nofree nosync nounwind readnone willreturn +; CHECK: Function Attrs: nocallback nofree nosync nounwind willreturn memory(none) ; CHECK-NEXT: declare void @llvm.donothing Index: llvm/test/Other/attribute-comment.ll =================================================================== --- llvm/test/Other/attribute-comment.ll +++ llvm/test/Other/attribute-comment.ll @@ -1,6 +1,6 @@ ; RUN: opt -S < %s | FileCheck %s -strict-whitespace -; CHECK: {{^}}; Function Attrs: nounwind readnone ssp uwtable{{$}} +; CHECK: {{^}}; Function Attrs: nounwind ssp memory(none) uwtable{{$}} ; CHECK-NEXT: define void @test1() #0 define void @test1() #0 { ret void Index: llvm/test/Other/cgscc-devirt-iteration.ll =================================================================== --- llvm/test/Other/cgscc-devirt-iteration.ll +++ llvm/test/Other/cgscc-devirt-iteration.ll @@ -15,7 +15,7 @@ ; RUN: opt -aa-pipeline=basic-aa -passes='default' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER2 declare void @readnone() readnone -; CHECK: Function Attrs: nofree nosync readnone +; CHECK: Function Attrs: nofree nosync memory(none) ; CHECK-NEXT: declare void @readnone() declare void @unknown() @@ -28,7 +28,7 @@ define void @test1() { ; BEFORE-NOT: Function Attrs -; AFTER: Function Attrs: nofree nosync readnone +; AFTER: Function Attrs: nofree nosync memory(none) ; CHECK-LABEL: define void @test1() entry: %fptr = alloca void ()* @@ -51,13 +51,13 @@ ; devirtualize again, and then deduce readnone. declare void @readnone_with_arg(void ()**) readnone -; CHECK: Function Attrs: nofree nosync readnone +; CHECK: Function Attrs: nofree nosync memory(none) ; CHECK-LABEL: declare void @readnone_with_arg(void ()**) define void @test2_a(void ()** %ignore) { ; BEFORE-NOT: Function Attrs -; AFTER1: Function Attrs: nofree readonly -; AFTER2: Function Attrs: nofree nosync readnone +; AFTER1: Function Attrs: nofree memory(read) +; AFTER2: Function Attrs: nofree nosync memory(none) ; BEFORE: define void @test2_a(void ()** %ignore) ; AFTER: define void @test2_a(void ()** readnone %ignore) entry: @@ -77,8 +77,8 @@ define void @test2_b() { ; BEFORE-NOT: Function Attrs -; AFTER1: Function Attrs: nofree readonly -; AFTER2: Function Attrs: nofree nosync readnone +; AFTER1: Function Attrs: nofree memory(read) +; AFTER2: Function Attrs: nofree nosync memory(none) ; CHECK-LABEL: define void @test2_b() entry: %f2ptr = alloca void ()* Index: llvm/test/Other/cgscc-iterate-function-mutation.ll =================================================================== --- llvm/test/Other/cgscc-iterate-function-mutation.ll +++ llvm/test/Other/cgscc-iterate-function-mutation.ll @@ -338,4 +338,4 @@ ret void } -; CHECK: attributes #0 = { nofree nosync readnone } +; CHECK: attributes #0 = { nofree nosync memory(none) } Index: llvm/test/Other/invariant.group.ll =================================================================== --- llvm/test/Other/invariant.group.ll +++ llvm/test/Other/invariant.group.ll @@ -91,11 +91,11 @@ declare void @useBool(i1) declare void @clobber(i8*) -; CHECK: Function Attrs: inaccessiblememonly nocallback nofree nosync nounwind speculatable willreturn{{$}} +; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite){{$}} ; CHECK-NEXT: declare i8* @llvm.launder.invariant.group.p0i8(i8*) declare i8* @llvm.launder.invariant.group.p0i8(i8*) -; CHECK: Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn{{$}} +; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none){{$}} ; CHECK-NEXT: declare i8* @llvm.strip.invariant.group.p0i8(i8*) declare i8* @llvm.strip.invariant.group.p0i8(i8*) Index: llvm/test/Other/opt-override-mcpu-mattr.ll =================================================================== --- llvm/test/Other/opt-override-mcpu-mattr.ll +++ llvm/test/Other/opt-override-mcpu-mattr.ll @@ -4,8 +4,8 @@ ; target-cpu and target-features using command line options -mcpu and ; -mattr. -; CHECK: attributes #0 = { nounwind readnone ssp uwtable "target-cpu"="broadwell" "target-features"="+ssse3,+cx16,+sse,+sse2,+sse3,+avx2" "use-soft-float"="false" } -; CHECK: attributes #1 = { nounwind readnone ssp uwtable "target-cpu"="core2" "target-features"="+ssse3,+cx16,+sse,+sse2,+sse3,+avx2" "use-soft-float"="false" } +; CHECK: attributes #0 = { nounwind ssp memory(none) uwtable "target-cpu"="broadwell" "target-features"="+ssse3,+cx16,+sse,+sse2,+sse3,+avx2" "use-soft-float"="false" } +; CHECK: attributes #1 = { nounwind ssp memory(none) uwtable "target-cpu"="core2" "target-features"="+ssse3,+cx16,+sse,+sse2,+sse3,+avx2" "use-soft-float"="false" } define i32 @no_target_cpu() #0 { entry: Index: llvm/test/Other/print-module-scope.ll =================================================================== --- llvm/test/Other/print-module-scope.ll +++ llvm/test/Other/print-module-scope.ll @@ -30,7 +30,7 @@ ; FOO: define void @foo ; FOO: Function Attrs: nounwind ; FOO: define void @bar -; FOO: Function Attrs: nounwind readnone ssp +; FOO: Function Attrs: nounwind ssp memory(none) ; FOO: declare void @baz define void @foo() nounwind ssp { @@ -49,6 +49,6 @@ attributes #1 = { nounwind readnone ssp "use-soft-float"="false" } ; FOO: attributes #{{[0-9]}} = { nounwind "frame-pointer"="all" } -; FOO: attributes #{{[0-9]}} = { nounwind readnone ssp "use-soft-float"="false" } +; FOO: attributes #{{[0-9]}} = { nounwind ssp memory(none) "use-soft-float"="false" } ; FOO-NOT: IR Dump After {{Simplify the CFG|SimplifyCFGPass}} Index: llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll @@ -3,7 +3,7 @@ ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC define internal i32 @deref(i32* %x) nounwind { -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@deref ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -18,7 +18,7 @@ } define i32 @f(i32 %x) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@f ; TUNIT-SAME: (i32 returned [[X:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -26,7 +26,7 @@ ; TUNIT-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 ; TUNIT-NEXT: ret i32 [[X]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@f ; CGSCC-SAME: (i32 [[X:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -42,9 +42,9 @@ ret i32 %tmp1 } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nounwind readonly willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll @@ -7,7 +7,7 @@ ; because there is a load of %A in the entry block define internal i32 @callee(i1 %C, i32* %A) { ; -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@callee ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -36,13 +36,13 @@ } define i32 @foo(i32* %A) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@foo ; TUNIT-SAME: (i32* nocapture nofree readonly [[A:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree readonly align 4 [[A]]) #[[ATTR1:[0-9]+]] ; TUNIT-NEXT: ret i32 [[X]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]]) #[[ATTR2:[0-9]+]] @@ -53,10 +53,10 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind readonly willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR2]] = { readonly willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll @@ -3,7 +3,7 @@ ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC define internal fastcc i32 @hash(i32* %ts, i32 %mod) nounwind { -; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@hash ; CGSCC-SAME: () #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -14,13 +14,13 @@ } define void @encode(i32* %m, i32* %ts, i32* %new) nounwind { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@encode ; TUNIT-SAME: (i32* nocapture nofree readnone [[M:%.*]], i32* nocapture nofree readnone [[TS:%.*]], i32* nocapture nofree readnone [[NEW:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@encode ; CGSCC-SAME: (i32* nocapture nofree readnone [[M:%.*]], i32* nocapture nofree readnone [[TS:%.*]], i32* nocapture nofree readnone [[NEW:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -31,8 +31,8 @@ unreachable } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree noreturn nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree noreturn nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll @@ -3,7 +3,7 @@ ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC define internal fastcc i32 @term_SharingList(i32* %Term, i32* %List) nounwind { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@term_SharingList ; CGSCC-SAME: () #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -25,7 +25,7 @@ } define i32 @term_Sharing(i32* %Term) nounwind { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@term_Sharing ; CHECK-SAME: (i32* nocapture nofree readnone [[TERM:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -46,5 +46,5 @@ ret i32 0 } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll @@ -7,7 +7,7 @@ target triple = "x86_64-unknown-linux-gnu" define internal fastcc void @no_promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 { -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@no_promote_avx2 ; CHECK-SAME: (<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: bb: @@ -22,7 +22,7 @@ } define void @no_promote(<4 x i64>* %arg) #1 { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@no_promote ; TUNIT-SAME: (<4 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: bb: @@ -35,7 +35,7 @@ ; TUNIT-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@no_promote ; CGSCC-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: bb: @@ -60,7 +60,7 @@ } define internal fastcc void @promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 { -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@promote_avx2 ; CHECK-SAME: (<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: bb: @@ -77,7 +77,7 @@ } define void @promote(<4 x i64>* %arg) #0 { -; TUNIT: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@promote ; TUNIT-SAME: (<4 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: bb: @@ -91,7 +91,7 @@ ; TUNIT-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@promote ; CGSCC-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: bb: @@ -123,15 +123,15 @@ attributes #1 = { nounwind uwtable } attributes #2 = { argmemonly nounwind } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "target-features"="+avx2" } -; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn uwtable } -; TUNIT: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR3]] = { willreturn writeonly } +; TUNIT: attributes #[[ATTR0]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "target-features"="+avx2" } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable } +; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR3]] = { willreturn } ; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "target-features"="+avx2" } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn uwtable } -; CGSCC: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR3]] = { willreturn writeonly } +; CGSCC: attributes #[[ATTR0]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "target-features"="+avx2" } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: readwrite) uwtable } +; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR3]] = { willreturn } ; CGSCC: attributes #[[ATTR4]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll @@ -9,7 +9,7 @@ ; This should promote define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #0 { ; -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; CHECK-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: bb: @@ -27,7 +27,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg) #0 { ; -; TUNIT: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; TUNIT-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: bb: @@ -41,7 +41,7 @@ ; TUNIT-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; CGSCC-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: bb: @@ -69,7 +69,7 @@ ; This should promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { ; -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; CHECK-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: bb: @@ -87,7 +87,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg) #1 { ; -; TUNIT: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; TUNIT-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: bb: @@ -101,7 +101,7 @@ ; TUNIT-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; CGSCC-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: bb: @@ -129,7 +129,7 @@ ; This should promote define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { ; -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256 ; CHECK-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: bb: @@ -147,7 +147,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %arg) #0 { ; -; TUNIT: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 ; TUNIT-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: bb: @@ -161,7 +161,7 @@ ; TUNIT-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 ; CGSCC-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: bb: @@ -189,7 +189,7 @@ ; This should promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #0 { ; -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512 ; CHECK-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: bb: @@ -207,7 +207,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* %arg) #1 { ; -; TUNIT: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 ; TUNIT-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: bb: @@ -221,7 +221,7 @@ ; TUNIT-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 ; CGSCC-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: bb: @@ -249,7 +249,7 @@ ; This should not promote define internal fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { ; -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256 ; CHECK-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: bb: @@ -265,7 +265,7 @@ define void @avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg) #2 { ; -; TUNIT: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 ; TUNIT-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR2:[0-9]+]] { ; TUNIT-NEXT: bb: @@ -278,7 +278,7 @@ ; TUNIT-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 ; CGSCC-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: bb: @@ -305,7 +305,7 @@ ; This should not promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #2 { ; -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256 ; CHECK-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: bb: @@ -321,7 +321,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* %arg) #1 { ; -; TUNIT: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 ; TUNIT-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: bb: @@ -334,7 +334,7 @@ ; TUNIT-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 ; CGSCC-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: bb: @@ -361,7 +361,7 @@ ; This should promote define internal fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #3 { ; -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256 ; CHECK-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: bb: @@ -379,7 +379,7 @@ define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %arg) #4 { ; -; TUNIT: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 ; TUNIT-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: bb: @@ -393,7 +393,7 @@ ; TUNIT-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 ; CGSCC-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: bb: @@ -421,7 +421,7 @@ ; This should promote define internal fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #4 { ; -; CHECK: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256 ; CHECK-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: bb: @@ -439,7 +439,7 @@ define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %arg) #3 { ; -; TUNIT: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 ; TUNIT-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: bb: @@ -453,7 +453,7 @@ ; TUNIT-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 ; CGSCC-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: bb: @@ -488,19 +488,19 @@ attributes #4 = { inlinehint norecurse nounwind uwtable "target-features"="+avx2" "min-legal-vector-width"="256" "prefer-vector-width"="256" } attributes #5 = { argmemonly nounwind } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "min-legal-vector-width"="512" "prefer-vector-width"="512" "target-features"="+avx512vl" } -; TUNIT: attributes #[[ATTR1]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "min-legal-vector-width"="512" "prefer-vector-width"="256" "target-features"="+avx512vl" } -; TUNIT: attributes #[[ATTR2]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "min-legal-vector-width"="256" "prefer-vector-width"="256" "target-features"="+avx512vl" } -; TUNIT: attributes #[[ATTR3]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "min-legal-vector-width"="512" "prefer-vector-width"="256" "target-features"="+avx2" } -; TUNIT: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR5]] = { willreturn writeonly } +; TUNIT: attributes #[[ATTR0]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "min-legal-vector-width"="512" "prefer-vector-width"="512" "target-features"="+avx512vl" } +; TUNIT: attributes #[[ATTR1]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "min-legal-vector-width"="512" "prefer-vector-width"="256" "target-features"="+avx512vl" } +; TUNIT: attributes #[[ATTR2]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "min-legal-vector-width"="256" "prefer-vector-width"="256" "target-features"="+avx512vl" } +; TUNIT: attributes #[[ATTR3]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "min-legal-vector-width"="512" "prefer-vector-width"="256" "target-features"="+avx2" } +; TUNIT: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR5]] = { willreturn } ; TUNIT: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "min-legal-vector-width"="512" "prefer-vector-width"="512" "target-features"="+avx512vl" } -; CGSCC: attributes #[[ATTR1]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "min-legal-vector-width"="512" "prefer-vector-width"="256" "target-features"="+avx512vl" } -; CGSCC: attributes #[[ATTR2]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "min-legal-vector-width"="256" "prefer-vector-width"="256" "target-features"="+avx512vl" } -; CGSCC: attributes #[[ATTR3]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "min-legal-vector-width"="512" "prefer-vector-width"="256" "target-features"="+avx2" } -; CGSCC: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR5]] = { willreturn writeonly } +; CGSCC: attributes #[[ATTR0]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "min-legal-vector-width"="512" "prefer-vector-width"="512" "target-features"="+avx512vl" } +; CGSCC: attributes #[[ATTR1]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "min-legal-vector-width"="512" "prefer-vector-width"="256" "target-features"="+avx512vl" } +; CGSCC: attributes #[[ATTR2]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "min-legal-vector-width"="256" "prefer-vector-width"="256" "target-features"="+avx512vl" } +; CGSCC: attributes #[[ATTR3]] = { inlinehint nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "min-legal-vector-width"="512" "prefer-vector-width"="256" "target-features"="+avx2" } +; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR5]] = { willreturn } ; CGSCC: attributes #[[ATTR6]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll @@ -9,7 +9,7 @@ ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = constant [[T:%.*]] { i32 0, i32 0, i32 17, i32 25 } ;. define internal i32 @test(%T* %p) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test ; CGSCC-SAME: () #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -26,13 +26,13 @@ define i32 @caller() { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret i32 42 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -44,9 +44,9 @@ ret i32 %v } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll @@ -40,7 +40,7 @@ ; Test2 ; Different alignemnt privatizable arguments define internal i32 @test(i32* %X, i64* %Y) { -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i64 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: [[Y_PRIV:%.*]] = alloca i64, align 8 @@ -69,7 +69,7 @@ } define internal i32 @caller(i32* %A) { -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4 @@ -84,13 +84,13 @@ } define i32 @callercaller() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@callercaller ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: ret i32 3 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@callercaller ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: [[X:%.*]] = call i32 @caller(i32 noundef 2) #[[ATTR4:[0-9]+]] @@ -102,11 +102,11 @@ ret i32 %X } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR3]] = { readonly willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR3]] = { willreturn memory(read) } ; CGSCC: attributes #[[ATTR4]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll @@ -7,7 +7,7 @@ ; Don't drop 'byval' on %X here. define internal i32 @f(%struct.ss* byval(%struct.ss) %b, i32* byval(i32) %X, i32 %i) nounwind { ; -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@f ; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -43,7 +43,7 @@ ; Also make sure we don't drop the call zeroext attribute. define i32 @test(i32* %X) { ; -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@test ; TUNIT-SAME: (i32* nocapture nofree readonly [[X:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -59,7 +59,7 @@ ; TUNIT-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]]) #[[ATTR1:[0-9]+]] ; TUNIT-NEXT: ret i32 [[C]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@test ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -82,10 +82,10 @@ ret i32 %c } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } ; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: readwrite) } ; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll @@ -4,7 +4,7 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define internal i32 @test(i32* %X, i32* %Y) { -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test ; CGSCC-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[Y:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: [[X_PRIV:%.*]] = alloca i32, align 4 @@ -21,7 +21,7 @@ } define internal i32 @caller(i32* %B) { -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[B_PRIV:%.*]] = alloca i32, align 4 @@ -36,13 +36,13 @@ } define i32 @callercaller() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@callercaller ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: ret i32 3 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@callercaller ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: [[X:%.*]] = call i32 @caller(i32 noundef 2) #[[ATTR4:[0-9]+]] @@ -55,11 +55,11 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR3]] = { readonly willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR3]] = { willreturn memory(read) } ; CGSCC: attributes #[[ATTR4]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll @@ -5,7 +5,7 @@ %struct.ss = type { i32, i64 } define internal void @f(%struct.ss* byval(%struct.ss) %b, i32* byval(i32) %X) nounwind { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@f ; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -35,7 +35,7 @@ define i32 @test(i32* %X) { ; -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@test ; TUNIT-SAME: (i32* nocapture nofree readonly [[X:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -51,7 +51,7 @@ ; TUNIT-NEXT: call void @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]]) #[[ATTR1:[0-9]+]] ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@test ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -72,10 +72,10 @@ ret i32 0 } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } ; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: readwrite) } ; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll @@ -7,7 +7,7 @@ %struct.ss = type { i32, i64 } define internal i32 @f(%struct.ss* byval(%struct.ss) %b) nounwind { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@f ; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -32,7 +32,7 @@ define internal i32 @g(%struct.ss* byval(%struct.ss) align 32 %b) nounwind { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@g ; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -57,7 +57,7 @@ define i32 @main() nounwind { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@main ; TUNIT-SAME: () #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -65,20 +65,20 @@ ; TUNIT-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 ; TUNIT-NEXT: store i32 1, i32* [[TMP1]], align 8 ; TUNIT-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; TUNIT-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to i32* -; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST1]], align 8 -; TUNIT-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 1 -; TUNIT-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_12]], align 8 -; TUNIT-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) #[[ATTR2:[0-9]+]] ; TUNIT-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* -; TUNIT-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST]], align 32 +; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 8 ; TUNIT-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 1 -; TUNIT-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_1]], align 32 +; TUNIT-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 8 +; TUNIT-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) #[[ATTR2:[0-9]+]] +; TUNIT-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to i32* +; TUNIT-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align 32 +; TUNIT-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 1 +; TUNIT-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 32 ; TUNIT-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]]) #[[ATTR2]] ; TUNIT-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] ; TUNIT-NEXT: ret i32 [[A]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@main ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -104,11 +104,11 @@ ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll @@ -11,7 +11,7 @@ ;. define internal i32 @test(i32** %x) { ; -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -25,14 +25,14 @@ } define i32 @caller() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[X:%.*]] = call i32 @test() #[[ATTR1:[0-9]+]] ; TUNIT-NEXT: ret i32 [[X]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -45,10 +45,10 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll @@ -4,7 +4,7 @@ ; Don't promote around control flow. define internal i32 @callee(i1 %C, i32* %P) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@callee ; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -27,14 +27,14 @@ } define i32 @foo(i1 %C, i32* %P) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@foo ; TUNIT-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[X:%.*]] = call i32 @callee(i1 [[C]], i32* nocapture nofree readonly [[P]]) #[[ATTR1:[0-9]+]] ; TUNIT-NEXT: ret i32 [[X]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -47,10 +47,10 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind readonly willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR2]] = { readonly willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll @@ -5,7 +5,7 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define internal i32 @callee(i1 %C, i32* %P) { -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@callee ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: [[P_PRIV:%.*]] = alloca i32, align 4 @@ -28,13 +28,13 @@ } define i32 @foo() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@foo ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: ret i32 17 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[X:%.*]] = call i32 @callee(i32 noundef 17) #[[ATTR2:[0-9]+]] @@ -47,9 +47,9 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readonly willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll @@ -7,7 +7,7 @@ ; Inlining should nuke the invoke (and any inlined calls) here even with ; argument promotion running along with it. define void @zot() personality i32 (...)* @wibble { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@zot ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] personality i32 (...)* @wibble { ; TUNIT-NEXT: bb: @@ -18,7 +18,7 @@ ; TUNIT: bb2: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@zot ; CGSCC-SAME: () #[[ATTR0:[0-9]+]] personality i32 (...)* @wibble { ; CGSCC-NEXT: bb: @@ -43,13 +43,13 @@ } define internal void @hoge() { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@hoge ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: bb: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@hoge ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: bb: @@ -62,7 +62,7 @@ } define internal fastcc i8* @spam(i1 (i8*)* %arg) { -; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@spam ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: bb: @@ -85,7 +85,7 @@ } define internal i1 @barney(i8* %arg) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@barney ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: bb: @@ -96,13 +96,13 @@ } define i32 @test_inf_promote_caller(i32 %arg) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test_inf_promote_caller ; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: bb: ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_inf_promote_caller ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: bb: @@ -119,7 +119,7 @@ } define internal i32 @test_inf_promote_callee(%S* %arg, %S* %arg1) { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_inf_promote_callee ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: bb: @@ -137,13 +137,13 @@ declare i32 @wibble(...) ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { noreturn nounwind readnone } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { noreturn nounwind } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR4]] = { noreturn nounwind readnone } +; CGSCC: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR4]] = { noreturn nounwind } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll @@ -19,13 +19,13 @@ ;. define void @run() { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@run ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@run ; CGSCC-SAME: () #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -40,7 +40,7 @@ } define internal i8 @UseLongDoubleUnsafely(%union.u* byval(%union.u) align 16 %arg) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@UseLongDoubleUnsafely ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -54,7 +54,7 @@ } define internal x86_fp80 @UseLongDoubleSafely(%union.u* byval(%union.u) align 16 %arg) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@UseLongDoubleSafely ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: ret x86_fp80 undef @@ -65,7 +65,7 @@ } define internal i64 @AccessPaddingOfStruct(%struct.Foo* byval(%struct.Foo) %a) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@AccessPaddingOfStruct ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: ret i64 undef @@ -76,7 +76,7 @@ } define internal i64 @CaptureAStruct(%struct.Foo* byval(%struct.Foo) %a) { -; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@CaptureAStruct ; CGSCC-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -104,9 +104,9 @@ br label %loop } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind memory(none) } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll @@ -8,7 +8,7 @@ ; Argpromote + sroa should change this to passing the two integers by value. define internal i32 @f(%struct.ss* inalloca(%struct.ss) %s) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@f ; CHECK-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull inalloca([[STRUCT_SS:%.*]]) align 4 dereferenceable(8) [[S:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -29,7 +29,7 @@ } define i32 @main() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@main ; TUNIT-SAME: () #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -41,7 +41,7 @@ ; TUNIT-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull inalloca([[STRUCT_SS]]) align 4 dereferenceable(8) [[S]]) #[[ATTR2:[0-9]+]] ; TUNIT-NEXT: ret i32 [[R]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@main ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -65,7 +65,7 @@ ; Argpromote can't promote %a because of the icmp use. define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca(%struct.ss) %b) nounwind { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@g ; CGSCC-SAME: (%struct.ss* noalias nocapture nofree nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* noalias nocapture nofree nonnull writeonly inalloca([[STRUCT_SS:%.*]]) align 4 dereferenceable(8) [[B:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -77,13 +77,13 @@ } define i32 @test() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -95,12 +95,12 @@ ret i32 0 } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind readonly willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR3]] = { readonly willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR3]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll @@ -21,7 +21,7 @@ } define i32 @b() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@b ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -33,7 +33,7 @@ } define i32 @c() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@c ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -46,5 +46,5 @@ ret i32 %result } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll @@ -13,7 +13,7 @@ } define internal i32 @test(i32* %X, i32* %Y) { -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@test ; CGSCC-SAME: (i32* noalias nocapture nofree noundef writeonly align 4 [[X:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] @@ -34,7 +34,7 @@ } define internal i32 @caller(i32* %B) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 @@ -48,13 +48,13 @@ } define i32 @callercaller() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@callercaller ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@callercaller ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 @@ -68,11 +68,11 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR4]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR4]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll @@ -13,7 +13,7 @@ } define internal i32 @test(i32* %X, i32* %Y) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@test ; CHECK-SAME: (i32* noalias nocapture nofree noundef writeonly align 4 [[X:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] @@ -34,14 +34,14 @@ } define internal i32 @caller(i32* %B) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@caller ; TUNIT-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR2:[0-9]+]] ; TUNIT-NEXT: ret i32 undef ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 @@ -55,14 +55,14 @@ } define i32 @callercaller() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@callercaller ; TUNIT-SAME: () #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR2]] ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@callercaller ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 @@ -77,12 +77,12 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR3]] = { nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR3]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll @@ -8,7 +8,7 @@ %T = type { i32, i32, i32, i32 } define internal i32 @test(%T* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@test ; CHECK-SAME: (%T* nocapture nofree readonly [[P:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 @@ -27,13 +27,13 @@ } define i32 @caller(%T* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@caller ; TUNIT-SAME: (%T* nocapture nofree readonly [[P:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[V:%.*]] = musttail call i32 @test(%T* nocapture nofree readonly [[P]]) #[[ATTR4:[0-9]+]] ; TUNIT-NEXT: ret i32 [[V]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: (%T* nocapture nofree readonly [[P:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[V:%.*]] = musttail call i32 @test(%T* nocapture nofree readonly [[P]]) #[[ATTR5:[0-9]+]] @@ -46,12 +46,12 @@ ; Don't promote arguments of musttail caller define i32 @foo(%T* %p, i32 %v) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@foo ; TUNIT-SAME: (%T* nocapture nofree readnone [[P:%.*]], i32 [[V:%.*]]) #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (%T* nocapture nofree readnone [[P:%.*]], i32 [[V:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: ret i32 0 @@ -60,7 +60,7 @@ } define internal i32 @test2(%T* %p, i32 %p2) { -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test2 ; CGSCC-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 @@ -68,7 +68,7 @@ ; CGSCC-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 ; CGSCC-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 ; CGSCC-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] -; CGSCC-NEXT: [[CA:%.*]] = musttail call noundef i32 @foo(%T* undef, i32 [[V]]) #[[ATTR6:[0-9]+]] +; CGSCC-NEXT: [[CA:%.*]] = musttail call noundef i32 @foo(%T* undef, i32 [[V]]) #[[ATTR5]] ; CGSCC-NEXT: ret i32 [[CA]] ; %a.gep = getelementptr %T, %T* %p, i64 0, i32 3 @@ -81,12 +81,12 @@ } define i32 @caller2(%T* %g) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller2 ; TUNIT-SAME: (%T* nocapture nofree readnone [[G:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@caller2 ; CGSCC-SAME: (%T* nocapture nofree readonly align 4 [[G:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[V:%.*]] = call noundef i32 @test2(%T* nocapture nofree readonly [[G]], i32 noundef 0) #[[ATTR5]] @@ -101,14 +101,14 @@ ; is kept as well. define i32 @bar(%T* %p, i32 %v) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@bar ; TUNIT-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR2:[0-9]+]] { ; TUNIT-NEXT: [[I32PTR:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 0 ; TUNIT-NEXT: store i32 [[V]], i32* [[I32PTR]], align 4 ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@bar ; CGSCC-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: [[I32PTR:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 0 @@ -121,7 +121,7 @@ } define internal i32 @test2b(%T* %p, i32 %p2) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@test2b ; TUNIT-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) #[[ATTR3:[0-9]+]] { ; TUNIT-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 @@ -129,10 +129,10 @@ ; TUNIT-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 ; TUNIT-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 ; TUNIT-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] -; TUNIT-NEXT: [[CA:%.*]] = musttail call noundef i32 @bar(%T* undef, i32 [[V]]) #[[ATTR5:[0-9]+]] +; TUNIT-NEXT: [[CA:%.*]] = musttail call noundef i32 @bar(%T* undef, i32 [[V]]) #[[ATTR4]] ; TUNIT-NEXT: ret i32 [[CA]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@test2b ; CGSCC-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) #[[ATTR4:[0-9]+]] { ; CGSCC-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 @@ -140,7 +140,7 @@ ; CGSCC-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 ; CGSCC-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 ; CGSCC-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] -; CGSCC-NEXT: [[CA:%.*]] = musttail call noundef i32 @bar(%T* undef, i32 [[V]]) #[[ATTR7:[0-9]+]] +; CGSCC-NEXT: [[CA:%.*]] = musttail call noundef i32 @bar(%T* undef, i32 [[V]]) #[[ATTR6:[0-9]+]] ; CGSCC-NEXT: ret i32 [[CA]] ; %a.gep = getelementptr %T, %T* %p, i64 0, i32 3 @@ -153,37 +153,34 @@ } define i32 @caller2b(%T* %g) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@caller2b ; TUNIT-SAME: (%T* nocapture nofree readonly [[G:%.*]]) #[[ATTR3]] { -; TUNIT-NEXT: [[V:%.*]] = call noundef i32 @test2b(%T* nocapture nofree readonly [[G]], i32 undef) #[[ATTR6:[0-9]+]] +; TUNIT-NEXT: [[V:%.*]] = call noundef i32 @test2b(%T* nocapture nofree readonly [[G]], i32 undef) #[[ATTR4]] ; TUNIT-NEXT: ret i32 [[V]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@caller2b ; CGSCC-SAME: (%T* nocapture nofree readonly align 4 [[G:%.*]]) #[[ATTR4]] { -; CGSCC-NEXT: [[V:%.*]] = call noundef i32 @test2b(%T* nocapture nofree readonly [[G]], i32 noundef 0) #[[ATTR8:[0-9]+]] +; CGSCC-NEXT: [[V:%.*]] = call noundef i32 @test2b(%T* nocapture nofree readonly [[G]], i32 noundef 0) #[[ATTR7:[0-9]+]] ; CGSCC-NEXT: ret i32 [[V]] ; %v = call i32 @test2b(%T* %g, i32 0) ret i32 %v } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR5]] = { readonly willreturn } -; CGSCC: attributes #[[ATTR6]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR7]] = { nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR8]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR5]] = { willreturn } +; CGSCC: attributes #[[ATTR6]] = { nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR7]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll @@ -12,7 +12,7 @@ %fun_t = type void (%p_t)* define void @foo() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@foo ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[TMP:%.*]] = alloca void (i16*)*, align 8 @@ -24,7 +24,7 @@ } define internal void @bar(%p_t %p) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@bar ; CGSCC-SAME: (i16* nocapture nofree readnone [[P:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: call void @llvm.dbg.value(metadata i16* [[P]], metadata [[META3:![0-9]+]], metadata !DIExpression()) #[[ATTR2:[0-9]+]], !dbg [[DBG5:![0-9]+]] @@ -47,12 +47,12 @@ !5 = !DIExpression() !6 = !DILocation(line: 1, column: 1, scope: !3) ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } -; CGSCC: attributes #[[ATTR2]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. ; TUNIT: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug) ; TUNIT: [[META1:![0-9]+]] = !DIFile(filename: "test.c", directory: "") Index: llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll @@ -7,13 +7,13 @@ define internal void @add({i32, i32}* %this, i32* sret(i32) %r) { ; -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@add ; TUNIT-SAME: ({ i32, i32 }* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: store i32 undef, i32* [[R]], align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@add ; CGSCC-SAME: ({ i32, i32 }* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 @@ -34,14 +34,14 @@ } define void @f() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@f ; TUNIT-SAME: () #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: [[R:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) undef, i32* noalias nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R]]) #[[ATTR2:[0-9]+]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@f ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[R:%.*]] = alloca i32, align 4 @@ -56,11 +56,11 @@ ret void } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll @@ -45,7 +45,7 @@ } define internal i32 @vfu2(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nounwind readonly { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@vfu2 ; CHECK-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: @@ -86,7 +86,7 @@ ; TUNIT-NEXT: [[TMP2:%.*]] = load i8, i8* [[MYSTR_CAST1]], align 8 ; TUNIT-NEXT: [[MYSTR_0_12:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i64 0, i32 1 ; TUNIT-NEXT: [[TMP3:%.*]] = load i32, i32* [[MYSTR_0_12]], align 8 -; TUNIT-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP2]], i32 [[TMP3]]) #[[ATTR2:[0-9]+]] +; TUNIT-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP2]], i32 [[TMP3]]) #[[ATTR0]] ; TUNIT-NEXT: ret i32 [[RESULT]] ; ; CGSCC: Function Attrs: nounwind @@ -110,7 +110,7 @@ } define internal i32 @vfu2_v2(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nounwind readonly { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@vfu2_v2 ; CHECK-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: @@ -155,7 +155,7 @@ ; TUNIT-NEXT: [[TMP2:%.*]] = load i8, i8* [[MYSTR_CAST1]], align 8 ; TUNIT-NEXT: [[MYSTR_0_12:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i64 0, i32 1 ; TUNIT-NEXT: [[TMP3:%.*]] = load i32, i32* [[MYSTR_0_12]], align 8 -; TUNIT-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP2]], i32 [[TMP3]]) #[[ATTR2]] +; TUNIT-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP2]], i32 [[TMP3]]) #[[ATTR0]] ; TUNIT-NEXT: ret i32 [[RESULT]] ; ; CGSCC: Function Attrs: nounwind @@ -172,10 +172,6 @@ ret i32 %result } ;. -; TUNIT: attributes #[[ATTR0]] = { nounwind } -; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR2]] = { nounwind readonly } -;. -; CGSCC: attributes #[[ATTR0]] = { nounwind } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; CHECK: attributes #[[ATTR0]] = { nounwind } +; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll @@ -7,13 +7,13 @@ define i64 @fn2() { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@fn2 ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret i64 undef ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@fn2 ; CGSCC-SAME: () #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -31,7 +31,7 @@ define i64 @fn2b(i32 %arg) { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@fn2b ; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -39,7 +39,7 @@ ; TUNIT-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]] ; TUNIT-NEXT: ret i64 [[DIV]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@fn2b ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: @@ -56,13 +56,13 @@ } define i64 @fn2c() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@fn2c ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret i64 42 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@fn2c ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: entry: @@ -79,7 +79,7 @@ } define internal i64 @fn1(i64 %p1) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@fn1 ; CGSCC-SAME: (i64 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -91,9 +91,9 @@ ret i64 %cond } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll @@ -6,7 +6,7 @@ define void @fn2(i32* %P, i1 %C) { ; -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@fn2 ; TUNIT-SAME: (i32* nocapture nofree [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -21,7 +21,7 @@ ; TUNIT: exit: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@fn2 ; CGSCC-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -54,7 +54,7 @@ } define internal i32 @fn1(i32 %p1) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@fn1 ; CGSCC-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -116,7 +116,7 @@ } define internal i32 @fn0(i32 %p1) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@fn0 ; CGSCC-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -128,10 +128,10 @@ ret i32 %cond } ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind memory(argmem: readwrite) } ; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind null_pointer_is_valid } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll @@ -8,7 +8,7 @@ declare dso_local fastcc float @bar(%struct.wobble* noalias, <8 x i32>) unnamed_addr define %struct.zot @widget(<8 x i32> %arg) local_unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@widget ; CHECK-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: bb: @@ -19,14 +19,14 @@ } define void @baz(<8 x i32> %arg) local_unnamed_addr { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@baz ; TUNIT-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr #[[ATTR0]] { ; TUNIT-NEXT: bb: ; TUNIT-NEXT: [[TMP1:%.*]] = extractvalue [[STRUCT_ZOT:%.*]] undef, 0, 0 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@baz ; CGSCC-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: bb: @@ -38,8 +38,8 @@ ret void } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll @@ -40,7 +40,7 @@ ; TUNIT-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16)*)(i16 [[A]]) ; TUNIT-NEXT: ret i16 [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (i16 [[A:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16)*)(i16 [[A]]) @@ -51,7 +51,7 @@ } define internal i16 @bar(i16 %p1, i16 %p2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bar ; CHECK-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: ret i16 0 @@ -66,7 +66,7 @@ ; TUNIT-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar2 to i16 (i16)*)(i16 [[A]]) ; TUNIT-NEXT: ret i16 [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind ; CGSCC-LABEL: define {{[^@]+}}@foo2 ; CGSCC-SAME: (i16 [[A:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar2 to i16 (i16)*)(i16 [[A]]) @@ -77,7 +77,7 @@ } define internal i16 @bar2(i16 %p1, i16 %p2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bar2 ; CHECK-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]] @@ -101,7 +101,7 @@ ; TUNIT-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]] ; TUNIT-NEXT: ret i16 [[ADD]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind ; CGSCC-LABEL: define {{[^@]+}}@vararg_tests ; CGSCC-SAME: (i16 [[A:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: [[CALL1:%.*]] = call i16 (i16, ...) @vararg_prop(i16 noundef 7, i16 noundef 8, i16 [[A]]) #[[ATTR2:[0-9]+]] @@ -116,7 +116,7 @@ } define internal i16 @vararg_prop(i16 %p1, ...) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@vararg_prop ; CGSCC-SAME: (i16 [[P1:%.*]], ...) #[[ATTR1]] { ; CGSCC-NEXT: ret i16 7 @@ -125,7 +125,7 @@ } define internal i16 @vararg_no_prop(i16 %p1, i16 %p2, ...) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@vararg_no_prop ; CHECK-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR1]] { ; CHECK-NEXT: ret i16 7 @@ -135,9 +135,9 @@ ;. ; TUNIT: attributes #[[ATTR0]] = { norecurse } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readnone } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll @@ -12,7 +12,7 @@ ; TUNIT-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16, i32)*)(i16 [[A]], i32 7) ; TUNIT-NEXT: ret i16 [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (i16 [[A:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16, i32)*)(i16 [[A]], i32 7) @@ -23,7 +23,7 @@ } define internal i16 @bar(i16 %p1, i16 %p2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bar ; CHECK-SAME: (i16 [[P1:%.*]], i16 returned [[P2:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: ret i16 [[P2]] @@ -34,8 +34,8 @@ ;. ; TUNIT: attributes #[[ATTR0]] = { norecurse } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readnone } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll @@ -5,7 +5,7 @@ ; See PR26774 define i32 @baz() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@baz ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret i32 10 @@ -45,8 +45,8 @@ ret i32 %val } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; TUNIT: attributes #[[ATTR1]] = { norecurse } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll @@ -17,7 +17,7 @@ ; CGSCC: @[[BAR_L:[a-zA-Z0-9_$"\\.-]+]] = internal constant [2 x i8*] [i8* blockaddress(@bar, [[LAB0:%.*]]), i8* blockaddress(@bar, [[END:%.*]])] ;. define internal void @foo(i32 %x) nounwind readnone { -; CGSCC: Function Attrs: nounwind readnone +; CGSCC: Function Attrs: nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -32,7 +32,7 @@ } define internal void @bar(i32* nocapture %pc) nounwind readonly { -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@bar ; CGSCC-SAME: (i32* nocapture [[PC:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -70,13 +70,13 @@ } define i32 @main() nounwind readnone { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@main ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@main ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -86,9 +86,9 @@ ret i32 0 } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nounwind readnone } -; CGSCC: attributes #[[ATTR1]] = { nounwind readonly } -; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nounwind memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nounwind memory(read) } +; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll @@ -12,7 +12,7 @@ } define void @bar() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bar ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret void @@ -20,5 +20,5 @@ ret void } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll @@ -5,7 +5,7 @@ target triple = "powerpc64le-unknown-linux" define void @test(i32 signext %n) { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@test ; CHECK-SAME: (i32 signext [[N:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -79,5 +79,5 @@ } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind memory(none) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/global.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/global.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/global.ll @@ -8,7 +8,7 @@ ; CHECK: @[[_ZL6TEST1G:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 42, align 4 ;. define void @_Z7test1f1v() nounwind { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@_Z7test1f1v ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -32,7 +32,7 @@ } define i32 @_Z7test1f2v() nounwind { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@_Z7test1f2v ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -43,5 +43,5 @@ ret i32 %tmp } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll @@ -38,7 +38,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" define internal i32 @cb0(i32 %zero) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@cb0 ; CHECK-SAME: (i32 [[ZERO:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -49,7 +49,7 @@ } define internal i32 @cb1(i32 %unknown) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@cb1 ; CHECK-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -60,13 +60,13 @@ } define internal i32 @cb2(i32 %unknown) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@cb2 ; TUNIT-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret i32 [[UNKNOWN]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@cb2 ; CGSCC-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -78,7 +78,7 @@ } define internal i32 @cb3(i32 %unknown) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@cb3 ; CHECK-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -89,7 +89,7 @@ } define internal i32 @cb4(i32 %unknown) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@cb4 ; CHECK-SAME: (i32 noundef [[UNKNOWN:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -125,10 +125,10 @@ !2 = !{i64 2, i64 3, i1 false} !3 = !{!0, !2, !1} ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } ;. ; CHECK: [[META0:![0-9]+]] = !{!1, !2, !3} ; CHECK: [[META1:![0-9]+]] = !{i64 0, i64 3, i1 false} Index: llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll @@ -78,7 +78,7 @@ } define internal i8* @no_side_effects(i8 %v) readonly nounwind { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@no_side_effects ; CGSCC-SAME: (i8 [[V:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: ret i8* null @@ -96,5 +96,5 @@ ret i8* null } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll @@ -68,7 +68,7 @@ declare !callback !0 dso_local i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) define internal i8* @foo(i8* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@foo ; CHECK-SAME: (i8* noalias nocapture nofree readnone align 4294967296 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -79,7 +79,7 @@ } define internal i8* @bar(i8* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bar ; CHECK-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -90,7 +90,7 @@ } define internal i8* @baz(i8* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@baz ; CHECK-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -101,7 +101,7 @@ } define internal i8* @buz(i8* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@buz ; CHECK-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -114,7 +114,7 @@ !1 = !{i64 2, i64 3, i1 false} !0 = !{!1} ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. ; CHECK: [[META0:![0-9]+]] = !{!1} ; CHECK: [[META1:![0-9]+]] = !{i64 2, i64 3, i1 false} Index: llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll @@ -5,7 +5,7 @@ ; CHECK-NOT: %X define internal i32 @foo(i32 %X) { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: () #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: ret i32 undef @@ -16,12 +16,12 @@ } define void @bar() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@bar ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@bar ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: ret void @@ -31,7 +31,7 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll @@ -9,13 +9,13 @@ ; FIXME: Remove obsolete calls/instructions define i32 @main() noreturn nounwind { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@main ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret i32 123 ; -; CGSCC: Function Attrs: nofree noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@main ; CGSCC-SAME: () #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -28,7 +28,7 @@ } define internal i32 @wwrite(i64 %i) nounwind readnone { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@wwrite ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -54,9 +54,9 @@ ret i32 0 } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll @@ -4,7 +4,7 @@ ;; This function returns its second argument on all return statements define internal i32* @incdec(i1 %C, i32* %V) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@incdec ; TUNIT-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull returned writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -13,7 +13,7 @@ ; TUNIT: F: ; TUNIT-NEXT: ret i32* [[V]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@incdec ; CGSCC-SAME: (i1 [[C:%.*]], i32* nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4 @@ -44,7 +44,7 @@ ;; This function returns its first argument as a part of a multiple return ;; value define internal { i32, i32 } @foo(i32 %A, i32 %B) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[X:%.*]] = add i32 [[A]], [[B]] @@ -59,7 +59,7 @@ } define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { ; TUNIT-NEXT: [[Q:%.*]] = alloca i32, align 4 @@ -79,7 +79,7 @@ ; CGSCC-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[Q]]) #[[ATTR3:[0-9]+]] ; CGSCC-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR4:[0-9]+]] ; CGSCC-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 -; CGSCC-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR5:[0-9]+]] +; CGSCC-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR3]] ; CGSCC-NEXT: br label [[OK:%.*]] ; CGSCC: OK: ; CGSCC-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0 @@ -118,14 +118,13 @@ declare i32 @__gxx_personality_v0(...) ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn } ; CGSCC: attributes #[[ATTR3]] = { nounwind willreturn } -; CGSCC: attributes #[[ATTR4]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR5]] = { nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR4]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll @@ -5,7 +5,7 @@ ; FIXME: icmp folding is missing define i1 @invokecaller(i1 %C) personality i32 (...)* @__gxx_personality_v0 { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@invokecaller ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { ; TUNIT-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]]) #[[ATTR1:[0-9]+]] @@ -15,7 +15,7 @@ ; TUNIT: FAIL: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@invokecaller ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { ; CGSCC-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]]) #[[ATTR2:[0-9]+]] @@ -37,7 +37,7 @@ } define internal i32 @foo(i1 %C) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@foo ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -46,7 +46,7 @@ ; TUNIT: F: ; TUNIT-NEXT: ret i32 undef ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -65,12 +65,12 @@ } define i1 @caller(i1 %C) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]]) #[[ATTR3:[0-9]+]] @@ -84,11 +84,11 @@ declare i32 @__gxx_personality_v0(...) ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nounwind readnone } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nounwind } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR3]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR3]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll @@ -7,7 +7,7 @@ %0 = type { i32, i32 } define internal %0 @foo(i1 %Q) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@foo ; CHECK-SAME: (i1 [[Q:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]] @@ -34,7 +34,7 @@ } define internal %0 @bar(i1 %Q) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bar ; CHECK-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[A:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0 @@ -59,13 +59,13 @@ } define %0 @caller(i1 %Q) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller ; TUNIT-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1:[0-9]+]] ; TUNIT-NEXT: ret [[TMP0]] [[X]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: (i1 [[Q:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR2:[0-9]+]] @@ -84,7 +84,7 @@ ; Similar to @caller but the result of both calls are actually used. define i32 @caller2(i1 %Q) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller2 ; TUNIT-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1]] @@ -98,7 +98,7 @@ ; TUNIT-NEXT: [[R:%.*]] = add i32 [[N]], [[M]] ; TUNIT-NEXT: ret i32 [[R]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller2 ; CGSCC-SAME: (i1 [[Q:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR2]] @@ -125,10 +125,10 @@ ret i32 %R } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll @@ -3,7 +3,7 @@ ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC define internal i32 @testf(i1 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@testf ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -29,7 +29,7 @@ } define internal i32 @test1(i1 %c) { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test1 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -59,12 +59,12 @@ } define i32 @main(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@main ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: ret i32 99 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@main ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[RES:%.*]] = call noundef i32 @test1(i1 [[C]]) #[[ATTR2]] @@ -74,9 +74,9 @@ ret i32 %res } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll @@ -26,7 +26,7 @@ ; CHECK: @[[GSH:[a-zA-Z0-9_$"\\.-]+]] = dso_local global i32 0, align 4 ;. define internal i32 @callee(i32* %thread_local_ptr, i32* %shared_ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; CHECK-LABEL: define {{[^@]+}}@callee ; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[THREAD_LOCAL_PTR:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[SHARED_PTR:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -63,7 +63,7 @@ !1 = !{i64 1, i64 0, i64 2, i1 false} !0 = !{!1} ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readonly willreturn } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(read) } ;. ; CHECK: [[META0:![0-9]+]] = !{!1} ; CHECK: [[META1:![0-9]+]] = !{i64 1, i64 0, i64 2, i1 false} Index: llvm/test/Transforms/Attributor/align.ll =================================================================== --- llvm/test/Transforms/Attributor/align.ll +++ llvm/test/Transforms/Attributor/align.ll @@ -17,7 +17,7 @@ ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = global i8 0, align 32 ;. define i32* @test1(i32* align 8 %0) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@test1 ; CHECK-SAME: (i32* nofree readnone returned align 8 "no-capture-maybe-returned" [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret i32* [[TMP0]] @@ -27,7 +27,7 @@ ; TEST 2 define i32* @test2(i32* %0) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@test2 ; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[TMP0:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret i32* [[TMP0]] @@ -37,7 +37,7 @@ ; TEST 3 define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@test3 ; CHECK-SAME: (i32* nofree readnone align 8 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 4 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]] @@ -49,7 +49,7 @@ ; TEST 4 define i32* @test4(i32* align 32 %0, i32* align 32 %1, i1 %2) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@test4 ; CHECK-SAME: (i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]] @@ -85,12 +85,12 @@ ; TEST 6 ; SCC define i32* @test6_1() #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@test6_1 ; TUNIT-SAME: () #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: ret i32* undef ; -; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@test6_1 ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: ret i32* undef @@ -100,12 +100,12 @@ } define i32* @test6_2() #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@test6_2 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i32* undef ; -; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@test6_2 ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: ret i32* undef @@ -134,7 +134,7 @@ ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@f1 ; CHECK-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: br label [[TMP3:%.*]] @@ -192,7 +192,7 @@ ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 { -; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@f3 ; CGSCC-SAME: () local_unnamed_addr #[[ATTR0]] { ; CGSCC-NEXT: br label [[TMP2:%.*]] @@ -216,13 +216,13 @@ ; TEST 7 ; Better than IR information define align 4 i8* @test7() #0 { -; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@test7 ; TUNIT-SAME: () #[[ATTR0]] { -; TUNIT-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) #[[ATTR9:[0-9]+]] +; TUNIT-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) #[[ATTR11:[0-9]+]] ; TUNIT-NEXT: ret i8* [[C]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@test7 ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: [[C:%.*]] = tail call noundef nonnull align 8 dereferenceable(1) i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) @a1) #[[ATTR13:[0-9]+]] @@ -235,7 +235,7 @@ ; TEST 7b ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 { -; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@f1b ; CGSCC-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { ; CGSCC-NEXT: br label [[TMP3:%.*]] @@ -296,7 +296,7 @@ ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 { ; -; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@f3b ; CGSCC-SAME: () local_unnamed_addr #[[ATTR0]] { ; CGSCC-NEXT: br label [[TMP2:%.*]] @@ -318,12 +318,12 @@ } define align 4 i32* @test7b(i32* align 32 %p) #0 { -; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@test7b ; TUNIT-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: ret i32* [[P]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@test7b ; CGSCC-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: ret i32* [[P]] @@ -525,14 +525,14 @@ define i64 @test11(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@test11 ; TUNIT-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR4:[0-9]+]] { ; TUNIT-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* ; TUNIT-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8 ; TUNIT-NEXT: ret i64 [[RET]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test11 ; CGSCC-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR5:[0-9]+]] { ; CGSCC-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* @@ -549,7 +549,7 @@ ; FXIME: %p should have nonnull define i64 @test12-1(i32* align 4 %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@test12-1 ; TUNIT-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* @@ -558,7 +558,7 @@ ; TUNIT-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16 ; TUNIT-NEXT: ret i64 [[RET]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test12-1 ; CGSCC-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* @@ -575,7 +575,7 @@ } define i64 @test12-2(i32* align 4 %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@test12-2 ; TUNIT-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* @@ -583,7 +583,7 @@ ; TUNIT-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16 ; TUNIT-NEXT: ret i64 [[RET]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test12-2 ; CGSCC-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* @@ -599,7 +599,7 @@ ; FXIME: %p should have nonnull define void @test12-3(i32* align 4 %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@test12-3 ; TUNIT-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR5:[0-9]+]] { ; TUNIT-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* @@ -608,7 +608,7 @@ ; TUNIT-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@test12-3 ; CGSCC-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] { ; CGSCC-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* @@ -625,7 +625,7 @@ } define void @test12-4(i32* align 4 %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@test12-4 ; TUNIT-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] { ; TUNIT-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* @@ -633,7 +633,7 @@ ; TUNIT-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@test12-4 ; CGSCC-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR6]] { ; CGSCC-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* @@ -699,7 +699,7 @@ } define void @test13(i1 %c, i32* align 32 %dst) #0 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable ; TUNIT-LABEL: define {{[^@]+}}@test13 ; TUNIT-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR7:[0-9]+]] { ; TUNIT-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] @@ -712,7 +712,7 @@ ; TUNIT-NEXT: store i32 0, i32* [[PTR]], align 32 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable ; CGSCC-LABEL: define {{[^@]+}}@test13 ; CGSCC-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] { ; CGSCC-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] @@ -737,7 +737,7 @@ } define void @test13-1(i1 %c, i32* align 32 %dst) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test13-1 ; TUNIT-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] { ; TUNIT-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] @@ -750,7 +750,7 @@ ; TUNIT-NEXT: store i32 0, i32* [[PTR]], align 16 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test13-1 ; CGSCC-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9:[0-9]+]] { ; CGSCC-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] @@ -775,7 +775,7 @@ } define void @test13-2(i1 %c, i32* align 32 %dst) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test13-2 ; TUNIT-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] @@ -788,7 +788,7 @@ ; TUNIT-NEXT: store i32 0, i32* [[PTR]], align 32 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test13-2 ; CGSCC-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] @@ -813,7 +813,7 @@ } define void @test13-3(i1 %c, i32* align 32 %dst) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test13-3 ; TUNIT-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] @@ -826,7 +826,7 @@ ; TUNIT-NEXT: store i32 0, i32* [[PTR]], align 32 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test13-3 ; CGSCC-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] @@ -852,13 +852,13 @@ ; Don't crash on ptr2int/int2ptr uses. define i64 @ptr2int(i32* %p) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ptr2int -; TUNIT-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9]] { +; TUNIT-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9:[0-9]+]] { ; TUNIT-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 ; TUNIT-NEXT: ret i64 [[P2I]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ptr2int ; CGSCC-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR10:[0-9]+]] { ; CGSCC-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 @@ -868,13 +868,13 @@ ret i64 %p2i } define i64* @int2ptr(i64 %i) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@int2ptr ; TUNIT-SAME: (i64 [[I:%.*]]) #[[ATTR9]] { ; TUNIT-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* ; TUNIT-NEXT: ret i64* [[I2P]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@int2ptr ; CGSCC-SAME: (i64 [[I:%.*]]) #[[ATTR10]] { ; CGSCC-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* @@ -886,13 +886,13 @@ ; Use the store alignment only for the pointer operand. define void @aligned_store(i8* %Value, i8** %Ptr) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@aligned_store ; TUNIT-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR5]] { ; TUNIT-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@aligned_store ; CGSCC-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR6]] { ; CGSCC-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 @@ -916,14 +916,14 @@ } define void @align_store_after_bc(i32* align 2048 %arg) { ; -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@align_store_after_bc ; TUNIT-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR5]] { ; TUNIT-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* ; TUNIT-NEXT: store i8 0, i8* [[BC]], align 2048 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@align_store_after_bc ; CGSCC-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR6]] { ; CGSCC-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* @@ -939,13 +939,13 @@ ; we cannot also put on the caller. @cnd = external global i1 define i32 @musttail_callee_1(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@musttail_callee_1 ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 ; TUNIT-NEXT: ret i32 [[V]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@musttail_callee_1 ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 @@ -955,24 +955,24 @@ ret i32 %v } define i32 @musttail_caller_1(i32* %p) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@musttail_caller_1 ; TUNIT-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR10:[0-9]+]] { ; TUNIT-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 ; TUNIT-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] ; TUNIT: mt: -; TUNIT-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree readonly [[P]]) #[[ATTR11:[0-9]+]] +; TUNIT-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree readonly [[P]]) #[[ATTR12:[0-9]+]] ; TUNIT-NEXT: ret i32 [[V]] ; TUNIT: exit: ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@musttail_caller_1 ; CGSCC-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR11:[0-9]+]] { ; CGSCC-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 ; CGSCC-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] ; CGSCC: mt: -; CGSCC-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR14:[0-9]+]] +; CGSCC-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR13]] ; CGSCC-NEXT: ret i32 [[V]] ; CGSCC: exit: ; CGSCC-NEXT: ret i32 0 @@ -1051,7 +1051,7 @@ @G = global i8 0, align 32 define internal i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2) norecurse { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@aligned_8_return ; TUNIT-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i8*, align 8 @@ -1068,7 +1068,7 @@ ; TUNIT-NEXT: [[L:%.*]] = load i8*, i8** [[STACK]], align 8 ; TUNIT-NEXT: ret i8* [[L]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@aligned_8_return ; CGSCC-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i8*, align 8 @@ -1101,13 +1101,13 @@ } define i8* @aligned_8_return_caller(i8* align(16) %a, i1 %c1, i1 %c2) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@aligned_8_return_caller ; TUNIT-SAME: (i8* nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] { -; TUNIT-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR12:[0-9]+]] +; TUNIT-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR12]] ; TUNIT-NEXT: ret i8* [[R]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@aligned_8_return_caller ; CGSCC-SAME: (i8* nofree readnone align 16 [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR12:[0-9]+]] { ; CGSCC-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR13]] @@ -1121,33 +1121,32 @@ attributes #1 = { uwtable noinline } attributes #2 = { null_pointer_is_valid } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone willreturn uwtable } +; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR1]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } ; TUNIT: attributes #[[ATTR2]] = { nounwind } ; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind } -; TUNIT: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; TUNIT: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } ; TUNIT: attributes #[[ATTR6]] = { nounwind willreturn } -; TUNIT: attributes #[[ATTR7]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } -; TUNIT: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR7]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable } +; TUNIT: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind willreturn memory(read) } +; TUNIT: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } +; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } ; CGSCC: attributes #[[ATTR1]] = { noinline nounwind uwtable } -; CGSCC: attributes #[[ATTR2]] = { nofree noinline nosync nounwind readnone willreturn uwtable } +; CGSCC: attributes #[[ATTR2]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } ; CGSCC: attributes #[[ATTR3]] = { nounwind } ; CGSCC: attributes #[[ATTR4]] = { nofree nosync nounwind } -; CGSCC: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } ; CGSCC: attributes #[[ATTR7]] = { nounwind willreturn } -; CGSCC: attributes #[[ATTR8]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } -; CGSCC: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR11]] = { nofree nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR12]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR13]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR14]] = { readonly willreturn } +; CGSCC: attributes #[[ATTR8]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable } +; CGSCC: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn memory(read) } +; CGSCC: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR13]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/allow_list.ll =================================================================== --- llvm/test/Transforms/Attributor/allow_list.ll +++ llvm/test/Transforms/Attributor/allow_list.ll @@ -35,7 +35,7 @@ ; CHECK_DISABLED_FUNCTION-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i32 ; CHECK_DISABLED_FUNCTION-NEXT: ret i32 [[TMP2]] ; -; CHECK_ENABLED_FUNCTION: Function Attrs: noinline nounwind readnone uwtable +; CHECK_ENABLED_FUNCTION: Function Attrs: noinline nounwind memory(none) uwtable ; CHECK_ENABLED_FUNCTION-LABEL: define {{[^@]+}}@range_test ; CHECK_ENABLED_FUNCTION-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK_ENABLED_FUNCTION-NEXT: ret i32 1 @@ -65,7 +65,7 @@ ; CHECK_DISABLED_FUNCTION-NEXT: [[TMP1:%.*]] = call i32 @range_test(i32 123) ; CHECK_DISABLED_FUNCTION-NEXT: ret i32 [[TMP1]] ; -; CHECK_ENABLED_FUNCTION: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK_ENABLED_FUNCTION: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK_ENABLED_FUNCTION-LABEL: define {{[^@]+}}@range_use1 ; CHECK_ENABLED_FUNCTION-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK_ENABLED_FUNCTION-NEXT: ret i32 1 @@ -112,7 +112,7 @@ ;. ; CHECK_DISABLED_FUNCTION: attributes #[[ATTR0]] = { noinline nounwind uwtable } ;. -; CHECK_ENABLED_FUNCTION: attributes #[[ATTR0]] = { noinline nounwind readnone uwtable } -; CHECK_ENABLED_FUNCTION: attributes #[[ATTR1]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } +; CHECK_ENABLED_FUNCTION: attributes #[[ATTR0]] = { noinline nounwind memory(none) uwtable } +; CHECK_ENABLED_FUNCTION: attributes #[[ATTR1]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } ; CHECK_ENABLED_FUNCTION: attributes #[[ATTR2]] = { noinline nounwind uwtable } ;. Index: llvm/test/Transforms/Attributor/alwaysinline.ll =================================================================== --- llvm/test/Transforms/Attributor/alwaysinline.ll +++ llvm/test/Transforms/Attributor/alwaysinline.ll @@ -8,7 +8,7 @@ ; the function is not exactly defined, and marked alwaysinline and can be inlined, ; so the function can be analyzed define linkonce void @inner1() alwaysinline { -; CHECK: Function Attrs: alwaysinline nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: alwaysinline nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@inner1 ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -19,13 +19,13 @@ } define void @outer1() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@outer1 ; TUNIT-SAME: () #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@outer1 ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -122,12 +122,12 @@ ret i32 %call } ;. -; TUNIT: attributes #[[ATTR0]] = { alwaysinline nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { alwaysinline nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; TUNIT: attributes #[[ATTR2]] = { norecurse } ; TUNIT: attributes #[[ATTR3]] = { alwaysinline } ;. -; CGSCC: attributes #[[ATTR0]] = { alwaysinline nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { alwaysinline nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR2]] = { alwaysinline } ;. Index: llvm/test/Transforms/Attributor/cb_liveness_disabled.ll =================================================================== --- llvm/test/Transforms/Attributor/cb_liveness_disabled.ll +++ llvm/test/Transforms/Attributor/cb_liveness_disabled.ll @@ -192,10 +192,10 @@ ; TUNIT_: !0 = !{i32 0, i32 101} ; TUNIT_: !1 = !{i32 100, i32 201} ;. -; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone sspstrong willreturn uwtable } -; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone sspstrong willreturn uwtable } -; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone sspstrong willreturn uwtable } -; CGSCC: attributes #[[ATTR2:[0-9]+]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind sspstrong willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR2:[0-9]+]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/cb_liveness_enabled.ll =================================================================== --- llvm/test/Transforms/Attributor/cb_liveness_enabled.ll +++ llvm/test/Transforms/Attributor/cb_liveness_enabled.ll @@ -195,10 +195,10 @@ ; TUNIT_: !0 = !{i32 0, i32 101} ; TUNIT_: !1 = !{i32 100, i32 201} ;. -; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone sspstrong willreturn uwtable } -; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone sspstrong willreturn uwtable } -; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone sspstrong willreturn uwtable } -; CGSCC: attributes #[[ATTR2:[0-9]+]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind sspstrong willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR2:[0-9]+]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/cb_range_disabled.ll =================================================================== --- llvm/test/Transforms/Attributor/cb_range_disabled.ll +++ llvm/test/Transforms/Attributor/cb_range_disabled.ll @@ -141,10 +141,10 @@ ret i32 %3 } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2:[0-9]+]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2:[0-9]+]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/cb_range_enabled.ll =================================================================== --- llvm/test/Transforms/Attributor/cb_range_enabled.ll +++ llvm/test/Transforms/Attributor/cb_range_enabled.ll @@ -145,10 +145,10 @@ ret i32 %3 } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2:[0-9]+]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2:[0-9]+]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/depgraph.ll =================================================================== --- llvm/test/Transforms/Attributor/depgraph.ll +++ llvm/test/Transforms/Attributor/depgraph.ll @@ -14,7 +14,7 @@ ; } ; define i32* @checkAndAdvance(i32* align 16 %0) { -; CHECK: Function Attrs: argmemonly nofree nosync nounwind readonly +; CHECK: Function Attrs: nofree nosync nounwind memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@checkAndAdvance ; CHECK-SAME: (i32* nofree noundef nonnull readonly align 16 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP0]], align 16 @@ -380,6 +380,6 @@ ; DOT-DAG: Node[[Node44]] -> Node[[Node43]]; ; DOT-DAG: Node[[Node43]] -> Node[[Node44]]; ;. -; CHECK: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind readonly } -; CHECK: attributes #[[ATTR1]] = { nofree nosync nounwind readonly } +; CHECK: attributes #[[ATTR0]] = { nofree nosync nounwind memory(argmem: read) } +; CHECK: attributes #[[ATTR1]] = { nofree nosync nounwind } ;. Index: llvm/test/Transforms/Attributor/dereferenceable-1.ll =================================================================== --- llvm/test/Transforms/Attributor/dereferenceable-1.ll +++ llvm/test/Transforms/Attributor/dereferenceable-1.ll @@ -12,7 +12,7 @@ ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = global i64 0 ;. define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test1 ; CHECK-SAME: (i32* nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32* @@ -26,7 +26,7 @@ ; TEST 2 define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test2 ; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32* @@ -41,7 +41,7 @@ ; TEST 3 ; GEP inbounds define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test3_1 ; CHECK-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1 @@ -52,7 +52,7 @@ } define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test3_2 ; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4 @@ -63,7 +63,7 @@ } define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 %2) local_unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test3_3 ; CHECK-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[RET1:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1 @@ -81,7 +81,7 @@ ; Better than known in IR. define dereferenceable(4) i32* @test4(i32* dereferenceable(8) %0) local_unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test4 ; CHECK-SAME: (i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: ret i32* [[TMP0]] @@ -284,7 +284,7 @@ ; FIXME: This should have a return dereferenceable(8) but we need to make sure it will work in loops as well. define i32* @test_for_minus_index(i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@test_for_minus_index ; CHECK-SAME: (i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 -2 @@ -297,7 +297,7 @@ } define void @deref_or_null_and_nonnull(i32* dereferenceable_or_null(100) %0) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@deref_or_null_and_nonnull ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(100) [[TMP0:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: store i32 1, i32* [[TMP0]], align 4 @@ -316,7 +316,7 @@ ; FIXME: %ptr should be dereferenceable(31) define void @test8(i8* %ptr) #0 { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@test8 ; CHECK-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(21) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: br label [[TMP1:%.*]] @@ -351,7 +351,7 @@ ; 8.2 (negative case) define void @test8_neg(i32 %i, i8* %ptr) #0 { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@test8_neg ; CHECK-SAME: (i32 [[I:%.*]], i8* nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[I]] to i64 @@ -374,7 +374,7 @@ ; NOTE: %p should not be dereferenceable define internal void @fill_range_not_inbounds(i32* %p, i64 %start){ -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@fill_range_not_inbounds ; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -410,7 +410,7 @@ ; FIXME: %p should be dereferenceable(40) define internal void @fill_range_inbounds(i32* %p, i64 %start){ -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@fill_range_inbounds ; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -445,7 +445,7 @@ } define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@call_fill_range ; TUNIT-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR3:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -454,13 +454,13 @@ ; TUNIT-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@call_fill_range ; CGSCC-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]] -; CGSCC-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6:[0-9]+]] -; CGSCC-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6]] +; CGSCC-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR1]] +; CGSCC-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR1]] ; CGSCC-NEXT: ret void ; entry: @@ -563,7 +563,7 @@ ; ; FIXME: %ptr should be dereferenceable(4) define dso_local void @rec-branch-1(i32 %a, i32 %b, i32 %c, i32* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@rec-branch-1 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -637,32 +637,59 @@ ; } ; FIXME: %ptr should be dereferenceable(4) define dso_local void @rec-branch-2(i32 %a, i32 %b, i32 %c, i32* %ptr) { -; CHECK: Function Attrs: argmemonly nofree nosync nounwind writeonly -; CHECK-LABEL: define {{[^@]+}}@rec-branch-2 -; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR4:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0 -; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]] -; CHECK: if.then: -; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0 -; CHECK-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] -; CHECK: if.then2: -; CHECK-NEXT: store i32 1, i32* [[PTR]], align 4 -; CHECK-NEXT: br label [[IF_END8:%.*]] -; CHECK: if.else: -; CHECK-NEXT: store i32 2, i32* [[PTR]], align 4 -; CHECK-NEXT: br label [[IF_END8]] -; CHECK: if.else3: -; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0 -; CHECK-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] -; CHECK: if.then5: -; CHECK-NEXT: store i32 3, i32* [[PTR]], align 4 -; CHECK-NEXT: br label [[IF_END8]] -; CHECK: if.else6: -; CHECK-NEXT: tail call void @rec-branch-2(i32 noundef 1, i32 noundef 1, i32 noundef 1, i32* nocapture nofree writeonly [[PTR]]) #[[ATTR7:[0-9]+]] -; CHECK-NEXT: br label [[IF_END8]] -; CHECK: if.end8: -; CHECK-NEXT: ret void +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: write) +; TUNIT-LABEL: define {{[^@]+}}@rec-branch-2 +; TUNIT-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR4:[0-9]+]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0 +; TUNIT-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]] +; TUNIT: if.then: +; TUNIT-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0 +; TUNIT-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] +; TUNIT: if.then2: +; TUNIT-NEXT: store i32 1, i32* [[PTR]], align 4 +; TUNIT-NEXT: br label [[IF_END8:%.*]] +; TUNIT: if.else: +; TUNIT-NEXT: store i32 2, i32* [[PTR]], align 4 +; TUNIT-NEXT: br label [[IF_END8]] +; TUNIT: if.else3: +; TUNIT-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0 +; TUNIT-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] +; TUNIT: if.then5: +; TUNIT-NEXT: store i32 3, i32* [[PTR]], align 4 +; TUNIT-NEXT: br label [[IF_END8]] +; TUNIT: if.else6: +; TUNIT-NEXT: tail call void @rec-branch-2(i32 noundef 1, i32 noundef 1, i32 noundef 1, i32* nocapture nofree writeonly [[PTR]]) #[[ATTR7:[0-9]+]] +; TUNIT-NEXT: br label [[IF_END8]] +; TUNIT: if.end8: +; TUNIT-NEXT: ret void +; +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: write) +; CGSCC-LABEL: define {{[^@]+}}@rec-branch-2 +; CGSCC-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR4:[0-9]+]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0 +; CGSCC-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]] +; CGSCC: if.then: +; CGSCC-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0 +; CGSCC-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] +; CGSCC: if.then2: +; CGSCC-NEXT: store i32 1, i32* [[PTR]], align 4 +; CGSCC-NEXT: br label [[IF_END8:%.*]] +; CGSCC: if.else: +; CGSCC-NEXT: store i32 2, i32* [[PTR]], align 4 +; CGSCC-NEXT: br label [[IF_END8]] +; CGSCC: if.else3: +; CGSCC-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0 +; CGSCC-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] +; CGSCC: if.then5: +; CGSCC-NEXT: store i32 3, i32* [[PTR]], align 4 +; CGSCC-NEXT: br label [[IF_END8]] +; CGSCC: if.else6: +; CGSCC-NEXT: tail call void @rec-branch-2(i32 noundef 1, i32 noundef 1, i32 noundef 1, i32* nocapture nofree writeonly [[PTR]]) #[[ATTR6:[0-9]+]] +; CGSCC-NEXT: br label [[IF_END8]] +; CGSCC: if.end8: +; CGSCC-NEXT: ret void ; entry: %tobool = icmp eq i32 %a, 0 @@ -704,11 +731,17 @@ ; ATTRIBUTOR-NEXT: call void @unknown() ; ATTRIBUTOR-NEXT: ret void ; -; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_pos -; CHECK-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]]) { -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8:[0-9]+]] [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ] -; CHECK-NEXT: call void @unknown() -; CHECK-NEXT: ret void +; TUNIT-LABEL: define {{[^@]+}}@nonnull_assume_pos +; TUNIT-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]]) { +; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8:[0-9]+]] [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ] +; TUNIT-NEXT: call void @unknown() +; TUNIT-NEXT: ret void +; +; CGSCC-LABEL: define {{[^@]+}}@nonnull_assume_pos +; CGSCC-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]]) { +; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7:[0-9]+]] [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ] +; CGSCC-NEXT: call void @unknown() +; CGSCC-NEXT: ret void ; call void @llvm.assume(i1 true) [ "nonnull"(i8* %arg3), "dereferenceable"(i8* %arg1, i64 1), "dereferenceable"(i8* %arg1, i64 2), "dereferenceable"(i8* %arg1, i64 101), "dereferenceable_or_null"(i8* %arg2, i64 31), "dereferenceable_or_null"(i8* %arg4, i64 42)] call void @unknown() @@ -750,23 +783,41 @@ ; ATTRIBUTOR-NEXT: call void @unknown() ; ATTRIBUTOR-NEXT: ret void ; -; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_call -; CHECK-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8* [[ARG4:%.*]]) { -; CHECK-NEXT: call void @unknown() -; CHECK-NEXT: [[P:%.*]] = call nonnull dereferenceable(101) i32* @unkown_ptr() #[[ATTR9:[0-9]+]] -; CHECK-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR9]] -; CHECK-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR9]] -; CHECK-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR9]] -; CHECK-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR9]] -; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR9]] -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i32* [[P]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ] -; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR9]] -; CHECK-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR9]] -; CHECK-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR9]] -; CHECK-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR9]] -; CHECK-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR9]] -; CHECK-NEXT: call void @unknown() -; CHECK-NEXT: ret void +; TUNIT-LABEL: define {{[^@]+}}@nonnull_assume_call +; TUNIT-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8* [[ARG4:%.*]]) { +; TUNIT-NEXT: call void @unknown() +; TUNIT-NEXT: [[P:%.*]] = call nonnull dereferenceable(101) i32* @unkown_ptr() #[[ATTR9:[0-9]+]] +; TUNIT-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR9]] +; TUNIT-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR9]] +; TUNIT-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR9]] +; TUNIT-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR9]] +; TUNIT-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR9]] +; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i32* [[P]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ] +; TUNIT-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR9]] +; TUNIT-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR9]] +; TUNIT-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR9]] +; TUNIT-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR9]] +; TUNIT-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR9]] +; TUNIT-NEXT: call void @unknown() +; TUNIT-NEXT: ret void +; +; CGSCC-LABEL: define {{[^@]+}}@nonnull_assume_call +; CGSCC-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8* [[ARG4:%.*]]) { +; CGSCC-NEXT: call void @unknown() +; CGSCC-NEXT: [[P:%.*]] = call nonnull dereferenceable(101) i32* @unkown_ptr() #[[ATTR8:[0-9]+]] +; CGSCC-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR8]] +; CGSCC-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR8]] +; CGSCC-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR8]] +; CGSCC-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR8]] +; CGSCC-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR8]] +; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i32* [[P]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ] +; CGSCC-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR8]] +; CGSCC-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR8]] +; CGSCC-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR8]] +; CGSCC-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR8]] +; CGSCC-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR8]] +; CGSCC-NEXT: call void @unknown() +; CGSCC-NEXT: ret void ; call void @unknown() %p = call i32* @unkown_ptr() @@ -818,27 +869,26 @@ !0 = !{i64 10, i64 100} ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; TUNIT: attributes #[[ATTR1]] = { nounwind willreturn } -; TUNIT: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind writeonly } -; TUNIT: attributes #[[ATTR5:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind memory(argmem: write) } +; TUNIT: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } +; TUNIT: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind } ; TUNIT: attributes #[[ATTR8]] = { willreturn } ; TUNIT: attributes #[[ATTR9]] = { nounwind } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR1]] = { nounwind willreturn } -; CGSCC: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR3]] = { argmemonly nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind writeonly } -; CGSCC: attributes #[[ATTR5:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR6]] = { nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly } -; CGSCC: attributes #[[ATTR8]] = { willreturn } -; CGSCC: attributes #[[ATTR9]] = { nounwind } +; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR4]] = { nofree nosync nounwind memory(argmem: write) } +; CGSCC: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } +; CGSCC: attributes #[[ATTR6]] = { nofree nosync nounwind } +; CGSCC: attributes #[[ATTR7]] = { willreturn } +; CGSCC: attributes #[[ATTR8]] = { nounwind } ;. ; CHECK: [[META0:![0-9]+]] = !{i64 10, i64 100} ;. Index: llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll =================================================================== --- llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll +++ llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll @@ -6,7 +6,7 @@ ; https://bugs.llvm.org/show_bug.cgi?id=21780 define <4 x double> @PR21780(double* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@PR21780 ; CHECK-SAME: (double* nocapture nofree noundef nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 1 @@ -44,7 +44,7 @@ define double @PR21780_only_access3_with_inbounds(double* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@PR21780_only_access3_with_inbounds ; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3 @@ -58,7 +58,7 @@ } define double @PR21780_only_access3_without_inbounds(double* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@PR21780_only_access3_without_inbounds ; CHECK-SAME: (double* nocapture nofree readonly align 8 [[PTR:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3 @@ -71,7 +71,7 @@ } define double @PR21780_without_inbounds(double* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@PR21780_without_inbounds ; CHECK-SAME: (double* nocapture nofree noundef nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3 @@ -94,7 +94,7 @@ ; Unsimplified, but still valid. Also, throw in some bogus arguments. define void @gep0(i8* %unused, i8* %other, i8* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@gep0 ; CHECK-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[OTHER:%.*]], i8* nocapture nofree nonnull readonly dereferenceable(3) [[PTR:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, i8* [[PTR]], i64 2 @@ -116,7 +116,7 @@ ; Multiple arguments may be dereferenceable. define void @ordering(i8* %ptr1, i32* %ptr2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@ordering ; CHECK-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR1:%.*]], i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR2:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: ret void @@ -137,7 +137,7 @@ ; Not in entry block. define void @not_entry_but_guaranteed_to_execute(i8* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@not_entry_but_guaranteed_to_execute ; CHECK-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -160,7 +160,7 @@ ; Not in entry block and not guaranteed to execute. define void @not_entry_not_guaranteed_to_execute(i8* %ptr, i1 %cond) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@not_entry_not_guaranteed_to_execute ; CHECK-SAME: (i8* nocapture nofree readnone [[PTR:%.*]], i1 [[COND:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -187,7 +187,7 @@ ; The last load may not execute, so derefenceable bytes only covers the 1st two loads. define void @partial_in_entry(i16* %ptr, i1 %cond) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@partial_in_entry ; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(4) [[PTR:%.*]], i1 [[COND:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -215,7 +215,7 @@ ; The 2nd and 3rd loads may never execute. define void @volatile_is_not_dereferenceable(i16* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable ; CHECK-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2 @@ -233,7 +233,7 @@ ; TODO: We should allow inference for atomic (but not volatile) ops. define void @atomic_is_alright(i16* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@atomic_is_alright ; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(6) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -268,7 +268,7 @@ ; We must have consecutive accesses. define void @variable_gep_index(i8* %unused, i8* %ptr, i64 %variable_index) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@variable_gep_index ; CHECK-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]], i64 [[VARIABLE_INDEX:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -285,7 +285,7 @@ define void @multi_index_gep(<4 x i8>* %ptr) { ; FIXME: %ptr should be dereferenceable(4) -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@multi_index_gep ; CHECK-SAME: (<4 x i8>* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -298,7 +298,7 @@ ; Could round weird bitwidths down? define void @not_byte_multiple(i9* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@not_byte_multiple ; CHECK-SAME: (i9* nocapture nofree nonnull readnone align 2 dereferenceable(2) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -311,7 +311,7 @@ ; Missing direct access from the pointer. define void @no_pointer_deref(i16* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@no_pointer_deref ; CHECK-SAME: (i16* nocapture nofree readnone align 2 [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -326,7 +326,7 @@ ; Out-of-order is ok, but missing access concludes dereferenceable range. define void @non_consecutive(i32* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@non_consecutive ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -343,7 +343,7 @@ ; Improve on existing dereferenceable attribute. define void @more_bytes(i32* dereferenceable(8) %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@more_bytes ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -362,7 +362,7 @@ ; Improve on existing dereferenceable_or_null attribute. define void @more_bytes_and_not_null(i32* dereferenceable_or_null(8) %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@more_bytes_and_not_null ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -381,7 +381,7 @@ ; But don't pessimize existing dereferenceable attribute. define void @better_bytes(i32* dereferenceable(100) %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@better_bytes ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(100) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -398,7 +398,7 @@ } define void @bitcast(i32* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bitcast ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[ARG:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -412,7 +412,7 @@ } define void @bitcast_different_sizes(double* %arg1, i8* %arg2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bitcast_different_sizes ; CHECK-SAME: (double* nocapture nofree nonnull readnone align 4 dereferenceable(12) [[ARG1:%.*]], i8* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[ARG2:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -434,7 +434,7 @@ } define void @negative_offset(i32* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@negative_offset ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -448,7 +448,7 @@ } define void @stores(i32* %arg) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@stores ; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* @@ -467,7 +467,7 @@ } define void @load_store(i32* %arg) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@load_store ; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* @@ -484,7 +484,7 @@ } define void @different_size1(i32* %arg) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@different_size1 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* @@ -499,7 +499,7 @@ } define void @different_size2(i32* %arg) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@different_size2 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: store i32 0, i32* [[ARG]], align 8 @@ -532,7 +532,7 @@ ; ; ATTRIBUTOR_CGSCC_NPM-LABEL: define i32 @require_cfg_analysis(i32 %c, i32* {{.*}} dereferenceable(4) %p) define i32 @require_cfg_analysis(i32 %c, i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@require_cfg_analysis ; CHECK-SAME: (i32 [[C:%.*]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0 @@ -584,9 +584,9 @@ ret i32 1 } ;. -; CHECK: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CHECK: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR3]] = { argmemonly nofree norecurse nounwind willreturn } -; CHECK: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CHECK: attributes #[[ATTR3]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) } +; CHECK: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } ;. Index: llvm/test/Transforms/Attributor/dereferenceable-2.ll =================================================================== --- llvm/test/Transforms/Attributor/dereferenceable-2.ll +++ llvm/test/Transforms/Attributor/dereferenceable-2.ll @@ -6,7 +6,7 @@ ; https://bugs.llvm.org/show_bug.cgi?id=21780 define <4 x double> @PR21780(double* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@PR21780 ; CHECK-SAME: (double* nocapture nofree noundef nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 1 @@ -44,7 +44,7 @@ define double @PR21780_only_access3_with_inbounds(double* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@PR21780_only_access3_with_inbounds ; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3 @@ -58,7 +58,7 @@ } define double @PR21780_only_access3_without_inbounds(double* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@PR21780_only_access3_without_inbounds ; CHECK-SAME: (double* nocapture nofree readonly align 8 [[PTR:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3 @@ -71,7 +71,7 @@ } define double @PR21780_without_inbounds(double* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@PR21780_without_inbounds ; CHECK-SAME: (double* nocapture nofree noundef nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3 @@ -94,7 +94,7 @@ ; Unsimplified, but still valid. Also, throw in some bogus arguments. define void @gep0(i8* %unused, i8* %other, i8* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@gep0 ; CHECK-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[OTHER:%.*]], i8* nocapture nofree nonnull readonly dereferenceable(3) [[PTR:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, i8* [[PTR]], i64 2 @@ -116,7 +116,7 @@ ; Multiple arguments may be dereferenceable. define void @ordering(i8* %ptr1, i32* %ptr2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@ordering ; CHECK-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR1:%.*]], i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR2:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: ret void @@ -137,7 +137,7 @@ ; Not in entry block. define void @not_entry_but_guaranteed_to_execute(i8* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@not_entry_but_guaranteed_to_execute ; CHECK-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -160,7 +160,7 @@ ; Not in entry block and not guaranteed to execute. define void @not_entry_not_guaranteed_to_execute(i8* %ptr, i1 %cond) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@not_entry_not_guaranteed_to_execute ; CHECK-SAME: (i8* nocapture nofree readnone [[PTR:%.*]], i1 [[COND:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -187,7 +187,7 @@ ; The last load may not execute, so derefenceable bytes only covers the 1st two loads. define void @partial_in_entry(i16* %ptr, i1 %cond) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@partial_in_entry ; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(4) [[PTR:%.*]], i1 [[COND:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -215,7 +215,7 @@ ; The 2nd and 3rd loads may never execute. define void @volatile_is_not_dereferenceable(i16* %ptr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable ; CHECK-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2 @@ -233,7 +233,7 @@ ; TODO: We should allow inference for atomic (but not volatile) ops. define void @atomic_is_alright(i16* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@atomic_is_alright ; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(6) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -268,7 +268,7 @@ ; We must have consecutive accesses. define void @variable_gep_index(i8* %unused, i8* %ptr, i64 %variable_index) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@variable_gep_index ; CHECK-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]], i64 [[VARIABLE_INDEX:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -285,7 +285,7 @@ define void @multi_index_gep(<4 x i8>* %ptr) { ; FIXME: %ptr should be dereferenceable(4) -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@multi_index_gep ; CHECK-SAME: (<4 x i8>* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -298,7 +298,7 @@ ; Could round weird bitwidths down? define void @not_byte_multiple(i9* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@not_byte_multiple ; CHECK-SAME: (i9* nocapture nofree nonnull readnone align 2 dereferenceable(2) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -311,7 +311,7 @@ ; Missing direct access from the pointer. define void @no_pointer_deref(i16* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@no_pointer_deref ; CHECK-SAME: (i16* nocapture nofree readnone align 2 [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -326,7 +326,7 @@ ; Out-of-order is ok, but missing access concludes dereferenceable range. define void @non_consecutive(i32* %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@non_consecutive ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -343,7 +343,7 @@ ; Improve on existing dereferenceable attribute. define void @more_bytes(i32* dereferenceable(8) %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@more_bytes ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -362,7 +362,7 @@ ; Improve on existing dereferenceable_or_null attribute. define void @more_bytes_and_not_null(i32* dereferenceable_or_null(8) %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@more_bytes_and_not_null ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -381,7 +381,7 @@ ; But don't pessimize existing dereferenceable attribute. define void @better_bytes(i32* dereferenceable(100) %ptr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@better_bytes ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(100) [[PTR:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -398,7 +398,7 @@ } define void @bitcast(i32* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bitcast ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[ARG:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -412,7 +412,7 @@ } define void @bitcast_different_sizes(double* %arg1, i8* %arg2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bitcast_different_sizes ; CHECK-SAME: (double* nocapture nofree nonnull readnone align 4 dereferenceable(12) [[ARG1:%.*]], i8* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[ARG2:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -434,7 +434,7 @@ } define void @negative_offset(i32* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@negative_offset ; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret void @@ -448,7 +448,7 @@ } define void @stores(i32* %arg) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@stores ; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* @@ -467,7 +467,7 @@ } define void @load_store(i32* %arg) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@load_store ; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* @@ -484,7 +484,7 @@ } define void @different_size1(i32* %arg) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@different_size1 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* @@ -499,7 +499,7 @@ } define void @different_size2(i32* %arg) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@different_size2 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: store i32 0, i32* [[ARG]], align 8 @@ -532,7 +532,7 @@ ; ; ATTRIBUTOR_CGSCC_NPM-LABEL: define i32 @require_cfg_analysis(i32 %c, i32* {{.*}} dereferenceable(4) %p) define i32 @require_cfg_analysis(i32 %c, i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@require_cfg_analysis ; CHECK-SAME: (i32 [[C:%.*]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0 @@ -584,9 +584,9 @@ ret i32 1 } ;. -; CHECK: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CHECK: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR3]] = { argmemonly nofree norecurse nounwind willreturn } -; CHECK: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CHECK: attributes #[[ATTR3]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) } +; CHECK: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } ;. Index: llvm/test/Transforms/Attributor/heap_to_stack.ll =================================================================== --- llvm/test/Transforms/Attributor/heap_to_stack.ll +++ llvm/test/Transforms/Attributor/heap_to_stack.ll @@ -656,9 +656,9 @@ ; CHECK: attributes #[[ATTR3:[0-9]+]] = { nofree nounwind } ; CHECK: attributes #[[ATTR4]] = { noreturn } ; CHECK: attributes #[[ATTR5:[0-9]+]] = { allockind("free") } -; CHECK: attributes #[[ATTR6:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; CHECK: attributes #[[ATTR7:[0-9]+]] = { allockind("alloc,uninitialized,aligned") allocsize(1) } ; CHECK: attributes #[[ATTR8:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) } -; CHECK: attributes #[[ATTR9:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } +; CHECK: attributes #[[ATTR9:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } ; CHECK: attributes #[[ATTR10]] = { nounwind } ;. Index: llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll =================================================================== --- llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll +++ llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll @@ -662,7 +662,7 @@ ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nofree nosync willreturn } ; CHECK: attributes #[[ATTR2:[0-9]+]] = { nofree nounwind } ; CHECK: attributes #[[ATTR3]] = { noreturn } -; CHECK: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; CHECK: attributes #[[ATTR5]] = { nounwind } ; CHECK: attributes #[[ATTR6]] = { nosync nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/internal-noalias.ll =================================================================== --- llvm/test/Transforms/Attributor/internal-noalias.ll +++ llvm/test/Transforms/Attributor/internal-noalias.ll @@ -3,7 +3,7 @@ ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable ; TUNIT-LABEL: define {{[^@]+}}@visible ; TUNIT-SAME: (i32* noalias nocapture nofree readonly [[A:%.*]], i32* noalias nocapture nofree readonly align 4 [[B:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -12,12 +12,12 @@ ; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; TUNIT-NEXT: ret i32 [[ADD]] ; -; CGSCC: Function Attrs: argmemonly nofree noinline nosync nounwind readonly willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(argmem: read) uwtable ; CGSCC-LABEL: define {{[^@]+}}@visible ; CGSCC-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR5:[0-9]+]] -; CGSCC-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR5]] +; CGSCC-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) +; CGSCC-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) ; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; CGSCC-NEXT: ret i32 [[ADD]] ; @@ -29,7 +29,7 @@ } define private i32 @noalias_args(i32* %A, i32* %B) #0 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable ; TUNIT-LABEL: define {{[^@]+}}@noalias_args ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -40,14 +40,14 @@ ; TUNIT-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] ; TUNIT-NEXT: ret i32 [[ADD2]] ; -; CGSCC: Function Attrs: argmemonly nofree noinline nosync nounwind readonly willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(argmem: read) uwtable ; CGSCC-LABEL: define {{[^@]+}}@noalias_args ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 ; CGSCC-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 ; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] -; CGSCC-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR5]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR5:[0-9]+]] ; CGSCC-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] ; CGSCC-NEXT: ret i32 [[ADD2]] ; @@ -62,7 +62,7 @@ define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable ; TUNIT-LABEL: define {{[^@]+}}@noalias_args_argmem ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -71,7 +71,7 @@ ; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] ; TUNIT-NEXT: ret i32 [[ADD]] ; -; CGSCC: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable ; CGSCC-LABEL: define {{[^@]+}}@noalias_args_argmem ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -88,7 +88,7 @@ } define dso_local i32 @visible_local(i32* %A) #0 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@visible_local ; TUNIT-SAME: (i32* nocapture nofree readonly [[A:%.*]]) #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -99,13 +99,13 @@ ; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; TUNIT-NEXT: ret i32 [[ADD]] ; -; CGSCC: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@visible_local ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 ; CGSCC-NEXT: store i32 5, i32* [[B]], align 4 -; CGSCC-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR5]] +; CGSCC-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) ; CGSCC-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) ; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; CGSCC-NEXT: ret i32 [[ADD]] @@ -120,7 +120,7 @@ } define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 { -; CGSCC: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable ; CGSCC-LABEL: define {{[^@]+}}@noalias_args_argmem_ro ; CGSCC-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[B_PRIV:%.*]] = alloca i32, align 4 @@ -139,13 +139,13 @@ } define i32 @visible_local_2() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@visible_local_2 ; TUNIT-SAME: () #[[ATTR2:[0-9]+]] { ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: ret i32 10 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@visible_local_2 ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32 noundef 5, i32 noundef 5) #[[ATTR6:[0-9]+]] @@ -158,13 +158,13 @@ } define internal i32 @noalias_args_argmem_rn(i32* %A, i32* %B) #1 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@noalias_args_argmem_rn ; TUNIT-SAME: (i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[T0:%.*]] = load i32, i32* [[B]], align 4 ; TUNIT-NEXT: ret i32 [[T0]] ; -; CGSCC: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@noalias_args_argmem_rn ; CGSCC-SAME: (i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR4:[0-9]+]] { ; CGSCC-NEXT: [[T0:%.*]] = load i32, i32* [[B]], align 4 @@ -177,7 +177,7 @@ } define i32 @visible_local_3() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@visible_local_3 ; TUNIT-SAME: () #[[ATTR2]] { ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 @@ -185,7 +185,7 @@ ; TUNIT-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B]]) #[[ATTR4:[0-9]+]] ; TUNIT-NEXT: ret i32 [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@visible_local_3 ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 @@ -202,18 +202,18 @@ attributes #0 = { noinline nounwind uwtable willreturn } attributes #1 = { argmemonly noinline nounwind uwtable willreturn} ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } -; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable } -; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind readonly } +; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable } +; TUNIT: attributes #[[ATTR1]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind } ; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree noinline nosync nounwind readonly willreturn uwtable } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } -; CGSCC: attributes #[[ATTR2]] = { argmemonly nofree noinline nosync nounwind willreturn uwtable } -; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR4]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable } -; CGSCC: attributes #[[ATTR5]] = { readonly } -; CGSCC: attributes #[[ATTR6]] = { readonly willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree noinline nosync nounwind willreturn memory(argmem: read) uwtable } +; CGSCC: attributes #[[ATTR1]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable } +; CGSCC: attributes #[[ATTR2]] = { nofree noinline nosync nounwind willreturn memory(argmem: readwrite) uwtable } +; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR4]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable } +; CGSCC: attributes #[[ATTR5]] = { memory(read) } +; CGSCC: attributes #[[ATTR6]] = { willreturn } ; CGSCC: attributes #[[ATTR7]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/internalize.ll =================================================================== --- llvm/test/Transforms/Attributor/internalize.ll +++ llvm/test/Transforms/Attributor/internalize.ll @@ -135,7 +135,7 @@ ; CHECK_DISABLED-NEXT: call void @unused_arg(i8 noundef 0) ; CHECK_DISABLED-NEXT: ret void ; -; CHECK_ENABLED: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK_ENABLED: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK_ENABLED-LABEL: define {{[^@]+}}@unused_arg_caller ; CHECK_ENABLED-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK_ENABLED-NEXT: unreachable @@ -164,7 +164,7 @@ ;. ; CHECK_DISABLED: attributes #[[ATTR0]] = { norecurse } ;. -; CHECK_ENABLED: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CHECK_ENABLED: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; CHECK_ENABLED: attributes #[[ATTR1]] = { norecurse } -; CHECK_ENABLED: attributes #[[ATTR2:[0-9]+]] = { nounwind readnone } +; CHECK_ENABLED: attributes #[[ATTR2:[0-9]+]] = { nounwind } ;. Index: llvm/test/Transforms/Attributor/liveness.ll =================================================================== --- llvm/test/Transforms/Attributor/liveness.ll +++ llvm/test/Transforms/Attributor/liveness.ll @@ -37,7 +37,7 @@ ; CGSCC: @[[P:[a-zA-Z0-9_$"\\.-]+]] = global i8 0 ;. define internal i32 @dead_internal_func(i32 %0) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@dead_internal_func ; CGSCC-SAME: () #[[ATTR6:[0-9]+]] { ; CGSCC-NEXT: br label [[TMP2:%.*]] @@ -68,13 +68,13 @@ } define i32 @volatile_load(i32*) norecurse nounwind uwtable { -; TUNIT: Function Attrs: argmemonly nofree norecurse nounwind willreturn uwtable +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@volatile_load ; TUNIT-SAME: (i32* nofree noundef align 4 [[TMP0:%.*]]) #[[ATTR6:[0-9]+]] { ; TUNIT-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4 ; TUNIT-NEXT: ret i32 [[TMP2]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nounwind willreturn uwtable +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@volatile_load ; CGSCC-SAME: (i32* nofree noundef align 4 [[TMP0:%.*]]) #[[ATTR7:[0-9]+]] { ; CGSCC-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4 @@ -85,7 +85,7 @@ } define internal i32 @internal_load(i32*) norecurse nounwind uwtable { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@internal_load ; CGSCC-SAME: () #[[ATTR8:[0-9]+]] { ; CGSCC-NEXT: ret i32 undef @@ -498,7 +498,7 @@ ; FIXME: Should be able to detect undefined behavior. define void @ub(i32* %0) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@ub ; TUNIT-SAME: (i32* nocapture nofree writeonly [[TMP0:%.*]]) #[[ATTR7:[0-9]+]] { ; TUNIT-NEXT: [[POISON:%.*]] = sub nuw i32 0, 1 @@ -507,7 +507,7 @@ ; TUNIT-NEXT: store i32 0, i32* [[POISON_YET_AGAIN]], align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@ub ; CGSCC-SAME: (i32* nocapture nofree writeonly [[TMP0:%.*]]) #[[ATTR9:[0-9]+]] { ; CGSCC-NEXT: [[POISON:%.*]] = sub nuw i32 0, 1 @@ -524,7 +524,7 @@ } define void @inf_loop() #0 { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@inf_loop ; TUNIT-SAME: () #[[ATTR8:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -532,7 +532,7 @@ ; TUNIT: while.body: ; TUNIT-NEXT: br label [[WHILE_BODY]] ; -; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@inf_loop ; CGSCC-SAME: () #[[ATTR10:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -551,7 +551,7 @@ ; FIXME: Detect infloops, and mark affected blocks dead. define i32 @test5(i32, i32) #0 { -; CHECK: Function Attrs: nosync readnone +; CHECK: Function Attrs: nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@test5 ; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR5:[0-9]+]] { ; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]] @@ -588,13 +588,13 @@ } define void @rec() #0 { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@rec ; TUNIT-SAME: () #[[ATTR9:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@rec ; CGSCC-SAME: () #[[ATTR11:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -2228,7 +2228,7 @@ } define internal i32 @switch_default_dead(i64 %i) nounwind { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@switch_default_dead ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: entry: @@ -2255,12 +2255,12 @@ } define i32 @switch_default_dead_caller() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@switch_default_dead_caller ; TUNIT-SAME: () #[[ATTR11:[0-9]+]] { ; TUNIT-NEXT: ret i32 123 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@switch_default_dead_caller ; CGSCC-SAME: () #[[ATTR11]] { ; CGSCC-NEXT: [[CALL2:%.*]] = tail call noundef i32 @switch_default_dead() #[[ATTR16:[0-9]+]] @@ -2377,7 +2377,7 @@ ; Allow blockaddress users define internal void @dead_with_blockaddress_users(i32* nocapture %pc) nounwind readonly { -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@dead_with_blockaddress_users ; CGSCC-SAME: (i32* nocapture [[PC:%.*]]) #[[ATTR13:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -2422,59 +2422,33 @@ @e = global %struct.a* null define i32 @main() { -; TUNIT-LABEL: define {{[^@]+}}@main() { -; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[F:%.*]] = alloca i32, align 4 -; TUNIT-NEXT: br label [[FOR_COND_0:%.*]] -; TUNIT: for.cond.0: -; TUNIT-NEXT: [[G_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_0:%.*]] ] -; TUNIT-NEXT: [[CMP_0:%.*]] = icmp ult i32 [[G_0]], 100 -; TUNIT-NEXT: br i1 [[CMP_0]], label [[FOR_BODY_0]], label [[FOR_END_0:%.*]] -; TUNIT: for.body.0: -; TUNIT-NEXT: [[INC]] = add nuw nsw i32 [[G_0]], 1 -; TUNIT-NEXT: br label [[FOR_COND_0]] -; TUNIT: for.end.0: -; TUNIT-NEXT: [[CALL:%.*]] = call i8* @malloc(i64 noundef 8) -; TUNIT-NEXT: store i8* [[CALL]], i8** bitcast (%struct.a** @e to i8**), align 8 -; TUNIT-NEXT: [[B:%.*]] = bitcast i8* [[CALL]] to %struct.a** -; TUNIT-NEXT: store %struct.a* null, %struct.a** [[B]], align 8 -; TUNIT-NEXT: br label [[FOR_COND_1:%.*]] -; TUNIT: for.cond.1: -; TUNIT-NEXT: [[G_1:%.*]] = phi i32 [ 0, [[FOR_END_0]] ], [ [[INC6:%.*]], [[FOR_BODY_1:%.*]] ] -; TUNIT-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[G_1]], 100 -; TUNIT-NEXT: br i1 [[CMP_1]], label [[FOR_BODY_1]], label [[FOR_END_1:%.*]] -; TUNIT: for.body.1: -; TUNIT-NEXT: [[CALL4:%.*]] = call i32 (i32*, ...) bitcast (i32 (i32)* @h to i32 (i32*, ...)*)(i32* nonnull [[F]]) -; TUNIT-NEXT: [[INC6]] = add nuw nsw i32 [[G_1]], 1 -; TUNIT-NEXT: br label [[FOR_COND_1]] -; TUNIT: for.end.1: -; TUNIT-NEXT: ret i32 0 -; -; CGSCC-LABEL: define {{[^@]+}}@main() { -; CGSCC-NEXT: entry: -; CGSCC-NEXT: br label [[FOR_COND_0:%.*]] -; CGSCC: for.cond.0: -; CGSCC-NEXT: [[G_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_0:%.*]] ] -; CGSCC-NEXT: [[CMP_0:%.*]] = icmp ult i32 [[G_0]], 100 -; CGSCC-NEXT: br i1 [[CMP_0]], label [[FOR_BODY_0]], label [[FOR_END_0:%.*]] -; CGSCC: for.body.0: -; CGSCC-NEXT: [[INC]] = add nuw nsw i32 [[G_0]], 1 -; CGSCC-NEXT: br label [[FOR_COND_0]] -; CGSCC: for.end.0: -; CGSCC-NEXT: [[CALL:%.*]] = call i8* @malloc(i64 noundef 8) -; CGSCC-NEXT: store i8* [[CALL]], i8** bitcast (%struct.a** @e to i8**), align 8 -; CGSCC-NEXT: [[B:%.*]] = bitcast i8* [[CALL]] to %struct.a** -; CGSCC-NEXT: store %struct.a* null, %struct.a** [[B]], align 8 -; CGSCC-NEXT: br label [[FOR_COND_1:%.*]] -; CGSCC: for.cond.1: -; CGSCC-NEXT: [[G_1:%.*]] = phi i32 [ 0, [[FOR_END_0]] ], [ [[INC6:%.*]], [[FOR_BODY_1:%.*]] ] -; CGSCC-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[G_1]], 100 -; CGSCC-NEXT: br i1 [[CMP_1]], label [[FOR_BODY_1]], label [[FOR_END_1:%.*]] -; CGSCC: for.body.1: -; CGSCC-NEXT: [[INC6]] = add nuw nsw i32 [[G_1]], 1 -; CGSCC-NEXT: br label [[FOR_COND_1]] -; CGSCC: for.end.1: -; CGSCC-NEXT: ret i32 0 +; CHECK-LABEL: define {{[^@]+}}@main() { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[F:%.*]] = alloca i32, align 4 +; CHECK-NEXT: br label [[FOR_COND_0:%.*]] +; CHECK: for.cond.0: +; CHECK-NEXT: [[G_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_0:%.*]] ] +; CHECK-NEXT: [[CMP_0:%.*]] = icmp ult i32 [[G_0]], 100 +; CHECK-NEXT: br i1 [[CMP_0]], label [[FOR_BODY_0]], label [[FOR_END_0:%.*]] +; CHECK: for.body.0: +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[G_0]], 1 +; CHECK-NEXT: br label [[FOR_COND_0]] +; CHECK: for.end.0: +; CHECK-NEXT: [[CALL:%.*]] = call i8* @malloc(i64 noundef 8) +; CHECK-NEXT: store i8* [[CALL]], i8** bitcast (%struct.a** @e to i8**), align 8 +; CHECK-NEXT: [[B:%.*]] = bitcast i8* [[CALL]] to %struct.a** +; CHECK-NEXT: store %struct.a* null, %struct.a** [[B]], align 8 +; CHECK-NEXT: br label [[FOR_COND_1:%.*]] +; CHECK: for.cond.1: +; CHECK-NEXT: [[G_1:%.*]] = phi i32 [ 0, [[FOR_END_0]] ], [ [[INC6:%.*]], [[FOR_BODY_1:%.*]] ] +; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[G_1]], 100 +; CHECK-NEXT: br i1 [[CMP_1]], label [[FOR_BODY_1]], label [[FOR_END_1:%.*]] +; CHECK: for.body.1: +; CHECK-NEXT: [[CALL4:%.*]] = call i32 (i32*, ...) bitcast (i32 (i32)* @h to i32 (i32*, ...)*)(i32* nonnull [[F]]) +; CHECK-NEXT: [[INC6]] = add nuw nsw i32 [[G_1]], 1 +; CHECK-NEXT: br label [[FOR_COND_1]] +; CHECK: for.end.1: +; CHECK-NEXT: ret i32 0 ; entry: %f = alloca i32 @@ -2513,12 +2487,12 @@ declare noalias i8* @malloc(i64) define i32 @h(i32 %i) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@h ; TUNIT-SAME: (i32 [[I:%.*]]) #[[ATTR11]] { ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@h ; CGSCC-SAME: (i32 [[I:%.*]]) #[[ATTR6]] { ; CGSCC-NEXT: ret i32 0 @@ -2532,7 +2506,7 @@ @p = global i8 0 define void @bad_gep() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@bad_gep ; TUNIT-SAME: () #[[ATTR11]] { ; TUNIT-NEXT: entry: @@ -2550,13 +2524,13 @@ ; TUNIT-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 1, i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[N]]) #[[ATTR14]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@bad_gep ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[N:%.*]] = alloca i8, align 1 ; CGSCC-NEXT: [[M:%.*]] = alloca i8, align 1 -; CGSCC-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1, i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[N]]) #[[ATTR17:[0-9]+]] +; CGSCC-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1, i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[N]]) #[[ATTR16]] ; CGSCC-NEXT: br label [[EXIT:%.*]] ; CGSCC: while.body: ; CGSCC-NEXT: unreachable @@ -2565,7 +2539,7 @@ ; CGSCC: if.end: ; CGSCC-NEXT: unreachable ; CGSCC: exit: -; CGSCC-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 1, i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[N]]) #[[ATTR17]] +; CGSCC-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 1, i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[N]]) #[[ATTR16]] ; CGSCC-NEXT: ret void ; entry: @@ -2594,7 +2568,7 @@ } define i8 @edge_vs_block_liveness() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@edge_vs_block_liveness ; TUNIT-SAME: () #[[ATTR11]] { ; TUNIT-NEXT: entry: @@ -2605,7 +2579,7 @@ ; TUNIT-NEXT: [[PHI:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ 1, [[B1]] ] ; TUNIT-NEXT: ret i8 1 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@edge_vs_block_liveness ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: entry: @@ -2632,37 +2606,36 @@ declare void @llvm.lifetime.end.p0i8(i64 %0, i8* %1) ;. ; TUNIT: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind } -; TUNIT: attributes #[[ATTR1:[0-9]+]] = { readnone } +; TUNIT: attributes #[[ATTR1:[0-9]+]] = { memory(none) } ; TUNIT: attributes #[[ATTR2]] = { nounwind } ; TUNIT: attributes #[[ATTR3]] = { noreturn nounwind } ; TUNIT: attributes #[[ATTR4]] = { noreturn } -; TUNIT: attributes #[[ATTR5]] = { nosync readnone } -; TUNIT: attributes #[[ATTR6]] = { argmemonly nofree norecurse nounwind willreturn uwtable } -; TUNIT: attributes #[[ATTR7]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind readnone } -; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR5]] = { nosync memory(none) } +; TUNIT: attributes #[[ATTR6]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable } +; TUNIT: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind memory(none) } +; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn memory(none) } ; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR12:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR12:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; TUNIT: attributes #[[ATTR13]] = { nounwind willreturn } ; TUNIT: attributes #[[ATTR14]] = { willreturn } ;. ; CGSCC: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind } -; CGSCC: attributes #[[ATTR1:[0-9]+]] = { readnone } +; CGSCC: attributes #[[ATTR1:[0-9]+]] = { memory(none) } ; CGSCC: attributes #[[ATTR2]] = { nounwind } ; CGSCC: attributes #[[ATTR3]] = { noreturn nounwind } ; CGSCC: attributes #[[ATTR4]] = { noreturn } -; CGSCC: attributes #[[ATTR5]] = { nosync readnone } -; CGSCC: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR7]] = { argmemonly nofree norecurse nounwind willreturn uwtable } -; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind readnone willreturn uwtable } -; CGSCC: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR10]] = { nofree norecurse noreturn nosync nounwind readnone } -; CGSCC: attributes #[[ATTR11]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR5]] = { nosync memory(none) } +; CGSCC: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR7]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable } +; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR10]] = { nofree norecurse noreturn nosync nounwind memory(none) } +; CGSCC: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR13]] = { nounwind readonly } -; CGSCC: attributes #[[ATTR14:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; CGSCC: attributes #[[ATTR13]] = { nounwind memory(read) } +; CGSCC: attributes #[[ATTR14:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; CGSCC: attributes #[[ATTR15]] = { nounwind willreturn } -; CGSCC: attributes #[[ATTR16]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR17]] = { willreturn } +; CGSCC: attributes #[[ATTR16]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/liveness_chains.ll =================================================================== --- llvm/test/Transforms/Attributor/liveness_chains.ll +++ llvm/test/Transforms/Attributor/liveness_chains.ll @@ -7,7 +7,7 @@ declare i32 @source() nounwind readonly define i32 @chain_dead(i32 %arg) { -; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@chain_dead ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: ret i32 0 @@ -27,10 +27,10 @@ } define i32 @chain_alive(i32 %arg) { -; CHECK: Function Attrs: nounwind readonly +; CHECK: Function Attrs: nounwind memory(read) ; CHECK-LABEL: define {{[^@]+}}@chain_alive ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[INIT:%.*]] = call i32 @source() #[[ATTR0]] +; CHECK-NEXT: [[INIT:%.*]] = call i32 @source() #[[ATTR2:[0-9]+]] ; CHECK-NEXT: [[V0:%.*]] = add i32 [[ARG]], [[INIT]] ; CHECK-NEXT: [[V1:%.*]] = add i32 [[INIT]], [[V0]] ; CHECK-NEXT: [[V2:%.*]] = add i32 [[V0]], [[V1]] @@ -57,6 +57,7 @@ ret i32 %v9 } ;. -; CHECK: attributes #[[ATTR0]] = { nounwind readonly } -; CHECK: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR0]] = { nounwind memory(read) } +; CHECK: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CHECK: attributes #[[ATTR2]] = { nounwind } ;. Index: llvm/test/Transforms/Attributor/lowerheap.ll =================================================================== --- llvm/test/Transforms/Attributor/lowerheap.ll +++ llvm/test/Transforms/Attributor/lowerheap.ll @@ -47,6 +47,6 @@ ; CHECK: attributes #[[ATTR1:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" } ; CHECK: attributes #[[ATTR2:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" } ; CHECK: attributes #[[ATTR3:[0-9]+]] = { allockind("free") "alloc-family"="malloc" } -; CHECK: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } +; CHECK: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } ; CHECK: attributes #[[ATTR5]] = { nounwind } ;. Index: llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll =================================================================== --- llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll +++ llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll @@ -3,7 +3,7 @@ ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC define i8 @test1(i32 %a, i32 %length) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test1 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -37,7 +37,7 @@ } define i8 @test2(i32 %n) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test2 ; CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -185,8 +185,8 @@ declare void @dummy(i1) nounwind declare void @llvm.experimental.guard(i1, ...) ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR1:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } ; CHECK: attributes #[[ATTR2]] = { nounwind } ; CHECK: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nosync willreturn } ;. Index: llvm/test/Transforms/Attributor/lvi-for-ashr.ll =================================================================== --- llvm/test/Transforms/Attributor/lvi-for-ashr.ll +++ llvm/test/Transforms/Attributor/lvi-for-ashr.ll @@ -5,7 +5,7 @@ ; FIXME: DOT should be replaced with 3 define i32 @test-ashr(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test-ashr ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: chk65: @@ -49,5 +49,5 @@ ret i32 %retval } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/memory_locations.ll =================================================================== --- llvm/test/Transforms/Attributor/memory_locations.ll +++ llvm/test/Transforms/Attributor/memory_locations.ll @@ -11,7 +11,7 @@ ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = external dso_local global i32, align 4 ;. define dso_local i8* @internal_only(i32 %arg) { -; CHECK: Function Attrs: inaccessiblememonly +; CHECK: Function Attrs: memory(inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@internal_only ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -26,7 +26,7 @@ } define dso_local i8* @internal_only_rec(i32 %arg) { -; CHECK: Function Attrs: inaccessiblememonly +; CHECK: Function Attrs: memory(inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -66,7 +66,7 @@ } define dso_local i8* @internal_only_rec_static_helper(i32 %arg) { -; CHECK: Function Attrs: inaccessiblememonly +; CHECK: Function Attrs: memory(inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_helper ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -79,7 +79,7 @@ } define internal i8* @internal_only_rec_static(i32 %arg) { -; CHECK: Function Attrs: inaccessiblememonly +; CHECK: Function Attrs: memory(inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -173,7 +173,7 @@ } define dso_local i8* @internal_argmem_only_read(i32* %arg) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly +; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_read ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: @@ -190,7 +190,7 @@ } define dso_local i8* @internal_argmem_only_write(i32* %arg) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly +; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_write ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: @@ -205,14 +205,14 @@ } define dso_local i8* @internal_argmem_only_rec(i32* %arg) { -; TUNIT: Function Attrs: inaccessiblemem_or_argmemonly +; TUNIT: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@internal_argmem_only_rec ; TUNIT-SAME: (i32* nocapture nofree [[ARG:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[CALL:%.*]] = call noalias i8* @internal_argmem_only_rec_1(i32* nocapture nofree align 4 [[ARG]]) ; TUNIT-NEXT: ret i8* [[CALL]] ; -; CGSCC: Function Attrs: inaccessiblemem_or_argmemonly +; CGSCC: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@internal_argmem_only_rec ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -225,7 +225,7 @@ } define internal i8* @internal_argmem_only_rec_1(i32* %arg) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly +; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_rec_1 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: @@ -281,7 +281,7 @@ } define internal i8* @internal_argmem_only_rec_2(i32* %arg) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly +; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_rec_2 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: @@ -303,7 +303,7 @@ declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) nounwind argmemonly willreturn define void @callerA1(i8* %arg) { -; CHECK: Function Attrs: argmemonly +; CHECK: Function Attrs: memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@callerA1 ; CHECK-SAME: (i8* [[ARG:%.*]]) #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: [[TMP1:%.*]] = call i8* @argmem_only(i8* [[ARG]]) @@ -313,7 +313,7 @@ ret void } define void @callerA2(i8* %arg) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly +; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@callerA2 ; CHECK-SAME: (i8* [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[TMP1:%.*]] = call i8* @inaccesible_argmem_only_decl(i8* [[ARG]]) @@ -323,7 +323,7 @@ ret void } define void @callerB1() { -; CHECK: Function Attrs: readnone +; CHECK: Function Attrs: memory(none) ; CHECK-LABEL: define {{[^@]+}}@callerB1 ; CHECK-SAME: () #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[STACK:%.*]] = alloca i8, align 1 @@ -335,7 +335,7 @@ ret void } define void @callerB2() { -; CHECK: Function Attrs: inaccessiblememonly +; CHECK: Function Attrs: memory(inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@callerB2 ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: [[STACK:%.*]] = alloca i8, align 1 @@ -388,7 +388,7 @@ } define void @callerE(i8* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@callerE ; CHECK-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { ; CHECK-NEXT: ret void @@ -399,7 +399,7 @@ define void @write_global() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CHECK-LABEL: define {{[^@]+}}@write_global ; CHECK-SAME: () #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: store i32 0, i32* @G, align 4 @@ -409,7 +409,7 @@ ret void } define void @write_global_via_arg(i32* %GPtr) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@write_global_via_arg ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[GPTR:%.*]]) #[[ATTR7:[0-9]+]] { ; CHECK-NEXT: store i32 0, i32* [[GPTR]], align 4 @@ -419,7 +419,7 @@ ret void } define internal void @write_global_via_arg_internal(i32* %GPtr) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CHECK-LABEL: define {{[^@]+}}@write_global_via_arg_internal ; CHECK-SAME: () #[[ATTR6]] { ; CHECK-NEXT: store i32 0, i32* @G, align 4 @@ -430,13 +430,13 @@ } define void @writeonly_global() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@writeonly_global ; TUNIT-SAME: () #[[ATTR6]] { ; TUNIT-NEXT: call void @write_global() #[[ATTR10:[0-9]+]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@writeonly_global ; CGSCC-SAME: () #[[ATTR8:[0-9]+]] { ; CGSCC-NEXT: call void @write_global() #[[ATTR11:[0-9]+]] @@ -446,13 +446,13 @@ ret void } define void @writeonly_global_via_arg() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@writeonly_global_via_arg ; TUNIT-SAME: () #[[ATTR6]] { ; TUNIT-NEXT: call void @write_global_via_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) @G) #[[ATTR10]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@writeonly_global_via_arg ; CGSCC-SAME: () #[[ATTR8]] { ; CGSCC-NEXT: call void @write_global_via_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) @G) #[[ATTR11]] @@ -464,13 +464,13 @@ define void @writeonly_global_via_arg_internal() { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal ; TUNIT-SAME: () #[[ATTR6]] { ; TUNIT-NEXT: call void @write_global_via_arg_internal() #[[ATTR10]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal ; CGSCC-SAME: () #[[ATTR8]] { ; CGSCC-NEXT: call void @write_global_via_arg_internal() #[[ATTR11]] @@ -481,7 +481,7 @@ } define i8 @recursive_not_readnone(i8* %ptr, i1 %c) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@recursive_not_readnone ; TUNIT-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8:[0-9]+]] { ; TUNIT-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 @@ -493,7 +493,7 @@ ; TUNIT-NEXT: store i8 1, i8* [[PTR]], align 1 ; TUNIT-NEXT: ret i8 0 ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@recursive_not_readnone ; CGSCC-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] { ; CGSCC-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 @@ -517,7 +517,7 @@ } define internal i8 @recursive_not_readnone_internal(i8* %ptr, i1 %c) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@recursive_not_readnone_internal ; TUNIT-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 @@ -529,7 +529,7 @@ ; TUNIT-NEXT: store i8 1, i8* [[PTR]], align 1 ; TUNIT-NEXT: ret i8 0 ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@recursive_not_readnone_internal ; CGSCC-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 @@ -553,14 +553,14 @@ } define i8 @readnone_caller(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@readnone_caller ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] { ; TUNIT-NEXT: [[A:%.*]] = alloca i8, align 1 ; TUNIT-NEXT: [[R:%.*]] = call i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[A]], i1 [[C]]) #[[ATTR11]] ; TUNIT-NEXT: ret i8 [[R]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@readnone_caller ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR10:[0-9]+]] { ; CGSCC-NEXT: [[A:%.*]] = alloca i8, align 1 @@ -573,7 +573,7 @@ } define internal i8 @recursive_readnone_internal2(i8* %ptr, i1 %c) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@recursive_readnone_internal2 ; TUNIT-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 @@ -585,7 +585,7 @@ ; TUNIT-NEXT: store i8 1, i8* [[PTR]], align 1 ; TUNIT-NEXT: ret i8 0 ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@recursive_readnone_internal2 ; CGSCC-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 @@ -609,13 +609,13 @@ } define i8 @readnone_caller2(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@readnone_caller2 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR9]] { ; TUNIT-NEXT: [[R:%.*]] = call i8 @recursive_readnone_internal2(i8* undef, i1 [[C]]) #[[ATTR11]] ; TUNIT-NEXT: ret i8 [[R]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@readnone_caller2 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR10]] { ; CGSCC-NEXT: [[R:%.*]] = call i8 @recursive_readnone_internal2(i8* undef, i1 [[C]]) #[[ATTR13]] @@ -626,7 +626,7 @@ } define internal i8 @recursive_not_readnone_internal3(i8* %ptr, i1 %c) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@recursive_not_readnone_internal3 ; TUNIT-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 @@ -638,7 +638,7 @@ ; TUNIT-NEXT: store i8 1, i8* [[PTR]], align 1 ; TUNIT-NEXT: ret i8 0 ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@recursive_not_readnone_internal3 ; CGSCC-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 @@ -662,14 +662,14 @@ } define i8 @readnone_caller3(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@readnone_caller3 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR9]] { ; TUNIT-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 ; TUNIT-NEXT: [[R:%.*]] = call i8 @recursive_not_readnone_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 [[C]]) #[[ATTR11]] ; TUNIT-NEXT: ret i8 [[R]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@readnone_caller3 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR10]] { ; CGSCC-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 @@ -682,7 +682,7 @@ } define internal void @argmemonly_before_ipconstprop(i32* %p) argmemonly { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CHECK-LABEL: define {{[^@]+}}@argmemonly_before_ipconstprop ; CHECK-SAME: () #[[ATTR6]] { ; CHECK-NEXT: store i32 0, i32* @G, align 4 @@ -693,13 +693,13 @@ } define void @argmemonky_caller() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@argmemonky_caller ; TUNIT-SAME: () #[[ATTR6]] { ; TUNIT-NEXT: call void @argmemonly_before_ipconstprop() #[[ATTR10]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@argmemonky_caller ; CGSCC-SAME: () #[[ATTR8]] { ; CGSCC-NEXT: call void @argmemonly_before_ipconstprop() #[[ATTR11]] @@ -709,31 +709,31 @@ ret void } ;. -; TUNIT: attributes #[[ATTR0]] = { inaccessiblememonly } -; TUNIT: attributes #[[ATTR1]] = { inaccessiblemem_or_argmemonly } -; TUNIT: attributes #[[ATTR2]] = { readnone } -; TUNIT: attributes #[[ATTR3]] = { argmemonly } -; TUNIT: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR7]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR8]] = { argmemonly nofree nosync nounwind writeonly } -; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone } -; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind writeonly } +; TUNIT: attributes #[[ATTR0]] = { memory(inaccessiblemem: readwrite) } +; TUNIT: attributes #[[ATTR1]] = { memory(argmem: readwrite, inaccessiblemem: readwrite) } +; TUNIT: attributes #[[ATTR2]] = { memory(none) } +; TUNIT: attributes #[[ATTR3]] = { memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; TUNIT: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind memory(argmem: write) } +; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind memory(none) } +; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind } ;. -; CGSCC: attributes #[[ATTR0]] = { inaccessiblememonly } -; CGSCC: attributes #[[ATTR1]] = { inaccessiblemem_or_argmemonly } -; CGSCC: attributes #[[ATTR2]] = { readnone } -; CGSCC: attributes #[[ATTR3]] = { argmemonly } -; CGSCC: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR7]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR9]] = { argmemonly nofree nosync nounwind writeonly } -; CGSCC: attributes #[[ATTR10]] = { nofree nosync nounwind readnone } -; CGSCC: attributes #[[ATTR11]] = { nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR12]] = { nofree nosync nounwind writeonly } -; CGSCC: attributes #[[ATTR13]] = { nounwind writeonly } +; CGSCC: attributes #[[ATTR0]] = { memory(inaccessiblemem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CGSCC: attributes #[[ATTR2]] = { memory(none) } +; CGSCC: attributes #[[ATTR3]] = { memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR9]] = { nofree nosync nounwind memory(argmem: write) } +; CGSCC: attributes #[[ATTR10]] = { nofree nosync nounwind memory(none) } +; CGSCC: attributes #[[ATTR11]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR12]] = { nofree nosync nounwind } +; CGSCC: attributes #[[ATTR13]] = { nounwind } ;. Index: llvm/test/Transforms/Attributor/misc.ll =================================================================== --- llvm/test/Transforms/Attributor/misc.ll +++ llvm/test/Transforms/Attributor/misc.ll @@ -67,7 +67,7 @@ ; CGSCC-SAME: (void (i8*)* [[FP:%.*]]) { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 -; CGSCC-NEXT: call void @foo(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR1]] +; CGSCC-NEXT: call void @foo(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR2:[0-9]+]] ; CGSCC-NEXT: call void @callback1(void (i32*)* noundef nonnull @foo) ; CGSCC-NEXT: call void @callback2(void (i8*)* noundef bitcast (void (i32*)* @foo to void (i8*)*)) ; CGSCC-NEXT: call void @callback2(void (i8*)* [[FP]]) @@ -93,7 +93,7 @@ define internal void @foo(i32* %a) { ; -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@foo ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -108,9 +108,10 @@ declare void @callback1(void (i32*)*) declare void @callback2(void (i8*)*) ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR1]] = { nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR1]] = { nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/misc_crash.ll =================================================================== --- llvm/test/Transforms/Attributor/misc_crash.ll +++ llvm/test/Transforms/Attributor/misc_crash.ll @@ -9,7 +9,7 @@ ; CHECK: @[[VAR2:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 0 ;. define i32 addrspace(1)* @foo(i32 addrspace(4)* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@foo ; CHECK-SAME: (i32 addrspace(4)* nofree readnone [[ARG:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -22,7 +22,7 @@ } define i32* @func1() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@func1 ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: ret i32* getelementptr inbounds ([1 x i32], [1 x i32]* @var1, i32 0, i32 0) @@ -37,7 +37,7 @@ } define internal void @func2a(i32* %0) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CHECK-LABEL: define {{[^@]+}}@func2a ; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: store i32 0, i32* @var2, align 4 @@ -118,7 +118,7 @@ ret i16 %call } define internal i16 @bar3(i16* %p1, i16 %p2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bar3 ; CHECK-SAME: (i16* nocapture nofree readnone [[P1:%.*]], i16 returned [[P2:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret i16 [[P2]] @@ -130,7 +130,7 @@ ; CHECK-SAME: (i8*) declare void @func6(i8*) ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn writeonly } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(write) } ; CHECK: attributes #[[ATTR2]] = { norecurse } ;. Index: llvm/test/Transforms/Attributor/noalias.ll =================================================================== --- llvm/test/Transforms/Attributor/noalias.ll +++ llvm/test/Transforms/Attributor/noalias.ll @@ -43,7 +43,7 @@ } define void @nocapture(i8* %a){ -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@nocapture ; CHECK-SAME: (i8* nocapture nofree readnone [[A:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret void @@ -159,7 +159,7 @@ ; Returning global pointer. Should not be noalias. define i8** @getter() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@getter ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: ret i8** @G @@ -169,12 +169,12 @@ ; Returning global pointer. Should not be noalias. define i8** @calle1(){ -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@calle1 ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: ret i8** @G ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@calle1 ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: [[TMP1:%.*]] = call noundef nonnull align 8 dereferenceable(8) i8** @getter() #[[ATTR11:[0-9]+]] @@ -520,7 +520,7 @@ ; TEST 14 i2p casts define internal i32 @p2i(i32* %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@p2i ; CHECK-SAME: (i32* noalias nofree readnone [[ARG:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32 @@ -531,22 +531,22 @@ } define i32 @i2p(i32* %arg) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@i2p ; TUNIT-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { -; TUNIT-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR9:[0-9]+]] +; TUNIT-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR10:[0-9]+]] ; TUNIT-NEXT: [[I2P:%.*]] = inttoptr i32 [[C]] to i8* ; TUNIT-NEXT: [[BC:%.*]] = bitcast i8* [[I2P]] to i32* -; TUNIT-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree readonly align 4 [[BC]]) #[[ATTR10:[0-9]+]] +; TUNIT-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree readonly align 4 [[BC]]) #[[ATTR10]] ; TUNIT-NEXT: ret i32 [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@i2p ; CGSCC-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { ; CGSCC-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR11]] ; CGSCC-NEXT: [[I2P:%.*]] = inttoptr i32 [[C]] to i8* ; CGSCC-NEXT: [[BC:%.*]] = bitcast i8* [[I2P]] to i32* -; CGSCC-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[BC]]) #[[ATTR12:[0-9]+]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[BC]]) #[[ATTR11]] ; CGSCC-NEXT: ret i32 [[CALL]] ; %c = call i32 @p2i(i32* %arg) @@ -556,13 +556,13 @@ ret i32 %call } define internal i32 @ret(i32* %arg) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@ret ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { ; TUNIT-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4 ; TUNIT-NEXT: ret i32 [[L]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@ret ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6:[0-9]+]] { ; CGSCC-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4 @@ -599,7 +599,7 @@ ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 ; CGSCC-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* -; CGSCC-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR13:[0-9]+]] +; CGSCC-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR12:[0-9]+]] ; 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]]) ; CGSCC-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) ; CGSCC-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) @@ -652,13 +652,13 @@ @alias_of_p = external global i32* define void @make_alias(i32* %p) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@make_alias ; TUNIT-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] { ; TUNIT-NEXT: store i32* [[P]], i32** @alias_of_p, align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@make_alias ; CGSCC-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR8:[0-9]+]] { ; CGSCC-NEXT: store i32* [[P]], i32** @alias_of_p, align 8 @@ -669,13 +669,13 @@ } define void @only_store(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@only_store ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] { ; TUNIT-NEXT: store i32 0, i32* [[P]], align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@only_store ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR9:[0-9]+]] { ; CGSCC-NEXT: store i32 0, i32* [[P]], align 4 @@ -686,28 +686,28 @@ } define void @test15_caller(i32* noalias %p, i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test15_caller ; TUNIT-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { ; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; TUNIT-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; TUNIT: if.then: -; TUNIT-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR12:[0-9]+]] +; TUNIT-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR10]] ; TUNIT-NEXT: br label [[IF_END]] ; TUNIT: if.end: -; TUNIT-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]] +; TUNIT-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR10]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test15_caller ; CGSCC-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10:[0-9]+]] { ; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; CGSCC-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; CGSCC: if.then: -; CGSCC-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14:[0-9]+]] +; CGSCC-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13:[0-9]+]] ; CGSCC-NEXT: br label [[IF_END]] ; CGSCC: if.end: -; CGSCC-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR14]] +; CGSCC-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]] ; CGSCC-NEXT: ret void ; %tobool = icmp eq i32 %c, 0 @@ -743,32 +743,32 @@ ; Therefore, only one of the two conditions of if statementes will be fulfilled. define internal void @test16_sub(i32* noalias %p, i32 %c1, i32 %c2) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test16_sub ; TUNIT-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR7]] { ; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0 ; TUNIT-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; TUNIT: if.then: -; TUNIT-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]] -; TUNIT-NEXT: tail call void @make_alias(i32* nofree writeonly align 4 [[P]]) #[[ATTR12]] +; TUNIT-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR10]] +; TUNIT-NEXT: tail call void @make_alias(i32* nofree writeonly align 4 [[P]]) #[[ATTR10]] ; TUNIT-NEXT: br label [[IF_END]] ; TUNIT: if.end: ; TUNIT-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0 ; TUNIT-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] ; TUNIT: if.then2: -; TUNIT-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]] +; TUNIT-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR10]] ; TUNIT-NEXT: br label [[IF_END3]] ; TUNIT: if.end3: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test16_sub ; CGSCC-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR10]] { ; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0 ; CGSCC-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; CGSCC: if.then: -; CGSCC-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] -; CGSCC-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] +; CGSCC-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14:[0-9]+]] +; CGSCC-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] ; CGSCC-NEXT: br label [[IF_END]] ; CGSCC: if.end: ; CGSCC-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0 @@ -800,16 +800,16 @@ } define void @test16_caller(i32* %p, i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test16_caller ; TUNIT-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { -; TUNIT-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR12]] +; TUNIT-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR10]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test16_caller ; CGSCC-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] { -; CGSCC-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR14]] +; CGSCC-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR13]] ; CGSCC-NEXT: ret void ; tail call void @test16_sub(i32* %p, i32 %c, i32 %c) @@ -836,32 +836,32 @@ ; } define void @test17_caller(i32* noalias %p, i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test17_caller ; TUNIT-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; TUNIT-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; TUNIT: l1: -; TUNIT-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]] +; TUNIT-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR10]] ; TUNIT-NEXT: br label [[L3:%.*]] ; TUNIT: l2: -; TUNIT-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]] +; TUNIT-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR10]] ; TUNIT-NEXT: br label [[L3]] ; TUNIT: l3: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test17_caller ; CGSCC-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; CGSCC-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; CGSCC: l1: -; CGSCC-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR14]] +; CGSCC-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]] ; CGSCC-NEXT: br label [[L3:%.*]] ; CGSCC: l2: -; CGSCC-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] +; CGSCC-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] ; CGSCC-NEXT: br label [[L3]] ; CGSCC: l3: ; CGSCC-NEXT: ret void @@ -894,12 +894,12 @@ ; } define void @noreturn() { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@noreturn -; TUNIT-SAME: () #[[ATTR9]] { +; TUNIT-SAME: () #[[ATTR9:[0-9]+]] { ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@noreturn ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: ret void @@ -909,30 +909,30 @@ } define void @test18_caller(i32* noalias %p, i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test18_caller ; TUNIT-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; TUNIT-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; TUNIT: l1: -; TUNIT-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]] +; TUNIT-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR10]] ; TUNIT-NEXT: br label [[L2]] ; TUNIT: l2: -; TUNIT-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]] +; TUNIT-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR10]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test18_caller ; CGSCC-SAME: (i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; CGSCC-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; CGSCC: l1: -; CGSCC-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] +; CGSCC-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] ; CGSCC-NEXT: br label [[L2]] ; CGSCC: l2: -; CGSCC-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] +; CGSCC-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] ; CGSCC-NEXT: ret void ; entry: @@ -949,33 +949,32 @@ ret void } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; TUNIT: attributes #[[ATTR1]] = { nounwind uwtable } ; TUNIT: attributes #[[ATTR2]] = { nounwind } ; TUNIT: attributes #[[ATTR3]] = { nounwind ssp uwtable } -; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR6:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR8]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR11]] = { willreturn } -; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(read) } +; TUNIT: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; TUNIT: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; TUNIT: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR11]] = { willreturn memory(readwrite) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR1]] = { nounwind uwtable } -; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR3]] = { nounwind } ; CGSCC: attributes #[[ATTR4]] = { nounwind ssp uwtable } -; CGSCC: attributes #[[ATTR5]] = { nofree nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR7:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR11]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR12]] = { readonly willreturn } -; CGSCC: attributes #[[ATTR13]] = { willreturn } -; CGSCC: attributes #[[ATTR14]] = { nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn memory(read) } +; CGSCC: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR7:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR11]] = { willreturn } +; CGSCC: attributes #[[ATTR12]] = { willreturn memory(readwrite) } +; CGSCC: attributes #[[ATTR13]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR14]] = { nounwind willreturn memory(write) } ;. Index: llvm/test/Transforms/Attributor/nocapture-1.ll =================================================================== --- llvm/test/Transforms/Attributor/nocapture-1.ll +++ llvm/test/Transforms/Attributor/nocapture-1.ll @@ -11,7 +11,7 @@ ; CHECK: @[[G3:[a-zA-Z0-9_$"\\.-]+]] = global i8* null ;. define i32* @c1(i32* %q) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@c1 ; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[Q:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret i32* [[Q]] @@ -21,7 +21,7 @@ ; It would also be acceptable to mark %q as readnone. Update @c3 too. define void @c2(i32* %q) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CHECK-LABEL: define {{[^@]+}}@c2 ; CHECK-SAME: (i32* nofree writeonly [[Q:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: store i32* [[Q]], i32** @g, align 8 @@ -32,16 +32,16 @@ } define void @c3(i32* %q) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@c3 ; TUNIT-SAME: (i32* nofree writeonly [[Q:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR14:[0-9]+]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@c3 ; CGSCC-SAME: (i32* nofree writeonly [[Q:%.*]]) #[[ATTR2:[0-9]+]] { -; CGSCC-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR17:[0-9]+]] +; CGSCC-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR14:[0-9]+]] ; CGSCC-NEXT: ret void ; call void @c2(i32* %q) @@ -49,7 +49,7 @@ } define i1 @c4(i32* %q, i32 %bitno) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@c4 ; CHECK-SAME: (i32* nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32 @@ -73,7 +73,7 @@ ; c4b is c4 but without the escaping part define i1 @c4b(i32* %q, i32 %bitno) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@c4b ; CHECK-SAME: (i32* nocapture nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32 @@ -98,7 +98,7 @@ @lookup_table = global [2 x i1] [ i1 0, i1 1 ] define i1 @c5(i32* %q, i32 %bitno) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@c5 ; TUNIT-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2:[0-9]+]] { ; TUNIT-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32 @@ -108,7 +108,7 @@ ; TUNIT-NEXT: [[VAL:%.*]] = load i1, i1* [[LOOKUP]], align 1 ; TUNIT-NEXT: ret i1 [[VAL]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@c5 ; CGSCC-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32 @@ -130,10 +130,10 @@ declare void @throw_if_bit_set(i8*, i8) readonly define i1 @c6(i8* %q, i8 %bit) personality i32 (...)* @__gxx_personality_v0 { -; TUNIT: Function Attrs: nounwind readonly +; TUNIT: Function Attrs: nounwind memory(read) ; TUNIT-LABEL: define {{[^@]+}}@c6 ; TUNIT-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #[[ATTR4:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { -; TUNIT-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]]) #[[ATTR3:[0-9]+]] +; TUNIT-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]]) ; TUNIT-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]] ; TUNIT: ret0: ; TUNIT-NEXT: ret i1 false @@ -142,10 +142,10 @@ ; TUNIT-NEXT: cleanup ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@c6 ; CGSCC-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #[[ATTR5:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { -; CGSCC-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]]) #[[ATTR4:[0-9]+]] +; CGSCC-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]]) ; CGSCC-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]] ; CGSCC: ret0: ; CGSCC-NEXT: ret i1 false @@ -167,7 +167,7 @@ declare i32 @__gxx_personality_v0(...) define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@lookup_bit ; CHECK-SAME: (i32* nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32 @@ -184,17 +184,17 @@ } define i1 @c7(i32* %q, i32 %bitno) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@c7 ; TUNIT-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] { ; TUNIT-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR15:[0-9]+]] ; TUNIT-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1 ; TUNIT-NEXT: ret i1 [[VAL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@c7 ; CGSCC-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR6:[0-9]+]] { -; CGSCC-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR18:[0-9]+]] +; CGSCC-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR17:[0-9]+]] ; CGSCC-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1 ; CGSCC-NEXT: ret i1 [[VAL]] ; @@ -292,13 +292,13 @@ ; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn ; TUNIT-LABEL: define {{[^@]+}}@nc2 ; TUNIT-SAME: (i32* nocapture nofree [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR5]] { -; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 noundef false) #[[ATTR16:[0-9]+]] +; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 noundef false) #[[ATTR14]] ; TUNIT-NEXT: ret void ; ; CGSCC: Function Attrs: nofree nosync nounwind willreturn ; CGSCC-LABEL: define {{[^@]+}}@nc2 ; CGSCC-SAME: (i32* nocapture nofree align 4 [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR8:[0-9]+]] { -; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree align 4 [[P]], i1 noundef false) #[[ATTR14:[0-9]+]] +; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree align 4 [[P]], i1 noundef false) #[[ATTR14]] ; CGSCC-NEXT: ret void ; %1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; [#uses=0] @@ -320,16 +320,16 @@ ; FIXME: readonly and nocapture missing on the pointer. declare void @external(i8* readonly) nounwind argmemonly define void @nc4(i8* %p) { -; TUNIT: Function Attrs: argmemonly nounwind +; TUNIT: Function Attrs: nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@nc4 ; TUNIT-SAME: (i8* [[P:%.*]]) #[[ATTR6:[0-9]+]] { -; TUNIT-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR17:[0-9]+]] +; TUNIT-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR16:[0-9]+]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nounwind +; CGSCC: Function Attrs: nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@nc4 ; CGSCC-SAME: (i8* [[P:%.*]]) #[[ATTR9:[0-9]+]] { -; CGSCC-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR19:[0-9]+]] +; CGSCC-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR18:[0-9]+]] ; CGSCC-NEXT: ret void ; call void @external(i8* %p) @@ -349,17 +349,17 @@ ; It would be acceptable to add readnone to %y1_1 and %y1_2. define void @test1_1(i8* %x1_1, i8* %y1_1, i1 %c) { -; TUNIT: Function Attrs: nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test1_1 ; TUNIT-SAME: (i8* nocapture nofree readnone [[X1_1:%.*]], i8* nocapture nofree readnone [[Y1_1:%.*]], i1 [[C:%.*]]) #[[ATTR7:[0-9]+]] { -; TUNIT-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) #[[ATTR7]] +; TUNIT-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) #[[ATTR17:[0-9]+]] ; TUNIT-NEXT: store i32* null, i32** @g, align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test1_1 ; CGSCC-SAME: (i8* nocapture nofree readnone [[X1_1:%.*]], i8* nocapture nofree readnone [[Y1_1:%.*]], i1 [[C:%.*]]) #[[ATTR10:[0-9]+]] { -; CGSCC-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) #[[ATTR10]] +; CGSCC-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) #[[ATTR19:[0-9]+]] ; CGSCC-NEXT: store i32* null, i32** @g, align 8 ; CGSCC-NEXT: ret void ; @@ -369,23 +369,23 @@ } define i8* @test1_2(i8* %x1_2, i8* %y1_2, i1 %c) { -; TUNIT: Function Attrs: nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test1_2 ; TUNIT-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; TUNIT: t: -; TUNIT-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 noundef [[C]]) #[[ATTR7]] +; TUNIT-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 noundef [[C]]) #[[ATTR17]] ; TUNIT-NEXT: store i32* null, i32** @g, align 8 ; TUNIT-NEXT: br label [[F]] ; TUNIT: f: ; TUNIT-NEXT: ret i8* [[Y1_2]] ; -; CGSCC: Function Attrs: nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test1_2 ; CGSCC-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR10]] { ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; CGSCC: t: -; CGSCC-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 noundef [[C]]) #[[ATTR10]] +; CGSCC-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 noundef [[C]]) #[[ATTR19]] ; CGSCC-NEXT: store i32* null, i32** @g, align 8 ; CGSCC-NEXT: br label [[F]] ; CGSCC: f: @@ -401,17 +401,17 @@ } define void @test2(i8* %x2) { -; TUNIT: Function Attrs: nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test2 ; TUNIT-SAME: (i8* nocapture nofree readnone [[X2:%.*]]) #[[ATTR7]] { -; TUNIT-NEXT: call void @test2(i8* noalias nocapture nofree readnone undef) #[[ATTR7]] +; TUNIT-NEXT: call void @test2(i8* noalias nocapture nofree readnone undef) #[[ATTR17]] ; TUNIT-NEXT: store i32* null, i32** @g, align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test2 ; CGSCC-SAME: (i8* nocapture nofree readnone [[X2:%.*]]) #[[ATTR10]] { -; CGSCC-NEXT: call void @test2(i8* noalias nocapture nofree readnone undef) #[[ATTR10]] +; CGSCC-NEXT: call void @test2(i8* noalias nocapture nofree readnone undef) #[[ATTR19]] ; CGSCC-NEXT: store i32* null, i32** @g, align 8 ; CGSCC-NEXT: ret void ; @@ -421,17 +421,17 @@ } define void @test3(i8* %x3, i8* %y3, i8* %z3) { -; TUNIT: Function Attrs: nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test3 ; TUNIT-SAME: (i8* nocapture nofree readnone [[X3:%.*]], i8* nocapture nofree readnone [[Y3:%.*]], i8* nocapture nofree readnone [[Z3:%.*]]) #[[ATTR7]] { -; TUNIT-NEXT: call void @test3(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef) #[[ATTR7]] +; TUNIT-NEXT: call void @test3(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef) #[[ATTR17]] ; TUNIT-NEXT: store i32* null, i32** @g, align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test3 ; CGSCC-SAME: (i8* nocapture nofree readnone [[X3:%.*]], i8* nocapture nofree readnone [[Y3:%.*]], i8* nocapture nofree readnone [[Z3:%.*]]) #[[ATTR10]] { -; CGSCC-NEXT: call void @test3(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef) #[[ATTR10]] +; CGSCC-NEXT: call void @test3(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef) #[[ATTR19]] ; CGSCC-NEXT: store i32* null, i32** @g, align 8 ; CGSCC-NEXT: ret void ; @@ -441,17 +441,17 @@ } define void @test4_1(i8* %x4_1, i1 %c) { -; TUNIT: Function Attrs: nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test4_1 ; TUNIT-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { -; TUNIT-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nocapture nofree readnone undef, i1 [[C]]) #[[ATTR7]] +; TUNIT-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nocapture nofree readnone undef, i1 [[C]]) #[[ATTR17]] ; TUNIT-NEXT: store i32* null, i32** @g, align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test4_1 ; CGSCC-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]]) #[[ATTR10]] { -; CGSCC-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nocapture nofree readnone undef, i1 [[C]]) #[[ATTR10]] +; CGSCC-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nocapture nofree readnone undef, i1 [[C]]) #[[ATTR19]] ; CGSCC-NEXT: store i32* null, i32** @g, align 8 ; CGSCC-NEXT: ret void ; @@ -461,23 +461,23 @@ } define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2, i1 %c) { -; TUNIT: Function Attrs: nofree nosync nounwind writeonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test4_2 ; TUNIT-SAME: (i8* nocapture nofree readnone [[X4_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y4_2:%.*]], i8* nocapture nofree readnone [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; TUNIT: t: -; TUNIT-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 noundef [[C]]) #[[ATTR7]] +; TUNIT-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 noundef [[C]]) #[[ATTR17]] ; TUNIT-NEXT: store i32* null, i32** @g, align 8 ; TUNIT-NEXT: br label [[F]] ; TUNIT: f: ; TUNIT-NEXT: ret i8* [[Y4_2]] ; -; CGSCC: Function Attrs: nofree nosync nounwind writeonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test4_2 ; CGSCC-SAME: (i8* nocapture nofree readnone [[X4_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y4_2:%.*]], i8* nocapture nofree readnone [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR10]] { ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; CGSCC: t: -; CGSCC-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 noundef [[C]]) #[[ATTR10]] +; CGSCC-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 noundef [[C]]) #[[ATTR19]] ; CGSCC-NEXT: store i32* null, i32** @g, align 8 ; CGSCC-NEXT: br label [[F]] ; CGSCC: f: @@ -521,13 +521,13 @@ } define void @test_cmpxchg(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@test_cmpxchg ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] { ; TUNIT-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[P]], i32 0, i32 1 acquire monotonic, align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@test_cmpxchg ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR11:[0-9]+]] { ; CGSCC-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[P]], i32 0, i32 1 acquire monotonic, align 4 @@ -538,13 +538,13 @@ } define void @test_cmpxchg_ptr(i32** %p, i32* %q) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@test_cmpxchg_ptr ; TUNIT-SAME: (i32** nocapture nofree noundef nonnull dereferenceable(8) [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: [[TMP1:%.*]] = cmpxchg i32** [[P]], i32* null, i32* [[Q]] acquire monotonic, align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@test_cmpxchg_ptr ; CGSCC-SAME: (i32** nocapture nofree noundef nonnull dereferenceable(8) [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR11]] { ; CGSCC-NEXT: [[TMP1:%.*]] = cmpxchg i32** [[P]], i32* null, i32* [[Q]] acquire monotonic, align 8 @@ -555,13 +555,13 @@ } define void @test_atomicrmw(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@test_atomicrmw ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst, align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@test_atomicrmw ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR11]] { ; CGSCC-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst, align 4 @@ -572,7 +572,7 @@ } define void @test_volatile(i32* %x) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@test_volatile ; TUNIT-SAME: (i32* nofree align 4 [[X:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: entry: @@ -580,7 +580,7 @@ ; TUNIT-NEXT: store volatile i32 0, i32* [[GEP]], align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@test_volatile ; CGSCC-SAME: (i32* nofree align 4 [[X:%.*]]) #[[ATTR11]] { ; CGSCC-NEXT: entry: @@ -607,7 +607,7 @@ ; CGSCC-LABEL: define {{[^@]+}}@nocaptureLaunder ; CGSCC-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR7]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR20:[0-9]+]] +; CGSCC-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR17]] ; CGSCC-NEXT: store i8 42, i8* [[B]], align 1 ; CGSCC-NEXT: ret void ; @@ -629,7 +629,7 @@ ; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn ; CGSCC-LABEL: define {{[^@]+}}@captureLaunder ; CGSCC-SAME: (i8* nofree [[P:%.*]]) #[[ATTR7]] { -; CGSCC-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR20]] +; CGSCC-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR17]] ; CGSCC-NEXT: store i8* [[B]], i8** @g2, align 8 ; CGSCC-NEXT: ret void ; @@ -639,19 +639,19 @@ } define void @nocaptureStrip(i8* %p) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@nocaptureStrip ; TUNIT-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR19:[0-9]+]] +; TUNIT-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]] ; TUNIT-NEXT: store i8 42, i8* [[B]], align 1 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@nocaptureStrip ; CGSCC-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]] +; CGSCC-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR17]] ; CGSCC-NEXT: store i8 42, i8* [[B]], align 1 ; CGSCC-NEXT: ret void ; @@ -663,17 +663,17 @@ @g3 = global i8* null define void @captureStrip(i8* %p) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@captureStrip ; TUNIT-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR1]] { -; TUNIT-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR19]] +; TUNIT-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]] ; TUNIT-NEXT: store i8* [[B]], i8** @g3, align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@captureStrip ; CGSCC-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR1]] { -; CGSCC-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]] +; CGSCC-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR17]] ; CGSCC-NEXT: store i8* [[B]], i8** @g3, align 8 ; CGSCC-NEXT: ret void ; @@ -683,7 +683,7 @@ } define i1 @captureICmp(i32* %x) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@captureICmp ; CHECK-SAME: (i32* nofree readnone [[X:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32* [[X]], null @@ -694,7 +694,7 @@ } define i1 @captureICmpRev(i32* %x) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@captureICmpRev ; CHECK-SAME: (i32* nofree readnone [[X:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32* null, [[X]] @@ -705,7 +705,7 @@ } define i1 @nocaptureInboundsGEPICmp(i32* %x) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@nocaptureInboundsGEPICmp ; CHECK-SAME: (i32* nocapture nofree readnone [[X:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret i1 false @@ -717,7 +717,7 @@ } define i1 @nocaptureInboundsGEPICmpRev(i32* %x) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@nocaptureInboundsGEPICmpRev ; CHECK-SAME: (i32* nocapture nofree readnone [[X:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret i1 true @@ -729,7 +729,7 @@ } define i1 @nocaptureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@nocaptureDereferenceableOrNullICmp ; CHECK-SAME: (i32* nocapture nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8* @@ -742,14 +742,14 @@ } define i1 @captureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) null_pointer_is_valid { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp ; TUNIT-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR9:[0-9]+]] { ; TUNIT-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8* ; TUNIT-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null ; TUNIT-NEXT: ret i1 [[TMP2]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp ; CGSCC-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR12:[0-9]+]] { ; CGSCC-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8* @@ -776,16 +776,16 @@ declare i8* @unknownpi8pi8(i8*,i8* returned) define i8* @test_returned1(i8* %A, i8* returned %B) nounwind readonly { -; TUNIT: Function Attrs: nounwind readonly +; TUNIT: Function Attrs: nounwind memory(read) ; TUNIT-LABEL: define {{[^@]+}}@test_returned1 -; TUNIT-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] { +; TUNIT-SAME: (i8* nocapture [[A:%.*]], i8* returned [[B:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* [[A]], i8* [[B]]) ; TUNIT-NEXT: ret i8* [[P]] ; -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@test_returned1 -; CGSCC-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR5]] { +; CGSCC-SAME: (i8* nocapture [[A:%.*]], i8* returned [[B:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* [[A]], i8* [[B]]) ; CGSCC-NEXT: ret i8* [[P]] @@ -796,14 +796,14 @@ } define i8* @test_returned2(i8* %A, i8* %B) { -; TUNIT: Function Attrs: nounwind readonly +; TUNIT: Function Attrs: nounwind memory(read) ; TUNIT-LABEL: define {{[^@]+}}@test_returned2 ; TUNIT-SAME: (i8* readonly [[A:%.*]], i8* readonly [[B:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* readonly [[A]], i8* readonly [[B]]) #[[ATTR4]] ; TUNIT-NEXT: ret i8* [[P]] ; -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@test_returned2 ; CGSCC-SAME: (i8* readonly [[A:%.*]], i8* readonly [[B:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: entry: @@ -843,46 +843,44 @@ declare i8* @llvm.launder.invariant.group.p0i8(i8*) declare i8* @llvm.strip.invariant.group.p0i8(i8*) ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR3]] = { readonly } -; TUNIT: attributes #[[ATTR4]] = { nounwind readonly } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(read) } +; TUNIT: attributes #[[ATTR3:[0-9]+]] = { memory(read) } +; TUNIT: attributes #[[ATTR4]] = { nounwind memory(read) } ; TUNIT: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR6]] = { argmemonly nounwind } -; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly } -; TUNIT: attributes #[[ATTR8]] = { argmemonly nofree norecurse nounwind willreturn } -; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; TUNIT: attributes #[[ATTR10:[0-9]+]] = { nounwind readonly willreturn } +; TUNIT: attributes #[[ATTR6]] = { nounwind memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind memory(write) } +; TUNIT: attributes #[[ATTR8]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) } +; TUNIT: attributes #[[ATTR10:[0-9]+]] = { nounwind willreturn memory(read) } ; TUNIT: attributes #[[ATTR11]] = { nounwind willreturn } -; TUNIT: attributes #[[ATTR12:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind speculatable willreturn } -; TUNIT: attributes #[[ATTR13:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } -; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR15]] = { nofree nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR16]] = { nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR17]] = { nounwind } +; TUNIT: attributes #[[ATTR12:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite) } +; TUNIT: attributes #[[ATTR13:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR15]] = { nofree nounwind willreturn } +; TUNIT: attributes #[[ATTR16]] = { nounwind } +; TUNIT: attributes #[[ATTR17]] = { nofree nosync nounwind } ; TUNIT: attributes #[[ATTR18]] = { willreturn } -; TUNIT: attributes #[[ATTR19]] = { readnone willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR4]] = { readonly } -; CGSCC: attributes #[[ATTR5]] = { nounwind readonly } -; CGSCC: attributes #[[ATTR6]] = { nofree nosync nounwind readonly willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(read) } +; CGSCC: attributes #[[ATTR4:[0-9]+]] = { memory(read) } +; CGSCC: attributes #[[ATTR5]] = { nounwind memory(read) } +; CGSCC: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn memory(read) } ; CGSCC: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn } ; CGSCC: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR9]] = { argmemonly nounwind } -; CGSCC: attributes #[[ATTR10]] = { nofree nosync nounwind writeonly } -; CGSCC: attributes #[[ATTR11]] = { argmemonly nofree norecurse nounwind willreturn } -; CGSCC: attributes #[[ATTR12]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; CGSCC: attributes #[[ATTR13:[0-9]+]] = { nounwind readonly willreturn } +; CGSCC: attributes #[[ATTR9]] = { nounwind memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR10]] = { nofree nosync nounwind memory(write) } +; CGSCC: attributes #[[ATTR11]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR12]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) } +; CGSCC: attributes #[[ATTR13:[0-9]+]] = { nounwind willreturn memory(read) } ; CGSCC: attributes #[[ATTR14]] = { nounwind willreturn } -; CGSCC: attributes #[[ATTR15:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind speculatable willreturn } -; CGSCC: attributes #[[ATTR16:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } -; CGSCC: attributes #[[ATTR17]] = { nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR18]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR19]] = { nounwind } -; CGSCC: attributes #[[ATTR20]] = { willreturn } +; CGSCC: attributes #[[ATTR15:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite) } +; CGSCC: attributes #[[ATTR16:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +; CGSCC: attributes #[[ATTR17]] = { willreturn } +; CGSCC: attributes #[[ATTR18]] = { nounwind } +; CGSCC: attributes #[[ATTR19]] = { nofree nosync nounwind } ;. Index: llvm/test/Transforms/Attributor/nocapture-2.ll =================================================================== --- llvm/test/Transforms/Attributor/nocapture-2.ll +++ llvm/test/Transforms/Attributor/nocapture-2.ll @@ -16,7 +16,7 @@ ; ; no-capture is missing on %p because it is not dereferenceable define i32 @is_null_return(i32* %p) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@is_null_return ; CHECK-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -42,7 +42,7 @@ ; ; no-capture is missing on %p because it is not dereferenceable define i32 @is_null_control(i32* %p) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@is_null_control ; CHECK-SAME: (i32* nofree [[P:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -99,7 +99,7 @@ ; } ; define double* @srec0(double* %a) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@srec0 ; CHECK-SAME: (double* nocapture nofree readnone [[A:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: @@ -124,7 +124,7 @@ ; Other arguments are possible here due to the no-return behavior. ; define i32* @srec16(i32* %a) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@srec16 ; CHECK-SAME: (i32* nocapture nofree readnone [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: @@ -164,27 +164,49 @@ ; return scc_A((int*)(scc_A(a) ? scc_B((double*)a) : scc_C(a))); ; } define float* @scc_A(i32* dereferenceable_or_null(4) %a) { -; CHECK: Function Attrs: nofree nosync nounwind readnone -; CHECK-LABEL: define {{[^@]+}}@scc_A -; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[A]], null -; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; CHECK: cond.true: -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i16* -; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]] -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[CALL]] to double* -; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]] -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i32* -; CHECK-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]] -; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL2]] to i32* -; CHECK-NEXT: br label [[COND_END:%.*]] -; CHECK: cond.false: -; CHECK-NEXT: br label [[COND_END]] -; CHECK: cond.end: -; CHECK-NEXT: [[COND:%.*]] = phi i32* [ [[TMP3]], [[COND_TRUE]] ], [ [[A]], [[COND_FALSE]] ] -; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[COND]] to float* -; CHECK-NEXT: ret float* [[TMP4]] +; TUNIT: Function Attrs: nofree nosync nounwind memory(none) +; TUNIT-LABEL: define {{[^@]+}}@scc_A +; TUNIT-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2:[0-9]+]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[A]], null +; TUNIT-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; TUNIT: cond.true: +; TUNIT-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i16* +; TUNIT-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR9:[0-9]+]] +; TUNIT-NEXT: [[TMP1:%.*]] = bitcast i8* [[CALL]] to double* +; TUNIT-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR9]] +; TUNIT-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i32* +; TUNIT-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR9]] +; TUNIT-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL2]] to i32* +; TUNIT-NEXT: br label [[COND_END:%.*]] +; TUNIT: cond.false: +; TUNIT-NEXT: br label [[COND_END]] +; TUNIT: cond.end: +; TUNIT-NEXT: [[COND:%.*]] = phi i32* [ [[TMP3]], [[COND_TRUE]] ], [ [[A]], [[COND_FALSE]] ] +; TUNIT-NEXT: [[TMP4:%.*]] = bitcast i32* [[COND]] to float* +; TUNIT-NEXT: ret float* [[TMP4]] +; +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) +; CGSCC-LABEL: define {{[^@]+}}@scc_A +; CGSCC-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2:[0-9]+]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[A]], null +; CGSCC-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; CGSCC: cond.true: +; CGSCC-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i16* +; CGSCC-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR10:[0-9]+]] +; CGSCC-NEXT: [[TMP1:%.*]] = bitcast i8* [[CALL]] to double* +; CGSCC-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR10]] +; CGSCC-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i32* +; CGSCC-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR10]] +; CGSCC-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL2]] to i32* +; CGSCC-NEXT: br label [[COND_END:%.*]] +; CGSCC: cond.false: +; CGSCC-NEXT: br label [[COND_END]] +; CGSCC: cond.end: +; CGSCC-NEXT: [[COND:%.*]] = phi i32* [ [[TMP3]], [[COND_TRUE]] ], [ [[A]], [[COND_FALSE]] ] +; CGSCC-NEXT: [[TMP4:%.*]] = bitcast i32* [[COND]] to float* +; CGSCC-NEXT: ret float* [[TMP4]] ; entry: %tobool = icmp ne i32* %a, null @@ -211,27 +233,49 @@ ; FIXME: the call1 below to scc_B should return dereferenceable_or_null(8) (as the callee does). Something prevented that deduction and needs to be investigated. define i64* @scc_B(double* dereferenceable_or_null(8) %a) { -; CHECK: Function Attrs: nofree nosync nounwind readnone -; CHECK-LABEL: define {{[^@]+}}@scc_B -; CHECK-SAME: (double* nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne double* [[A]], null -; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; CHECK: cond.true: -; CHECK-NEXT: [[TMP0:%.*]] = bitcast double* [[A]] to i32* -; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]] -; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[CALL]] to double* -; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]] -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i16* -; CHECK-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]] -; CHECK-NEXT: br label [[COND_END:%.*]] -; CHECK: cond.false: -; CHECK-NEXT: [[TMP3:%.*]] = bitcast double* [[A]] to i8* -; CHECK-NEXT: br label [[COND_END]] -; CHECK: cond.end: -; CHECK-NEXT: [[COND:%.*]] = phi i8* [ [[CALL2]], [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] -; CHECK-NEXT: [[TMP4:%.*]] = bitcast i8* [[COND]] to i64* -; CHECK-NEXT: ret i64* [[TMP4]] +; TUNIT: Function Attrs: nofree nosync nounwind memory(none) +; TUNIT-LABEL: define {{[^@]+}}@scc_B +; TUNIT-SAME: (double* nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne double* [[A]], null +; TUNIT-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; TUNIT: cond.true: +; TUNIT-NEXT: [[TMP0:%.*]] = bitcast double* [[A]] to i32* +; TUNIT-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR9]] +; TUNIT-NEXT: [[TMP1:%.*]] = bitcast float* [[CALL]] to double* +; TUNIT-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR9]] +; TUNIT-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i16* +; TUNIT-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR9]] +; TUNIT-NEXT: br label [[COND_END:%.*]] +; TUNIT: cond.false: +; TUNIT-NEXT: [[TMP3:%.*]] = bitcast double* [[A]] to i8* +; TUNIT-NEXT: br label [[COND_END]] +; TUNIT: cond.end: +; TUNIT-NEXT: [[COND:%.*]] = phi i8* [ [[CALL2]], [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +; TUNIT-NEXT: [[TMP4:%.*]] = bitcast i8* [[COND]] to i64* +; TUNIT-NEXT: ret i64* [[TMP4]] +; +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) +; CGSCC-LABEL: define {{[^@]+}}@scc_B +; CGSCC-SAME: (double* nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne double* [[A]], null +; CGSCC-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; CGSCC: cond.true: +; CGSCC-NEXT: [[TMP0:%.*]] = bitcast double* [[A]] to i32* +; CGSCC-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR10]] +; CGSCC-NEXT: [[TMP1:%.*]] = bitcast float* [[CALL]] to double* +; CGSCC-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR10]] +; CGSCC-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i16* +; CGSCC-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR10]] +; CGSCC-NEXT: br label [[COND_END:%.*]] +; CGSCC: cond.false: +; CGSCC-NEXT: [[TMP3:%.*]] = bitcast double* [[A]] to i8* +; CGSCC-NEXT: br label [[COND_END]] +; CGSCC: cond.end: +; CGSCC-NEXT: [[COND:%.*]] = phi i8* [ [[CALL2]], [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +; CGSCC-NEXT: [[TMP4:%.*]] = bitcast i8* [[COND]] to i64* +; CGSCC-NEXT: ret i64* [[TMP4]] ; entry: %tobool = icmp ne double* %a, null @@ -257,29 +301,53 @@ } define i8* @scc_C(i16* dereferenceable_or_null(2) %a) { -; CHECK: Function Attrs: nofree nosync nounwind readnone -; CHECK-LABEL: define {{[^@]+}}@scc_C -; CHECK-SAME: (i16* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[BC:%.*]] = bitcast i16* [[A]] to i32* -; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[BC]]) #[[ATTR2]] -; CHECK-NEXT: [[BC2:%.*]] = bitcast float* [[CALL]] to i8* -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[BC2]], null -; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; CHECK: cond.true: -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[A]] to double* -; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]] -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64* [[CALL1]] to i8* -; CHECK-NEXT: br label [[COND_END:%.*]] -; CHECK: cond.false: -; CHECK-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A]]) #[[ATTR2]] -; CHECK-NEXT: br label [[COND_END]] -; CHECK: cond.end: -; CHECK-NEXT: [[COND:%.*]] = phi i8* [ [[TMP1]], [[COND_TRUE]] ], [ [[CALL2]], [[COND_FALSE]] ] -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[COND]] to i32* -; CHECK-NEXT: [[CALL3:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]] -; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL3]] to i8* -; CHECK-NEXT: ret i8* [[TMP3]] +; TUNIT: Function Attrs: nofree nosync nounwind memory(none) +; TUNIT-LABEL: define {{[^@]+}}@scc_C +; TUNIT-SAME: (i16* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: [[BC:%.*]] = bitcast i16* [[A]] to i32* +; TUNIT-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[BC]]) #[[ATTR9]] +; TUNIT-NEXT: [[BC2:%.*]] = bitcast float* [[CALL]] to i8* +; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[BC2]], null +; TUNIT-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; TUNIT: cond.true: +; TUNIT-NEXT: [[TMP0:%.*]] = bitcast i16* [[A]] to double* +; TUNIT-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR9]] +; TUNIT-NEXT: [[TMP1:%.*]] = bitcast i64* [[CALL1]] to i8* +; TUNIT-NEXT: br label [[COND_END:%.*]] +; TUNIT: cond.false: +; TUNIT-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; TUNIT-NEXT: br label [[COND_END]] +; TUNIT: cond.end: +; TUNIT-NEXT: [[COND:%.*]] = phi i8* [ [[TMP1]], [[COND_TRUE]] ], [ [[CALL2]], [[COND_FALSE]] ] +; TUNIT-NEXT: [[TMP2:%.*]] = bitcast i8* [[COND]] to i32* +; TUNIT-NEXT: [[CALL3:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR9]] +; TUNIT-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL3]] to i8* +; TUNIT-NEXT: ret i8* [[TMP3]] +; +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) +; CGSCC-LABEL: define {{[^@]+}}@scc_C +; CGSCC-SAME: (i16* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[BC:%.*]] = bitcast i16* [[A]] to i32* +; CGSCC-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[BC]]) #[[ATTR10]] +; CGSCC-NEXT: [[BC2:%.*]] = bitcast float* [[CALL]] to i8* +; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[BC2]], null +; CGSCC-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; CGSCC: cond.true: +; CGSCC-NEXT: [[TMP0:%.*]] = bitcast i16* [[A]] to double* +; CGSCC-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR10]] +; CGSCC-NEXT: [[TMP1:%.*]] = bitcast i64* [[CALL1]] to i8* +; CGSCC-NEXT: br label [[COND_END:%.*]] +; CGSCC: cond.false: +; CGSCC-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A]]) #[[ATTR10]] +; CGSCC-NEXT: br label [[COND_END]] +; CGSCC: cond.end: +; CGSCC-NEXT: [[COND:%.*]] = phi i8* [ [[TMP1]], [[COND_TRUE]] ], [ [[CALL2]], [[COND_FALSE]] ] +; CGSCC-NEXT: [[TMP2:%.*]] = bitcast i8* [[COND]] to i32* +; CGSCC-NEXT: [[CALL3:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR10]] +; CGSCC-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL3]] to i8* +; CGSCC-NEXT: ret i8* [[TMP3]] ; entry: %bc = bitcast i16* %a to i32* @@ -360,7 +428,7 @@ ; ; There should *not* be a no-capture attribute on %a define i64* @not_captured_but_returned_0(i64* %a) #0 { -; CHECK: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable ; CHECK-LABEL: define {{[^@]+}}@not_captured_but_returned_0 ; CHECK-SAME: (i64* nofree noundef nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: entry: @@ -381,7 +449,7 @@ ; ; There should *not* be a no-capture attribute on %a define i64* @not_captured_but_returned_1(i64* %a) #0 { -; CHECK: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable ; CHECK-LABEL: define {{[^@]+}}@not_captured_but_returned_1 ; CHECK-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: entry: @@ -403,20 +471,20 @@ ; } ; define void @test_not_captured_but_returned_calls(i64* %a) #0 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable ; TUNIT-LABEL: define {{[^@]+}}@test_not_captured_but_returned_calls ; TUNIT-SAME: (i64* nocapture nofree writeonly align 8 [[A:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9:[0-9]+]] -; TUNIT-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; TUNIT-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR10:[0-9]+]] +; TUNIT-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR10]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(argmem: write) uwtable ; CGSCC-LABEL: define {{[^@]+}}@test_not_captured_but_returned_calls ; CGSCC-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR5:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR10:[0-9]+]] -; CGSCC-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR10]] +; CGSCC-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR11:[0-9]+]] +; CGSCC-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR11]] ; CGSCC-NEXT: ret void ; entry: @@ -433,18 +501,18 @@ ; ; There should *not* be a no-capture attribute on %a define i64* @negative_test_not_captured_but_returned_call_0a(i64* %a) #0 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable ; TUNIT-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a ; TUNIT-SAME: (i64* nofree returned writeonly align 8 "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; TUNIT-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR10]] ; TUNIT-NEXT: ret i64* [[A]] ; -; CGSCC: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(argmem: write) uwtable ; CGSCC-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a ; CGSCC-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call noundef nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A]]) #[[ATTR10]] +; CGSCC-NEXT: [[CALL:%.*]] = call noundef nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A]]) #[[ATTR11]] ; CGSCC-NEXT: ret i64* [[CALL]] ; entry: @@ -460,20 +528,20 @@ ; ; There should *not* be a no-capture attribute on %a define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable ; TUNIT-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0b ; TUNIT-SAME: (i64* nofree writeonly align 8 [[A:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; TUNIT-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR10]] ; TUNIT-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[A]] to i64 ; TUNIT-NEXT: store i64 [[TMP0]], i64* [[A]], align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(argmem: write) uwtable ; CGSCC-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0b ; CGSCC-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A]]) #[[ATTR10]] +; CGSCC-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A]]) #[[ATTR11]] ; CGSCC-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64 ; CGSCC-NEXT: store i64 [[TMP0]], i64* [[A]], align 8 ; CGSCC-NEXT: ret void @@ -493,18 +561,18 @@ ; ; There should *not* be a no-capture attribute on %a define i64* @negative_test_not_captured_but_returned_call_1a(i64* %a) #0 { -; TUNIT: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable ; TUNIT-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1a ; TUNIT-SAME: (i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call noundef nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; TUNIT-NEXT: [[CALL:%.*]] = call noundef nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR10]] ; TUNIT-NEXT: ret i64* [[CALL]] ; -; CGSCC: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(argmem: write) uwtable ; CGSCC-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1a ; CGSCC-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call noundef nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR10]] +; CGSCC-NEXT: [[CALL:%.*]] = call noundef nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR11]] ; CGSCC-NEXT: ret i64* [[CALL]] ; entry: @@ -520,20 +588,20 @@ ; ; There should *not* be a no-capture attribute on %a define void @negative_test_not_captured_but_returned_call_1b(i64* %a) #0 { -; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(write) uwtable ; TUNIT-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1b ; TUNIT-SAME: (i64* nofree writeonly align 8 [[A:%.*]]) #[[ATTR5:[0-9]+]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; TUNIT-NEXT: [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR10]] ; TUNIT-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64 ; TUNIT-NEXT: store i64 [[TMP0]], i64* [[CALL]], align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn writeonly uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(write) uwtable ; CGSCC-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1b ; CGSCC-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR6:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR10]] +; CGSCC-NEXT: [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR11]] ; CGSCC-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64 ; CGSCC-NEXT: store i64 [[TMP0]], i64* [[CALL]], align 8 ; CGSCC-NEXT: ret void @@ -619,18 +687,18 @@ declare i32* @readonly_unknown(i32*, i32*) readonly define void @not_captured_by_readonly_call(i32* %b) #0 { -; TUNIT: Function Attrs: noinline nounwind readonly uwtable +; TUNIT: Function Attrs: noinline nounwind memory(read) uwtable ; TUNIT-LABEL: define {{[^@]+}}@not_captured_by_readonly_call ; TUNIT-SAME: (i32* nocapture readonly [[B:%.*]]) #[[ATTR7:[0-9]+]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[B]]) #[[ATTR6:[0-9]+]] +; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[B]]) ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: noinline nounwind readonly uwtable +; CGSCC: Function Attrs: noinline nounwind memory(read) uwtable ; CGSCC-LABEL: define {{[^@]+}}@not_captured_by_readonly_call ; CGSCC-SAME: (i32* nocapture readonly [[B:%.*]]) #[[ATTR8:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[B]]) #[[ATTR7:[0-9]+]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[B]]) ; CGSCC-NEXT: ret void ; entry: @@ -644,18 +712,18 @@ ; Make sure the returned flag on %r is strong enough to justify nocapture on %b but **not** on %r. ; define i32* @not_captured_by_readonly_call_not_returned_either1(i32* %b, i32* returned %r) { -; TUNIT: Function Attrs: nounwind readonly +; TUNIT: Function Attrs: nounwind memory(read) ; TUNIT-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either1 ; TUNIT-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8:[0-9]+]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]] +; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR11:[0-9]+]] ; TUNIT-NEXT: ret i32* [[CALL]] ; -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either1 ; CGSCC-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR9:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR9]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR12:[0-9]+]] ; CGSCC-NEXT: ret i32* [[CALL]] ; entry: @@ -665,18 +733,18 @@ declare i32* @readonly_unknown_r1a(i32*, i32* returned) readonly define i32* @not_captured_by_readonly_call_not_returned_either2(i32* %b, i32* %r) { -; TUNIT: Function Attrs: nounwind readonly +; TUNIT: Function Attrs: nounwind memory(read) ; TUNIT-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either2 ; TUNIT-SAME: (i32* readonly [[B:%.*]], i32* readonly [[R:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]] +; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR11]] ; TUNIT-NEXT: ret i32* [[CALL]] ; -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either2 ; CGSCC-SAME: (i32* readonly [[B:%.*]], i32* readonly [[R:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR9]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR12]] ; CGSCC-NEXT: ret i32* [[CALL]] ; entry: @@ -686,18 +754,18 @@ declare i32* @readonly_unknown_r1b(i32*, i32* returned) readonly nounwind define i32* @not_captured_by_readonly_call_not_returned_either3(i32* %b, i32* %r) { -; TUNIT: Function Attrs: nounwind readonly +; TUNIT: Function Attrs: nounwind memory(read) ; TUNIT-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3 ; TUNIT-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly [[R:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR8]] +; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR11]] ; TUNIT-NEXT: ret i32* [[CALL]] ; -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3 ; CGSCC-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly [[R:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR9]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR12]] ; CGSCC-NEXT: ret i32* [[CALL]] ; entry: @@ -706,18 +774,18 @@ } define i32* @not_captured_by_readonly_call_not_returned_either4(i32* %b, i32* %r) nounwind { -; TUNIT: Function Attrs: nounwind readonly +; TUNIT: Function Attrs: nounwind memory(read) ; TUNIT-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either4 ; TUNIT-SAME: (i32* readonly [[B:%.*]], i32* readonly [[R:%.*]]) #[[ATTR8]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR6]] +; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) ; TUNIT-NEXT: ret i32* [[CALL]] ; -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either4 ; CGSCC-SAME: (i32* readonly [[B:%.*]], i32* readonly [[R:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR7]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) ; CGSCC-NEXT: ret i32* [[CALL]] ; entry: @@ -743,19 +811,12 @@ declare i32* @readonly_i32p(i32*) readonly define void @nocapture_is_not_subsumed_2(i32* nocapture %b) { -; TUNIT-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2 -; TUNIT-SAME: (i32* nocapture [[B:%.*]]) { -; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly [[B]]) #[[ATTR6]] -; TUNIT-NEXT: store i32 0, i32* [[CALL]], align 4 -; TUNIT-NEXT: ret void -; -; CGSCC-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2 -; CGSCC-SAME: (i32* nocapture [[B:%.*]]) { -; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly [[B]]) #[[ATTR7]] -; CGSCC-NEXT: store i32 0, i32* [[CALL]], align 4 -; CGSCC-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2 +; CHECK-SAME: (i32* nocapture [[B:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly [[B]]) +; CHECK-NEXT: store i32 0, i32* [[CALL]], align 4 +; CHECK-NEXT: ret void ; entry: %call = call i32* @readonly_i32p(i32* %b) @@ -765,26 +826,30 @@ attributes #0 = { noinline nounwind uwtable } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind readnone } +; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR1]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind memory(none) } ; TUNIT: attributes #[[ATTR3]] = { noinline nounwind uwtable } -; TUNIT: attributes #[[ATTR4]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } -; TUNIT: attributes #[[ATTR5]] = { nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } -; TUNIT: attributes #[[ATTR6]] = { readonly } -; TUNIT: attributes #[[ATTR7]] = { noinline nounwind readonly uwtable } -; TUNIT: attributes #[[ATTR8]] = { nounwind readonly } -; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR4]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable } +; TUNIT: attributes #[[ATTR5]] = { nofree noinline norecurse nosync nounwind willreturn memory(write) uwtable } +; TUNIT: attributes #[[ATTR6:[0-9]+]] = { memory(read) } +; TUNIT: attributes #[[ATTR7]] = { noinline nounwind memory(read) uwtable } +; TUNIT: attributes #[[ATTR8]] = { nounwind memory(read) } +; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind } +; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR11]] = { nounwind } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone willreturn uwtable } -; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind readnone } +; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind memory(none) } ; CGSCC: attributes #[[ATTR3]] = { noinline nounwind uwtable } -; CGSCC: attributes #[[ATTR4]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } -; CGSCC: attributes #[[ATTR5]] = { argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable } -; CGSCC: attributes #[[ATTR6]] = { nofree noinline nosync nounwind willreturn writeonly uwtable } -; CGSCC: attributes #[[ATTR7]] = { readonly } -; CGSCC: attributes #[[ATTR8]] = { noinline nounwind readonly uwtable } -; CGSCC: attributes #[[ATTR9]] = { nounwind readonly } -; CGSCC: attributes #[[ATTR10]] = { nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR4]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: write) uwtable } +; CGSCC: attributes #[[ATTR5]] = { nofree noinline nosync nounwind willreturn memory(argmem: write) uwtable } +; CGSCC: attributes #[[ATTR6]] = { nofree noinline nosync nounwind willreturn memory(write) uwtable } +; CGSCC: attributes #[[ATTR7:[0-9]+]] = { memory(read) } +; CGSCC: attributes #[[ATTR8]] = { noinline nounwind memory(read) uwtable } +; CGSCC: attributes #[[ATTR9]] = { nounwind memory(read) } +; CGSCC: attributes #[[ATTR10]] = { nofree nosync nounwind } +; CGSCC: attributes #[[ATTR11]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR12]] = { nounwind } ;. Index: llvm/test/Transforms/Attributor/nodelete.ll =================================================================== --- llvm/test/Transforms/Attributor/nodelete.ll +++ llvm/test/Transforms/Attributor/nodelete.ll @@ -6,13 +6,13 @@ %"b" = type { i8 } define hidden i64 @f1() align 2 { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@f1 ; TUNIT-SAME: () #[[ATTR0:[0-9]+]] align 2 { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret i64 undef ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@f1 ; CGSCC-SAME: () #[[ATTR0:[0-9]+]] align 2 { ; CGSCC-NEXT: entry: @@ -27,7 +27,7 @@ } define internal i64 @f2(%"a"* %this) align 2 { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@f2 ; CGSCC-SAME: () #[[ATTR0]] align 2 { ; CGSCC-NEXT: entry: @@ -43,7 +43,7 @@ } define internal void @f3(%"b"* %this) align 2 { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@f3 ; CGSCC-SAME: () #[[ATTR0]] align 2 { ; CGSCC-NEXT: entry: @@ -58,7 +58,7 @@ } define internal i1 @f4(%"b"* %this) align 2 { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@f4 ; CGSCC-SAME: () #[[ATTR0]] align 2 { ; CGSCC-NEXT: entry: @@ -73,7 +73,7 @@ } define internal %"a"* @f5(%"b"* %this) align 2 { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@f5 ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] align 2 { ; CGSCC-NEXT: entry: @@ -87,9 +87,9 @@ ret %"a"* %0 } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/nofree.ll =================================================================== --- llvm/test/Transforms/Attributor/nofree.ll +++ llvm/test/Transforms/Attributor/nofree.ll @@ -15,7 +15,7 @@ ; TEST 1 (positive case) define void @only_return() #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@only_return ; CHECK-SAME: () #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: ret void @@ -104,12 +104,12 @@ define void @mutual_recursion1() #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@mutual_recursion1 ; TUNIT-SAME: () #[[ATTR4:[0-9]+]] { ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@mutual_recursion1 ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: ret void @@ -119,12 +119,12 @@ } define void @mutual_recursion2() #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@mutual_recursion2 ; TUNIT-SAME: () #[[ATTR4]] { ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@mutual_recursion2 ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: ret void @@ -182,17 +182,17 @@ ; Call function declaration with "nofree" -; CHECK: Function Attrs: nofree noinline nounwind readnone uwtable +; CHECK: Function Attrs: nofree noinline nounwind memory(none) uwtable ; CHECK-NEXT: declare void @nofree_function() declare void @nofree_function() nofree readnone #0 define void @call_nofree_function() #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@call_nofree_function ; TUNIT-SAME: () #[[ATTR4]] { ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@call_nofree_function ; CGSCC-SAME: () #[[ATTR5:[0-9]+]] { ; CGSCC-NEXT: ret void @@ -240,12 +240,12 @@ ; TEST 10 (positive case) ; Call intrinsic function -; CHECK: Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) ; CHECK-NEXT: declare float @llvm.floor.f32(float) declare float @llvm.floor.f32(float) define void @call_floor(float %a) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@call_floor ; CHECK-SAME: (float [[A:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: ret void @@ -255,7 +255,7 @@ } define float @call_floor2(float %a) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@call_floor2 ; CHECK-SAME: (float [[A:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR11:[0-9]+]] @@ -269,12 +269,12 @@ ; Check propagation. define void @f1() #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@f1 ; TUNIT-SAME: () #[[ATTR4]] { ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@f1 ; CGSCC-SAME: () #[[ATTR5]] { ; CGSCC-NEXT: ret void @@ -284,12 +284,12 @@ } define void @f2() #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@f2 ; TUNIT-SAME: () #[[ATTR4]] { ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@f2 ; CGSCC-SAME: () #[[ATTR5]] { ; CGSCC-NEXT: ret void @@ -357,7 +357,7 @@ ; ; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_pos ; CHECK-SAME: (i8* nofree [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* nofree [[ARG3:%.*]], i8* [[ARG4:%.*]]) { -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12:[0-9]+]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR11]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] ; CHECK-NEXT: call void @unknown(i8* nofree [[ARG1]], i8* [[ARG2]], i8* nofree [[ARG3]], i8* [[ARG4]]) ; CHECK-NEXT: ret void ; @@ -440,28 +440,26 @@ ; TUNIT: attributes #[[ATTR0]] = { nounwind } ; TUNIT: attributes #[[ATTR1]] = { noinline nounwind uwtable } ; TUNIT: attributes #[[ATTR2]] = { nobuiltin nounwind } -; TUNIT: attributes #[[ATTR3]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR4]] = { nofree noinline nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR5:[0-9]+]] = { nofree noinline nounwind readnone uwtable } -; TUNIT: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; TUNIT: attributes #[[ATTR3]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR4]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR5:[0-9]+]] = { nofree noinline nounwind memory(none) uwtable } +; TUNIT: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; TUNIT: attributes #[[ATTR7]] = { nofree nounwind } ; TUNIT: attributes #[[ATTR8:[0-9]+]] = { nobuiltin nofree nounwind } -; TUNIT: attributes #[[ATTR9:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR9:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } ; TUNIT: attributes #[[ATTR10:[0-9]+]] = { nounwind willreturn } -; TUNIT: attributes #[[ATTR11]] = { readnone willreturn } -; TUNIT: attributes #[[ATTR12]] = { willreturn } +; TUNIT: attributes #[[ATTR11]] = { willreturn } ;. ; CGSCC: attributes #[[ATTR0]] = { nounwind } ; CGSCC: attributes #[[ATTR1]] = { noinline nounwind uwtable } ; CGSCC: attributes #[[ATTR2]] = { nobuiltin nounwind } -; CGSCC: attributes #[[ATTR3]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nofree noinline nounwind readnone uwtable } -; CGSCC: attributes #[[ATTR5]] = { nofree noinline nosync nounwind readnone willreturn uwtable } -; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CGSCC: attributes #[[ATTR3]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nofree noinline nounwind memory(none) uwtable } +; CGSCC: attributes #[[ATTR5]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CGSCC: attributes #[[ATTR7]] = { nofree nounwind } ; CGSCC: attributes #[[ATTR8:[0-9]+]] = { nobuiltin nofree nounwind } -; CGSCC: attributes #[[ATTR9:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } +; CGSCC: attributes #[[ATTR9:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } ; CGSCC: attributes #[[ATTR10:[0-9]+]] = { nounwind willreturn } -; CGSCC: attributes #[[ATTR11]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR12]] = { willreturn } +; CGSCC: attributes #[[ATTR11]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/nonnull.ll =================================================================== --- llvm/test/Transforms/Attributor/nonnull.ll +++ llvm/test/Transforms/Attributor/nonnull.ll @@ -20,7 +20,7 @@ ; Return a pointer trivially nonnull (argument attribute) define i8* @test2(i8* nonnull %p) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test2 ; CHECK-SAME: (i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: ret i8* [[P]] @@ -29,7 +29,7 @@ } define i8* @test2A(i1 %c, i8* %ret) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@test2A ; CHECK-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] @@ -50,7 +50,7 @@ } define i8* @test2B(i1 %c, i8* %ret) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@test2B ; CHECK-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] @@ -106,12 +106,12 @@ ; nonnull if neither can ever return null. (In this case, they ; just never return period.) define i8* @test4_helper() { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test4_helper ; TUNIT-SAME: () #[[ATTR3:[0-9]+]] { ; TUNIT-NEXT: ret i8* undef ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test4_helper ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: ret i8* undef @@ -121,12 +121,12 @@ } define i8* @test4() { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test4 ; TUNIT-SAME: () #[[ATTR3]] { ; TUNIT-NEXT: ret i8* undef ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test4 ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: ret i8* undef @@ -138,7 +138,7 @@ ; Given a mutual recursive set of functions which *can* return null ; make sure we haven't marked them as nonnull. define i8* @test5_helper(i1 %c) { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test5_helper ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] @@ -147,7 +147,7 @@ ; TUNIT: end: ; TUNIT-NEXT: ret i8* null ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test5_helper ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] @@ -165,12 +165,12 @@ } define i8* @test5(i1 %c) { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test5 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: ret i8* null ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test5 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: ret i8* null @@ -237,7 +237,7 @@ } define i8* @test7(i8* %a) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test7 ; CHECK-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: ret i8* [[A]] @@ -247,7 +247,7 @@ } define i8* @test8(i8* %a) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test8 ; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1 @@ -258,7 +258,7 @@ } define i8* @test9(i8* %a, i64 %n) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test9 ; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]] @@ -271,7 +271,7 @@ ; ATTRIBUTOR_OPM: define i8* @test10 ; ATTRIBUTOR_NPM: define nonnull i8* @test10 define i8* @test10(i8* %a, i64 %n) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@test10 ; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[N]], 0 @@ -391,7 +391,7 @@ define internal i32* @f1(i32* %arg) { ; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull readonly %arg) -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind readonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@f1 ; TUNIT-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR6:[0-9]+]] { ; TUNIT-NEXT: bb: @@ -413,7 +413,7 @@ ; TUNIT-NEXT: [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to i32*), [[BB:%.*]] ] ; TUNIT-NEXT: ret i32* [[TMP10]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@f1 ; CGSCC-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { ; CGSCC-NEXT: bb: @@ -461,14 +461,14 @@ } define internal i32* @f2(i32* %arg) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind readonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@f2 ; TUNIT-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6]] { ; TUNIT-NEXT: bb: ; TUNIT-NEXT: [[TMP:%.*]] = tail call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]] ; TUNIT-NEXT: ret i32* [[TMP]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@f2 ; CGSCC-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: bb: @@ -482,14 +482,14 @@ define dso_local noalias i32* @f3(i32* %arg) { ; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull readonly %arg) -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind readonly +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@f3 ; TUNIT-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR6]] { ; TUNIT-NEXT: bb: ; TUNIT-NEXT: [[TMP:%.*]] = call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]] ; TUNIT-NEXT: ret i32* [[TMP]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@f3 ; CGSCC-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5]] { ; CGSCC-NEXT: bb: @@ -857,7 +857,7 @@ define i8 @parent7(i8* %a) { ; CHECK-LABEL: define {{[^@]+}}@parent7 ; CHECK-SAME: (i8* nonnull [[A:%.*]]) { -; CHECK-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR15:[0-9]+]] +; CHECK-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR13]] ; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]]) ; CHECK-NEXT: ret i8 [[RET]] ; @@ -915,7 +915,7 @@ } define i32* @gep1(i32* %p) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@gep1 ; CHECK-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1 @@ -927,13 +927,13 @@ define i32* @gep1_no_null_opt(i32* %p) #0 { ; Should't be able to derive nonnull based on gep. -; TUNIT: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@gep1_no_null_opt ; TUNIT-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR9:[0-9]+]] { ; TUNIT-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1 ; TUNIT-NEXT: ret i32* [[Q]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@gep1_no_null_opt ; CGSCC-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR8:[0-9]+]] { ; CGSCC-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1 @@ -944,7 +944,7 @@ } define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@gep2 ; CHECK-SAME: (i32 addrspace(3)* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32 addrspace(3)* [[P]], i32 1 @@ -956,7 +956,7 @@ ; FIXME: We should propagate dereferenceable here but *not* nonnull define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@as ; CHECK-SAME: (i32 addrspace(3)* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: ret i32 addrspace(3)* [[P]] @@ -966,7 +966,7 @@ ; CHECK-NOT: @g2() define internal i32* @g2() { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@g2 ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: ret i32* inttoptr (i64 4 to i32*) @@ -975,15 +975,15 @@ } define i32* @g1() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@g1 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i32* inttoptr (i64 4 to i32*) ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@g1 ; CGSCC-SAME: () #[[ATTR9:[0-9]+]] { -; CGSCC-NEXT: [[C:%.*]] = call noundef nonnull align 4 i32* @g2() #[[ATTR16:[0-9]+]] +; CGSCC-NEXT: [[C:%.*]] = call noundef nonnull align 4 i32* @g2() #[[ATTR13]] ; CGSCC-NEXT: ret i32* [[C]] ; %c = call i32* @g2() @@ -1391,10 +1391,10 @@ ; We should not mark the return of @strrchr as `nonnull`, it may well be NULL! define i8* @mybasename(i8* nofree readonly %str) { -; CHECK: Function Attrs: nofree nounwind readonly willreturn +; CHECK: Function Attrs: nofree nounwind willreturn memory(read) ; CHECK-LABEL: define {{[^@]+}}@mybasename ; CHECK-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR12:[0-9]+]] { -; CHECK-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR15]] +; CHECK-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR13]] ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null ; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]] @@ -1486,7 +1486,7 @@ declare void @use_i8_ptr_ret(i8* nofree nocapture readnone) nounwind willreturn define i8* @nonnull_function_ptr_1() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@nonnull_function_ptr_1 ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: ret i8* bitcast (i8* ()* @nonnull_function_ptr_1 to i8*) @@ -1497,7 +1497,7 @@ declare i8* @function_decl() define i8* @nonnull_function_ptr_2() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@nonnull_function_ptr_2 ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: ret i8* bitcast (i8* ()* @function_decl to i8*) @@ -1522,38 +1522,35 @@ attributes #0 = { null_pointer_is_valid } attributes #1 = { nounwind willreturn} ;. -; TUNIT: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) } +; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(none) } ; TUNIT: attributes #[[ATTR4]] = { noreturn } ; TUNIT: attributes #[[ATTR5]] = { nounwind } -; TUNIT: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind readonly } +; TUNIT: attributes #[[ATTR6]] = { nofree nosync nounwind memory(argmem: read) } ; TUNIT: attributes #[[ATTR7]] = { nounwind willreturn } -; TUNIT: attributes #[[ATTR8:[0-9]+]] = { nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } +; TUNIT: attributes #[[ATTR8:[0-9]+]] = { nounwind willreturn memory(read) } +; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) } ; TUNIT: attributes #[[ATTR10]] = { naked } ; TUNIT: attributes #[[ATTR11]] = { noinline optnone } -; TUNIT: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn } +; TUNIT: attributes #[[ATTR12]] = { nofree nounwind willreturn memory(read) } ; TUNIT: attributes #[[ATTR13]] = { willreturn } -; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind readonly } -; TUNIT: attributes #[[ATTR15]] = { readonly willreturn } +; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind } ;. -; CGSCC: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn } +; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) } ; CGSCC: attributes #[[ATTR3]] = { noreturn } ; CGSCC: attributes #[[ATTR4]] = { nounwind } -; CGSCC: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly } +; CGSCC: attributes #[[ATTR5]] = { nofree nosync nounwind memory(argmem: read) } ; CGSCC: attributes #[[ATTR6]] = { nounwind willreturn } -; CGSCC: attributes #[[ATTR7:[0-9]+]] = { nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; CGSCC: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR7:[0-9]+]] = { nounwind willreturn memory(read) } +; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) } +; CGSCC: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR10]] = { naked } ; CGSCC: attributes #[[ATTR11]] = { noinline optnone } -; CGSCC: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn } +; CGSCC: attributes #[[ATTR12]] = { nofree nounwind willreturn memory(read) } ; CGSCC: attributes #[[ATTR13]] = { willreturn } -; CGSCC: attributes #[[ATTR14]] = { nofree nosync nounwind readonly } -; CGSCC: attributes #[[ATTR15]] = { readonly willreturn } -; CGSCC: attributes #[[ATTR16]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR14]] = { nofree nosync nounwind } ;. Index: llvm/test/Transforms/Attributor/norecurse.ll =================================================================== --- llvm/test/Transforms/Attributor/norecurse.ll +++ llvm/test/Transforms/Attributor/norecurse.ll @@ -3,7 +3,7 @@ ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC define i32 @leaf() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@leaf ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret i32 1 @@ -12,7 +12,7 @@ } define i32 @self_rec() { -; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@self_rec ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: ret i32 4 @@ -22,12 +22,12 @@ } define i32 @indirect_rec() { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@indirect_rec ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i32 undef ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@indirect_rec ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: ret i32 undef @@ -36,12 +36,12 @@ ret i32 %a } define i32 @indirect_rec2() { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@indirect_rec2 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i32 undef ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@indirect_rec2 ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: ret i32 undef @@ -51,7 +51,7 @@ } define i32 @extern() { -; CHECK: Function Attrs: nosync readnone +; CHECK: Function Attrs: nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@extern ; CHECK-SAME: () #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @k() @@ -66,7 +66,7 @@ declare i32 @k() readnone define void @intrinsic(i8* %dest, i8* %src, i32 %len) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@intrinsic ; CHECK-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) #[[ATTR9:[0-9]+]] @@ -81,7 +81,7 @@ declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1) define internal i32 @called_by_norecurse() { -; CHECK: Function Attrs: norecurse nosync readnone +; CHECK: Function Attrs: norecurse nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse ; CHECK-SAME: () #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @k() @@ -91,13 +91,13 @@ ret i32 %a } define void @m() norecurse { -; TUNIT: Function Attrs: norecurse nosync readnone +; TUNIT: Function Attrs: norecurse nosync memory(none) ; TUNIT-LABEL: define {{[^@]+}}@m ; TUNIT-SAME: () #[[ATTR6]] { -; TUNIT-NEXT: [[A:%.*]] = call i32 @called_by_norecurse() #[[ATTR2]] +; TUNIT-NEXT: [[A:%.*]] = call i32 @called_by_norecurse() #[[ATTR10:[0-9]+]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: norecurse nosync readnone +; CGSCC: Function Attrs: norecurse nosync memory(none) ; CGSCC-LABEL: define {{[^@]+}}@m ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: [[A:%.*]] = call i32 @called_by_norecurse() @@ -108,13 +108,13 @@ } define internal i32 @called_by_norecurse_indirectly() { -; TUNIT: Function Attrs: norecurse nosync readnone +; TUNIT: Function Attrs: norecurse nosync memory(none) ; TUNIT-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly ; TUNIT-SAME: () #[[ATTR6]] { ; TUNIT-NEXT: [[A:%.*]] = call i32 @k() ; TUNIT-NEXT: ret i32 [[A]] ; -; CGSCC: Function Attrs: nosync readnone +; CGSCC: Function Attrs: nosync memory(none) ; CGSCC-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[A:%.*]] = call i32 @k() @@ -124,13 +124,13 @@ ret i32 %a } define internal i32 @o() { -; TUNIT: Function Attrs: norecurse nosync readnone +; TUNIT: Function Attrs: norecurse nosync memory(none) ; TUNIT-LABEL: define {{[^@]+}}@o ; TUNIT-SAME: () #[[ATTR6]] { -; TUNIT-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly() #[[ATTR2]] +; TUNIT-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly() #[[ATTR10]] ; TUNIT-NEXT: ret i32 [[A]] ; -; CGSCC: Function Attrs: norecurse nosync readnone +; CGSCC: Function Attrs: norecurse nosync memory(none) ; CGSCC-LABEL: define {{[^@]+}}@o ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly() @@ -140,13 +140,13 @@ ret i32 %a } define i32 @p() norecurse { -; TUNIT: Function Attrs: norecurse nosync readnone +; TUNIT: Function Attrs: norecurse nosync memory(none) ; TUNIT-LABEL: define {{[^@]+}}@p ; TUNIT-SAME: () #[[ATTR6]] { -; TUNIT-NEXT: [[A:%.*]] = call i32 @o() #[[ATTR2]] +; TUNIT-NEXT: [[A:%.*]] = call i32 @o() #[[ATTR10]] ; TUNIT-NEXT: ret i32 [[A]] ; -; CGSCC: Function Attrs: norecurse nosync readnone +; CGSCC: Function Attrs: norecurse nosync memory(none) ; CGSCC-LABEL: define {{[^@]+}}@p ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: [[A:%.*]] = call i32 @o() @@ -157,7 +157,7 @@ } define void @f(i32 %x) { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@f ; TUNIT-SAME: (i32 [[X:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -170,7 +170,7 @@ ; TUNIT: if.end: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@f ; CGSCC-SAME: (i32 [[X:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: @@ -198,7 +198,7 @@ } define void @g() norecurse { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@g ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -241,7 +241,7 @@ ; Call an unknown function in a dead block. declare void @unknown() define i32 @call_unknown_in_dead_block() local_unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@call_unknown_in_dead_block ; CHECK-SAME: () local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: ret i32 0 @@ -307,14 +307,26 @@ } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR2]] = { nosync readnone } -; CHECK: attributes #[[ATTR3:[0-9]+]] = { readnone } -; CHECK: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CHECK: attributes #[[ATTR5:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } -; CHECK: attributes #[[ATTR6]] = { norecurse nosync readnone } -; CHECK: attributes #[[ATTR7]] = { null_pointer_is_valid } -; CHECK: attributes #[[ATTR8:[0-9]+]] = { norecurse } -; CHECK: attributes #[[ATTR9]] = { willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nosync memory(none) } +; TUNIT: attributes #[[ATTR3:[0-9]+]] = { memory(none) } +; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR6]] = { norecurse nosync memory(none) } +; TUNIT: attributes #[[ATTR7]] = { null_pointer_is_valid } +; TUNIT: attributes #[[ATTR8]] = { norecurse } +; TUNIT: attributes #[[ATTR9]] = { willreturn } +; TUNIT: attributes #[[ATTR10]] = { nosync } +;. +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nosync memory(none) } +; CGSCC: attributes #[[ATTR3:[0-9]+]] = { memory(none) } +; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR6]] = { norecurse nosync memory(none) } +; CGSCC: attributes #[[ATTR7]] = { null_pointer_is_valid } +; CGSCC: attributes #[[ATTR8]] = { norecurse } +; CGSCC: attributes #[[ATTR9]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/noreturn.ll =================================================================== --- llvm/test/Transforms/Attributor/noreturn.ll +++ llvm/test/Transforms/Attributor/noreturn.ll @@ -15,7 +15,7 @@ ; } ; define void @srec0() #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@srec0 ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -34,7 +34,7 @@ ; } ; define i32 @srec16(i32 %a) #0 { -; CHECK: Function Attrs: nofree noinline noreturn nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline noreturn nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@srec16 ; CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: @@ -73,7 +73,7 @@ ; } ; define i32 @endless_loop(i32 %a) #0 { -; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable +; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@endless_loop ; CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: entry: @@ -98,7 +98,7 @@ ; ; FIXME: no-return missing (D65243 should fix this) define i32 @dead_return(i32 %a) #0 { -; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable +; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@dead_return ; CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -126,7 +126,7 @@ ; } ; define i32 @multiple_noreturn_calls(i32 %a) #0 { -; TUNIT: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse noreturn nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@multiple_noreturn_calls ; TUNIT-SAME: (i32 [[A:%.*]]) #[[ATTR3:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -139,7 +139,7 @@ ; TUNIT: cond.end: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree noinline noreturn nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline noreturn nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@multiple_noreturn_calls ; CGSCC-SAME: (i32 [[A:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -174,7 +174,7 @@ ; FIXME: we should derive "UB" as an argument and report it to the user on request. define i32 @endless_loop_but_willreturn() willreturn { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@endless_loop_but_willreturn ; TUNIT-SAME: () #[[ATTR4:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -182,7 +182,7 @@ ; TUNIT: while.body: ; TUNIT-NEXT: br label [[WHILE_BODY]] ; -; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@endless_loop_but_willreturn ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -199,13 +199,13 @@ ; TEST 6b: willreturn means *not* no-return or UB define i32 @UB_and_willreturn() willreturn { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@UB_and_willreturn ; TUNIT-SAME: () #[[ATTR4]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@UB_and_willreturn ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: entry: @@ -217,14 +217,14 @@ attributes #0 = { noinline nounwind uwtable } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree noinline nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR2]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } -; TUNIT: attributes #[[ATTR3]] = { nofree noinline norecurse noreturn nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR4]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR2]] = { nofree noinline norecurse noreturn nosync nounwind memory(none) uwtable } +; TUNIT: attributes #[[ATTR3]] = { nofree noinline norecurse noreturn nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR4]] = { nofree norecurse noreturn nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree noinline nosync nounwind readnone willreturn uwtable } -; CGSCC: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone willreturn uwtable } -; CGSCC: attributes #[[ATTR2]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } -; CGSCC: attributes #[[ATTR3]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR2]] = { nofree noinline norecurse noreturn nosync nounwind memory(none) uwtable } +; CGSCC: attributes #[[ATTR3]] = { nofree norecurse noreturn nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/noreturn_async.ll =================================================================== --- llvm/test/Transforms/Attributor/noreturn_async.ll +++ llvm/test/Transforms/Attributor/noreturn_async.ll @@ -149,6 +149,6 @@ declare i32 @llvm.eh.exceptioncode(token) ;. ; CHECK: attributes #[[ATTR0:[0-9]+]] = { noreturn } -; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind readnone } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(none) } ; CHECK: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind } ;. Index: llvm/test/Transforms/Attributor/noreturn_sync.ll =================================================================== --- llvm/test/Transforms/Attributor/noreturn_sync.ll +++ llvm/test/Transforms/Attributor/noreturn_sync.ll @@ -139,6 +139,6 @@ declare i32 @llvm.eh.exceptioncode(token) ;. -; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone } +; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind memory(none) } ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind } ;. Index: llvm/test/Transforms/Attributor/nosync.ll =================================================================== --- llvm/test/Transforms/Attributor/nosync.ll +++ llvm/test/Transforms/Attributor/nosync.ll @@ -30,7 +30,7 @@ ; CHECK: @[[A:[a-zA-Z0-9_$"\\.-]+]] = common global i32 0, align 4 ;. define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp { -; CHECK: Function Attrs: nofree norecurse nosync nounwind optsize readnone ssp willreturn uwtable +; CHECK: Function Attrs: nofree norecurse nosync nounwind optsize ssp willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@foo ; CHECK-SAME: (%struct.ST* nofree readnone "no-capture-maybe-returned" [[S:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -50,7 +50,7 @@ ; } define i32 @load_monotonic(i32* nocapture readonly %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@load_monotonic ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, i32* [[TMP0]] monotonic, align 4 @@ -68,7 +68,7 @@ ; } define void @store_monotonic(i32* nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn uwtable +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@store_monotonic ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: store atomic i32 10, i32* [[TMP0]] monotonic, align 4 @@ -86,7 +86,7 @@ ; } define i32 @load_acquire(i32* nocapture readonly %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@load_acquire ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, i32* [[TMP0]] acquire, align 4 @@ -103,7 +103,7 @@ ; } define void @load_release(i32* nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@load_release ; CHECK-SAME: (i32* nocapture nofree noundef writeonly align 4 [[TMP0:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0]] release, align 4 @@ -116,7 +116,7 @@ ; TEST 6 - negative volatile, relaxed atomic define void @load_volatile_release(i32* nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@load_volatile_release ; CHECK-SAME: (i32* nocapture nofree noundef writeonly align 4 [[TMP0:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0]] release, align 4 @@ -133,7 +133,7 @@ ; } define void @volatile_store(i32* %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@volatile_store ; CHECK-SAME: (i32* nofree noundef align 4 [[TMP0:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: store volatile i32 14, i32* [[TMP0]], align 4 @@ -151,7 +151,7 @@ ; } define i32 @volatile_load(i32* %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@volatile_load ; CHECK-SAME: (i32* nofree noundef align 4 [[TMP0:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4 @@ -199,14 +199,14 @@ ; volatile operation in same scc but dead. Call volatile_load defined in TEST 8. define i32 @scc1(i32* %0) noinline nounwind uwtable { -; TUNIT: Function Attrs: argmemonly nofree noinline nounwind uwtable +; TUNIT: Function Attrs: nofree noinline nounwind memory(argmem: readwrite) uwtable ; TUNIT-LABEL: define {{[^@]+}}@scc1 ; TUNIT-SAME: (i32* nofree [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] { ; TUNIT-NEXT: tail call void @scc2(i32* nofree [[TMP0]]) #[[ATTR19:[0-9]+]] ; TUNIT-NEXT: [[VAL:%.*]] = tail call i32 @volatile_load(i32* nofree align 4 [[TMP0]]) #[[ATTR19]] ; TUNIT-NEXT: ret i32 [[VAL]] ; -; CGSCC: Function Attrs: argmemonly nofree noinline nounwind uwtable +; CGSCC: Function Attrs: nofree noinline nounwind memory(argmem: readwrite) uwtable ; CGSCC-LABEL: define {{[^@]+}}@scc1 ; CGSCC-SAME: (i32* nofree [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] { ; CGSCC-NEXT: tail call void @scc2(i32* nofree [[TMP0]]) #[[ATTR19:[0-9]+]] @@ -219,7 +219,7 @@ } define void @scc2(i32* %0) noinline nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree noinline nounwind uwtable +; CHECK: Function Attrs: nofree noinline nounwind memory(argmem: readwrite) uwtable ; CHECK-LABEL: define {{[^@]+}}@scc2 ; CHECK-SAME: (i32* nofree [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] { ; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @scc1(i32* nofree [[TMP0]]) #[[ATTR19:[0-9]+]] @@ -349,7 +349,7 @@ ; It is odd to add nocapture but a result of the llvm.memcpy nocapture. ; define i32 @memcpy_volatile(i8* %ptr1, i8* %ptr2) { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@memcpy_volatile ; CHECK-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8* nocapture nofree readonly [[PTR2:%.*]]) #[[ATTR10:[0-9]+]] { ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[PTR1]], i8* noalias nocapture nofree readonly [[PTR2]], i32 noundef 8, i1 noundef true) #[[ATTR20:[0-9]+]] @@ -364,10 +364,10 @@ ; It is odd to add nocapture but a result of the llvm.memset nocapture. ; define i32 @memset_non_volatile(i8* %ptr1, i8 %val) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@memset_non_volatile ; CHECK-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8 [[VAL:%.*]]) #[[ATTR11:[0-9]+]] { -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nocapture nofree writeonly [[PTR1]], i8 [[VAL]], i32 noundef 8, i1 noundef false) #[[ATTR21:[0-9]+]] +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nocapture nofree writeonly [[PTR1]], i8 [[VAL]], i32 noundef 8, i1 noundef false) #[[ATTR20]] ; CHECK-NEXT: ret i32 4 ; call void @llvm.memset(i8* %ptr1, i8 %val, i32 8, i1 0) @@ -390,7 +390,7 @@ ; TEST 17 - negative. Convergent define void @convergent_readnone(){ -; CHECK: Function Attrs: readnone +; CHECK: Function Attrs: memory(none) ; CHECK-LABEL: define {{[^@]+}}@convergent_readnone ; CHECK-SAME: () #[[ATTR13:[0-9]+]] { ; CHECK-NEXT: call void @readnone_test() @@ -423,7 +423,7 @@ ; TEST 19 - positive, readnone & non-convergent intrinsic. define i32 @cos_test(float %x) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@cos_test ; CHECK-SAME: (float [[X:%.*]]) #[[ATTR15:[0-9]+]] { ; CHECK-NEXT: ret i32 4 @@ -433,37 +433,35 @@ } define float @cos_test2(float %x) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@cos_test2 ; CHECK-SAME: (float [[X:%.*]]) #[[ATTR15]] { -; CHECK-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR22:[0-9]+]] +; CHECK-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR20]] ; CHECK-NEXT: ret float [[C]] ; %c = call float @llvm.cos(float %x) ret float %c } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind optsize readnone ssp willreturn uwtable } -; CHECK: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn uwtable } -; CHECK: attributes #[[ATTR2]] = { argmemonly nofree norecurse nounwind willreturn uwtable } +; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind optsize ssp willreturn memory(none) uwtable } +; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable } +; CHECK: attributes #[[ATTR2]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable } ; CHECK: attributes #[[ATTR3]] = { noinline nosync nounwind uwtable } ; CHECK: attributes #[[ATTR4]] = { noinline nounwind uwtable } -; CHECK: attributes #[[ATTR5]] = { argmemonly nofree noinline nounwind uwtable } +; CHECK: attributes #[[ATTR5]] = { nofree noinline nounwind memory(argmem: readwrite) uwtable } ; CHECK: attributes #[[ATTR6]] = { nofree norecurse nounwind willreturn } ; CHECK: attributes #[[ATTR7]] = { nofree norecurse nounwind } ; CHECK: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn } ; CHECK: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind } -; CHECK: attributes #[[ATTR10]] = { argmemonly nofree norecurse nounwind willreturn } -; CHECK: attributes #[[ATTR11]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CHECK: attributes #[[ATTR12:[0-9]+]] = { convergent readnone } -; CHECK: attributes #[[ATTR13]] = { readnone } +; CHECK: attributes #[[ATTR10]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) } +; CHECK: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CHECK: attributes #[[ATTR12:[0-9]+]] = { convergent memory(none) } +; CHECK: attributes #[[ATTR13]] = { memory(none) } ; CHECK: attributes #[[ATTR14]] = { nounwind } -; CHECK: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR16:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } -; CHECK: attributes #[[ATTR17:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } -; CHECK: attributes #[[ATTR18:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CHECK: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CHECK: attributes #[[ATTR16:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +; CHECK: attributes #[[ATTR17:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } +; CHECK: attributes #[[ATTR18:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CHECK: attributes #[[ATTR19]] = { nofree nounwind } ; CHECK: attributes #[[ATTR20]] = { willreturn } -; CHECK: attributes #[[ATTR21]] = { willreturn writeonly } -; CHECK: attributes #[[ATTR22]] = { readnone willreturn } ;. Index: llvm/test/Transforms/Attributor/nounwind.ll =================================================================== --- llvm/test/Transforms/Attributor/nounwind.ll +++ llvm/test/Transforms/Attributor/nounwind.ll @@ -4,7 +4,7 @@ ; TEST 1 define i32 @foo1() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@foo1 ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret i32 1 @@ -14,12 +14,12 @@ ; TEST 2 define i32 @scc1_foo() { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@scc1_foo ; TUNIT-SAME: () #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: ret i32 1 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@scc1_foo ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: ret i32 1 @@ -31,12 +31,12 @@ ; TEST 3 define i32 @scc1_bar() { -; TUNIT: Function Attrs: nofree nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@scc1_bar ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i32 1 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@scc1_bar ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: ret i32 1 @@ -145,8 +145,8 @@ declare void @__cxa_end_catch() ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/openmp_parallel.ll =================================================================== --- llvm/test/Transforms/Attributor/openmp_parallel.ll +++ llvm/test/Transforms/Attributor/openmp_parallel.ll @@ -69,7 +69,7 @@ ; TUNIT-NEXT: br label [[OMP_PRECOND_THEN:%.*]] ; TUNIT: omp.precond.then: ; TUNIT-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -; TUNIT-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) +; TUNIT-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) #[[ATTR3:[0-9]+]] ; TUNIT-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 ; TUNIT-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* ; TUNIT-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) @@ -129,7 +129,7 @@ ; CGSCC-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] ; CGSCC: omp.precond.then: ; CGSCC-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -; CGSCC-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; CGSCC-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR3:[0-9]+]] ; CGSCC-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 ; CGSCC-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* ; CGSCC-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) @@ -264,7 +264,8 @@ ;. ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind uwtable } ; CHECK: attributes #[[ATTR1:[0-9]+]] = { alwaysinline nofree norecurse nounwind uwtable } -; CHECK: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CHECK: attributes #[[ATTR3:[0-9]+]] = { memory(readwrite) } ;. ; CHECK: [[META0:![0-9]+]] = !{i32 7, !"openmp", i32 50} ; CHECK: [[META1:![0-9]+]] = !{!2} Index: llvm/test/Transforms/Attributor/pointer-info.ll =================================================================== --- llvm/test/Transforms/Attributor/pointer-info.ll +++ llvm/test/Transforms/Attributor/pointer-info.ll @@ -6,7 +6,7 @@ %struct.test.a = type { %struct.test.b, i32, i8*} define void @foo(i8* %ptr) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@foo ; TUNIT-SAME: (i8* nocapture nofree readnone [[PTR:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -17,7 +17,7 @@ ; TUNIT-NEXT: tail call void @bar(%struct.test.a* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_TEST_A]]) align 8 dereferenceable(24) [[TMP0]]) #[[ATTR2:[0-9]+]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -41,7 +41,7 @@ } define void @bar(%struct.test.a* noundef byval(%struct.test.a) align 8 %dev) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@bar ; CHECK-SAME: (%struct.test.a* noalias nocapture nofree noundef nonnull writeonly byval([[STRUCT_TEST_A:%.*]]) align 8 dereferenceable(24) [[DEV:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_TEST_A]], %struct.test.a* [[DEV]], i64 0, i32 0 @@ -55,11 +55,11 @@ ret void } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/potential.ll =================================================================== --- llvm/test/Transforms/Attributor/potential.ll +++ llvm/test/Transforms/Attributor/potential.ll @@ -9,7 +9,7 @@ ; bool potential_test1(bool c) { return iszero(c ? 1 : -1); } define internal i1 @iszero1(i32 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@iszero1 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 @@ -20,12 +20,12 @@ } define i1 @potential_test1(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test1 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: ret i1 false ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test1 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[ARG:%.*]] = select i1 [[C]], i32 -1, i32 1 @@ -47,7 +47,7 @@ ; int potential_test2(int x) { return call_with_two_values(1) + call_with_two_values(-1); } define internal i32 @iszero2(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@iszero2 ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 @@ -60,7 +60,7 @@ } define internal i32 @call_with_two_values(i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@call_with_two_values ; TUNIT-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 noundef [[C]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] @@ -69,7 +69,7 @@ ; TUNIT-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] ; TUNIT-NEXT: ret i32 [[RET]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@call_with_two_values ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 noundef [[C]]) #[[ATTR2]] @@ -86,7 +86,7 @@ } define i32 @potential_test2(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test2 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 noundef 1) #[[ATTR1]], !range [[RNG1:![0-9]+]] @@ -94,7 +94,7 @@ ; TUNIT-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] ; TUNIT-NEXT: ret i32 [[RET]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test2 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 noundef 1) #[[ATTR2]] @@ -120,7 +120,7 @@ ; int potential_test3() { return zero_or_one(iszero(0))+zero_or_one(iszero(1)); } define internal i32 @iszero3(i32 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@iszero3 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 @@ -133,7 +133,7 @@ } define internal i32 @less_than_two(i32 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@less_than_two ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 2 @@ -146,12 +146,12 @@ } define i32 @potential_test3() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test3 ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: ret i32 2 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test3 ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) #[[ATTR2]] @@ -181,7 +181,7 @@ ; int potential_test7(int c) { return return1or3(c) == return3or4(c); } define i32 @potential_test4(i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test4 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]] @@ -189,7 +189,7 @@ ; TUNIT-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 ; TUNIT-NEXT: ret i32 [[RET]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test4 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]] @@ -204,7 +204,7 @@ } define i32 @potential_test5(i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test5 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]] @@ -213,7 +213,7 @@ ; TUNIT-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 ; TUNIT-NEXT: ret i32 [[RET]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test5 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]] @@ -230,14 +230,14 @@ } define i1 @potential_test6(i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test6 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]] ; TUNIT-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 ; TUNIT-NEXT: ret i1 [[RET]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test6 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]] @@ -250,7 +250,7 @@ } define i1 @potential_test7(i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test7 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]] @@ -258,7 +258,7 @@ ; TUNIT-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] ; TUNIT-NEXT: ret i1 [[RET]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test7 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]] @@ -273,7 +273,7 @@ } define internal i32 @return1or3(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@return1or3 ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 @@ -286,7 +286,7 @@ } define internal i32 @return2or4(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@return2or4 ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 @@ -299,7 +299,7 @@ } define internal i32 @return3or4(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@return3or4 ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 @@ -316,7 +316,7 @@ ; propagate argument to callsite argument define internal i1 @cmp_with_four(i32 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@cmp_with_four ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 4 @@ -327,7 +327,7 @@ } define internal i1 @wrapper(i32 %c) { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@wrapper ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[RET:%.*]] = call i1 @cmp_with_four(i32 noundef [[C]]) #[[ATTR2]] @@ -338,12 +338,12 @@ } define i1 @potential_test8() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test8 ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: ret i1 false ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test8 ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: [[RES1:%.*]] = call i1 @wrapper(i32 noundef 1) #[[ATTR2]] @@ -362,7 +362,7 @@ } define i1 @potential_test9() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@potential_test9 ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -405,7 +405,7 @@ ; and returned value of @potential_test10 can be simplified to 0(false) define internal i32 @may_return_undef(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@may_return_undef ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ @@ -430,14 +430,14 @@ } define i1 @potential_test10(i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test10 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) #[[ATTR1]] ; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0 ; TUNIT-NEXT: ret i1 [[CMP]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test10 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) #[[ATTR2]] @@ -450,7 +450,7 @@ } define i32 @optimize_undef_1(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@optimize_undef_1 ; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -469,7 +469,7 @@ } define i32 @optimize_undef_2(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@optimize_undef_2 ; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -488,7 +488,7 @@ } define i32 @optimize_undef_3(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@optimize_undef_3 ; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -511,7 +511,7 @@ ; FIXME: returned value can be simplified to 0 define i32 @potential_test11(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test11 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR1]], !range [[RNG0]] @@ -521,7 +521,7 @@ ; TUNIT-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] ; TUNIT-NEXT: ret i32 [[ACC2]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test11 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR2]] @@ -540,7 +540,7 @@ } define i32 @optimize_poison_1(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@optimize_poison_1 ; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -560,12 +560,12 @@ ; FIXME: returned value can be simplified to 0 define i32 @potential_test12(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test12 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test12 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[ZERO:%.*]] = call i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]] @@ -581,7 +581,7 @@ ; However, we should not simplify `and i32 %c, 3` to `%c` define internal i32 @potential_test13_callee(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@potential_test13_callee ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[RET:%.*]] = and i32 [[C]], 3 @@ -592,13 +592,13 @@ } define i32 @potential_test13_caller1() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test13_caller1 ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR1]], !range [[RNG0]] ; TUNIT-NEXT: ret i32 [[RET]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test13_caller1 ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]] @@ -609,13 +609,13 @@ } define i32 @potential_test13_caller2() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test13_caller2 ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR1]], !range [[RNG0]] ; TUNIT-NEXT: ret i32 [[RET]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test13_caller2 ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]] @@ -626,13 +626,13 @@ } define i32 @potential_test13_caller3() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test13_caller3 ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR1]], !range [[RNG0]] ; TUNIT-NEXT: ret i32 [[RET]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test13_caller3 ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR2]] @@ -643,7 +643,7 @@ } define i1 @potential_test14(i1 %c0, i1 %c1, i1 %c2, i1 %c3) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@potential_test14 ; CHECK-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1 @@ -662,7 +662,7 @@ } define i1 @potential_test15(i1 %c0, i1 %c1) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@potential_test15 ; CHECK-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1 @@ -677,7 +677,7 @@ } define i1 @potential_test16(i1 %c0, i1 %c1) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@potential_test16 ; CHECK-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[X1:%.*]] = select i1 [[C1]], i32 0, i32 1 @@ -691,12 +691,12 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { willreturn } ;. ; TUNIT: [[RNG0]] = !{i32 0, i32 2} ; TUNIT: [[RNG1]] = !{i32 0, i32 3} Index: llvm/test/Transforms/Attributor/range.ll =================================================================== --- llvm/test/Transforms/Attributor/range.ll +++ llvm/test/Transforms/Attributor/range.ll @@ -5,7 +5,7 @@ ; FIXME: CGSCC is not looking at callees and calleers even though it could be allowed. define i32 @test0(i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@test0 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, !range [[RNG0:![0-9]+]] @@ -16,13 +16,13 @@ } define i32 @test0-range-check(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@test0-range-check ; TUNIT-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #[[ATTR3:[0-9]+]], !range [[RNG0]] ; TUNIT-NEXT: ret i32 [[A]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test0-range-check ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5:[0-9]+]] @@ -269,7 +269,7 @@ ret void } define i32 @test1(i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@test1 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, !range [[RNG1:![0-9]+]] @@ -285,14 +285,14 @@ define i1 @test1-check(i32* %p) { ; -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@test1-check ; TUNIT-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #[[ATTR3]], !range [[RNG2:![0-9]+]] ; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 ; TUNIT-NEXT: ret i1 [[CMP]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test1-check ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5]] @@ -317,7 +317,7 @@ ; } define i32 @test2(i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@test2 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -334,7 +334,7 @@ } define i32 @test2_check(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@test2_check ; TUNIT-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -349,7 +349,7 @@ ; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ] ; TUNIT-NEXT: ret i32 [[RETVAL_0]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test2_check ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -408,7 +408,7 @@ declare dso_local void @unkown() define internal i32 @r1(i32) local_unnamed_addr { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@r1 ; TUNIT-SAME: () local_unnamed_addr #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: br label [[TMP4:%.*]] @@ -427,7 +427,7 @@ ; TUNIT-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100 ; TUNIT-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@r1 ; CGSCC-SAME: () local_unnamed_addr #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: br label [[TMP4:%.*]] @@ -467,7 +467,7 @@ define void @f1(i32){ ; TUNIT-LABEL: define {{[^@]+}}@f1 ; TUNIT-SAME: (i32 [[TMP0:%.*]]) { -; TUNIT-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR4:[0-9]+]] +; TUNIT-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR3]] ; TUNIT-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15 ; TUNIT-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] ; TUNIT: 4: @@ -478,7 +478,7 @@ ; ; CGSCC-LABEL: define {{[^@]+}}@f1 ; CGSCC-SAME: (i32 [[TMP0:%.*]]) { -; CGSCC-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR6:[0-9]+]] +; CGSCC-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR5]] ; CGSCC-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15 ; CGSCC-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] ; CGSCC: 4: @@ -510,7 +510,7 @@ ; } ; } define dso_local i32 @test4-f1(i32 %u) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test4-f1 ; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -522,7 +522,7 @@ ; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ] ; TUNIT-NEXT: ret i32 [[RETVAL_0]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test4-f1 ; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: @@ -549,18 +549,18 @@ define dso_local i32 @test4-g1(i32 %u) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test4-g1 ; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR4]] +; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR3]] ; TUNIT-NEXT: ret i32 [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test4-g1 ; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR6]] +; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR5]] ; CGSCC-NEXT: ret i32 [[CALL]] ; ; FIXME: %call should have range [0, inf] @@ -579,7 +579,7 @@ ; } ; } define dso_local i32 @test4-f2(i32 %u) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test4-f2 ; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -594,7 +594,7 @@ ; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ] ; TUNIT-NEXT: ret i32 [[RETVAL_0]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test4-f2 ; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: @@ -627,18 +627,18 @@ define dso_local i32 @test4-g2(i32 %u) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test4-g2 ; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR4]], !range [[RNG3:![0-9]+]] +; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR3]], !range [[RNG3:![0-9]+]] ; TUNIT-NEXT: ret i32 [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test4-g2 ; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR6]] +; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR5]] ; CGSCC-NEXT: ret i32 [[CALL]] ; entry: @@ -718,7 +718,7 @@ ; FIXME: All but the return is not needed anymore define dso_local zeroext i1 @phi(i32 %arg) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@phi ; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: bb: @@ -750,7 +750,7 @@ ; TUNIT-NEXT: [[DOT0:%.*]] = phi i1 [ true, [[BB11]] ], [ false, [[BB12]] ] ; TUNIT-NEXT: ret i1 [[DOT0]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@phi ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: bb: @@ -822,7 +822,7 @@ } define dso_local i1 @select(i32 %a) local_unnamed_addr #0 { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@select ; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -834,7 +834,7 @@ ; TUNIT-NEXT: [[CMP6:%.*]] = icmp eq i32 [[Y_0]], 5 ; TUNIT-NEXT: ret i1 [[CMP6]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@select ; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] { ; CGSCC-NEXT: entry: @@ -857,7 +857,7 @@ } define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@select_zext ; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -870,7 +870,7 @@ ; TUNIT-NEXT: [[DOT13:%.*]] = zext i1 [[CMP6]] to i32 ; TUNIT-NEXT: ret i32 [[DOT13]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@select_zext ; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] { ; CGSCC-NEXT: entry: @@ -895,7 +895,7 @@ } define dso_local i64 @select_int2ptr_bitcast_ptr2int(i32 %a) local_unnamed_addr #0 { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int ; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -910,7 +910,7 @@ ; TUNIT-NEXT: [[P2I:%.*]] = ptrtoint i32* [[BC]] to i64 ; TUNIT-NEXT: ret i64 [[P2I]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int ; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] { ; CGSCC-NEXT: entry: @@ -941,14 +941,14 @@ ; } define i1 @f_fcmp(float %a, float %b) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@f_fcmp ; TUNIT-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]] ; TUNIT-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false ; TUNIT-NEXT: ret i1 [[S]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@f_fcmp ; CGSCC-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]] @@ -960,14 +960,14 @@ ret i1 %s } define i1 @d_fcmp(double %a, double %b) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@d_fcmp ; TUNIT-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]] ; TUNIT-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false ; TUNIT-NEXT: ret i1 [[S]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@d_fcmp ; CGSCC-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]] @@ -979,14 +979,14 @@ ret i1 %s } define i1 @dp_icmp(double* %a, double* %b) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@dp_icmp ; TUNIT-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]] ; TUNIT-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false ; TUNIT-NEXT: ret i1 [[S]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@dp_icmp ; CGSCC-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]] @@ -998,14 +998,14 @@ ret i1 %s } define i1 @ip_icmp(i8* %a, i8* %b) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ip_icmp ; TUNIT-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]] ; TUNIT-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false ; TUNIT-NEXT: ret i1 [[S]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ip_icmp ; CGSCC-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]] @@ -1017,25 +1017,25 @@ ret i1 %s } define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dpa, double* %dpb, i8* %ipa, i8* %ipb) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@fcmp_caller ; TUNIT-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR1]] { -; TUNIT-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR4]] -; TUNIT-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR4]] -; TUNIT-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR4]] -; TUNIT-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR4]] +; TUNIT-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR3]] +; TUNIT-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR3]] +; TUNIT-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR3]] +; TUNIT-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR3]] ; TUNIT-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] ; TUNIT-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] ; TUNIT-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] ; TUNIT-NEXT: ret i1 [[O3]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@fcmp_caller ; CGSCC-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR6]] -; CGSCC-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR6]] -; CGSCC-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR6]] -; CGSCC-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR6]] +; CGSCC-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR5]] +; CGSCC-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR5]] +; CGSCC-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR5]] +; CGSCC-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR5]] ; CGSCC-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] ; CGSCC-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] ; CGSCC-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] @@ -1052,12 +1052,12 @@ } define i8 @ret_two() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ret_two ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 2 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ret_two ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: ret i8 2 @@ -1065,12 +1065,12 @@ ret i8 2 } define i8 @ret_undef() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ret_undef ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 undef ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ret_undef ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: ret i8 undef @@ -1080,15 +1080,15 @@ ; Verify we collapse undef to a value and return something non-undef here. define i8 @undef_collapse_1() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_1 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_1 ; CGSCC-SAME: () #[[ATTR3]] { -; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_undef() #[[ATTR6]] +; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_undef() #[[ATTR5]] ; CGSCC-NEXT: [[S:%.*]] = shl i8 [[C]], 2 ; CGSCC-NEXT: ret i8 [[S]] ; @@ -1099,15 +1099,15 @@ ; Verify we collapse undef to a value and return something non-undef here. define i8 @undef_collapse_2() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_2 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_2 ; CGSCC-SAME: () #[[ATTR3]] { -; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_two() #[[ATTR6]] +; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_two() #[[ATTR5]] ; CGSCC-NEXT: [[S:%.*]] = shl i8 undef, [[C]] ; CGSCC-NEXT: ret i8 [[S]] ; @@ -1118,16 +1118,16 @@ define i8 @undef_collapse_caller() { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_caller ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_caller ; CGSCC-SAME: () #[[ATTR3]] { -; CGSCC-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR6]] -; CGSCC-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR6]] +; CGSCC-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR5]] +; CGSCC-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR5]] ; CGSCC-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]] ; CGSCC-NEXT: ret i8 [[A]] ; @@ -1138,13 +1138,13 @@ } define i32 @ret1or2(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ret1or2 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2 ; TUNIT-NEXT: ret i32 [[S]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ret1or2 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2 @@ -1155,11 +1155,11 @@ } define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@callee_range_1 ; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR1]] { -; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]] -; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]] +; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR3]] +; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR3]] ; TUNIT-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]] ; TUNIT-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]] ; TUNIT-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4 @@ -1167,11 +1167,11 @@ ; TUNIT-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] ; TUNIT-NEXT: ret i1 [[F]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@callee_range_1 ; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR6]] -; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR6]] +; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR5]] +; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR5]] ; CGSCC-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]] ; CGSCC-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]] ; CGSCC-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4 @@ -1191,22 +1191,22 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@callee_range_2 ; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] { -; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]] -; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]] +; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR3]] +; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR3]] ; TUNIT-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] ; TUNIT-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 ; TUNIT-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 ; TUNIT-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] ; TUNIT-NEXT: ret i1 [[F]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@callee_range_2 ; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR6]] -; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR6]] +; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR5]] +; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR5]] ; CGSCC-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] ; CGSCC-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 ; CGSCC-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 @@ -1224,12 +1224,12 @@ define i32 @ret100() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ret100 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i32 100 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ret100 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: ret i32 100 @@ -1239,7 +1239,7 @@ define i1 @ctx_adjustment(i32 %V) { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ctx_adjustment ; TUNIT-SAME: (i32 [[V:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 @@ -1253,7 +1253,7 @@ ; TUNIT-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100 ; TUNIT-NEXT: ret i1 [[C2]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ctx_adjustment ; CGSCC-SAME: (i32 [[V:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 @@ -1261,7 +1261,7 @@ ; CGSCC: if.true: ; CGSCC-NEXT: br label [[END:%.*]] ; CGSCC: if.false: -; CGSCC-NEXT: [[CALL:%.*]] = call i32 @ret100() #[[ATTR6]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32 @ret100() #[[ATTR5]] ; CGSCC-NEXT: br label [[END]] ; CGSCC: end: ; CGSCC-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ [[CALL]], [[IF_FALSE]] ] @@ -1283,13 +1283,13 @@ define i32 @func(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@func ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1 ; TUNIT-NEXT: ret i32 [[RET]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@func ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1 @@ -1300,28 +1300,28 @@ } define i32 @simplify_callsite_argument(i1 %d) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@simplify_callsite_argument ; TUNIT-SAME: (i1 [[D:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; TUNIT: t: -; TUNIT-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR4]] +; TUNIT-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR3]] ; TUNIT-NEXT: ret i32 [[RET1]] ; TUNIT: f: -; TUNIT-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR4]] +; TUNIT-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR3]] ; TUNIT-NEXT: ret i32 [[RET2]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@simplify_callsite_argument ; CGSCC-SAME: (i1 [[D:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; CGSCC: t: -; CGSCC-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR6]] +; CGSCC-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR5]] ; CGSCC-NEXT: ret i32 [[RET1]] ; CGSCC: f: -; CGSCC-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR6]] +; CGSCC-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR5]] ; CGSCC-NEXT: ret i32 [[RET2]] ; %c = select i1 %d, i1 true, i1 false @@ -1336,7 +1336,7 @@ define internal i32 @less_than_65536(i32 %arg) { ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@less_than_65536 ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[SHRINKED:%.*]] = udiv i32 [[ARG]], 65536 @@ -1347,7 +1347,7 @@ } define internal i1 @is_less_than_65536(i32 %arg) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@is_less_than_65536 ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[CMP:%.*]] = icmp ult i32 [[ARG]], 65536 @@ -1358,18 +1358,18 @@ } define i1 @check_divided_range(i32 %arg) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@check_divided_range ; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@check_divided_range ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR6]] -; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR6]] -; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR6]] -; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR6]] +; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR5]] +; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR5]] +; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR5]] +; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR5]] ; CGSCC-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]] ; CGSCC-NEXT: ret i1 [[RET]] ; @@ -1383,7 +1383,7 @@ define internal i32 @cast_and_return(i1 %c) { ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@cast_and_return ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[RET:%.*]] = zext i1 [[C]] to i32 @@ -1394,7 +1394,7 @@ } define internal i1 @is_less_than_3(i32 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@is_less_than_3 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 3 @@ -1405,18 +1405,18 @@ } define i1 @check_casted_range(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@check_casted_range ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@check_casted_range ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR6]] -; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR6]] +; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR5]] +; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR5]] ; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; CGSCC-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR6]] +; CGSCC-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[RET]] ; %csret1 = call i32 @cast_and_return(i1 true) @@ -1427,7 +1427,7 @@ } define internal i32 @less_than_100_1(i32 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@less_than_100_1 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ @@ -1482,7 +1482,7 @@ } define internal i1 @is_less_than_100_1(i32 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@is_less_than_100_1 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 @@ -1493,16 +1493,16 @@ } define i1 @propagate_range1(i32 %c){ -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@propagate_range1 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@propagate_range1 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 [[C]]) #[[ATTR6]] -; CGSCC-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR6]] +; CGSCC-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 [[C]]) #[[ATTR5]] +; CGSCC-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[TRUE]] ; %csret = call i32 @less_than_100_1(i32 %c) @@ -1512,7 +1512,7 @@ define internal i32 @less_than_100_2(i32 %c) { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@less_than_100_2 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ @@ -1541,7 +1541,7 @@ ; TUNIT: otherwise: ; TUNIT-NEXT: ret i32 99 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@less_than_100_2 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ @@ -1597,13 +1597,13 @@ define internal i1 @is_less_than_100_2(i32 %c) { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@is_less_than_100_2 ; TUNIT-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 ; TUNIT-NEXT: ret i1 [[CMP]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@is_less_than_100_2 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 @@ -1614,23 +1614,23 @@ } define i1 @propagate_range2(i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@propagate_range2 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { -; TUNIT-NEXT: [[CSRET1:%.*]] = call noundef i32 @less_than_100_2(i32 noundef 0) #[[ATTR4]] -; TUNIT-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR4]] -; TUNIT-NEXT: [[CSRET2:%.*]] = call noundef i32 @less_than_100_2(i32 [[C]]) #[[ATTR4]] -; TUNIT-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR4]] +; TUNIT-NEXT: [[CSRET1:%.*]] = call noundef i32 @less_than_100_2(i32 noundef 0) #[[ATTR3]] +; TUNIT-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR3]] +; TUNIT-NEXT: [[CSRET2:%.*]] = call noundef i32 @less_than_100_2(i32 [[C]]) #[[ATTR3]] +; TUNIT-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR3]] ; TUNIT-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]] ; TUNIT-NEXT: ret i1 [[TRUE]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@propagate_range2 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR6]] -; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR6]] -; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) #[[ATTR6]] -; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR6]] +; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR5]] +; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR5]] +; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) #[[ATTR5]] +; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR5]] ; CGSCC-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]] ; CGSCC-NEXT: ret i1 [[TRUE]] ; @@ -1643,13 +1643,13 @@ } define internal i1 @non_zero(i8 %v) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@non_zero ; TUNIT-SAME: (i8 [[V:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0 ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@non_zero ; CGSCC-SAME: (i8 [[V:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0 @@ -1661,26 +1661,26 @@ ; Avoid range metadata for %l below define i1 @context(i8* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@context ; TUNIT-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 ; TUNIT-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; TUNIT: t: -; TUNIT-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR4]] +; TUNIT-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR3]] ; TUNIT-NEXT: ret i1 [[R]] ; TUNIT: f: ; TUNIT-NEXT: ret i1 false ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@context ; CGSCC-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 ; CGSCC-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; CGSCC: t: -; CGSCC-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR6]] +; CGSCC-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[R]] ; CGSCC: f: ; CGSCC-NEXT: ret i1 false @@ -1759,7 +1759,7 @@ } define i1 @loop_1(i32 %N) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@loop_1 ; TUNIT-SAME: (i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -1774,7 +1774,7 @@ ; TUNIT-NEXT: [[R:%.*]] = icmp sle i32 [[I]], 5 ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone +; CGSCC: Function Attrs: nofree norecurse nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@loop_1 ; CGSCC-SAME: (i32 [[N:%.*]]) #[[ATTR4:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -1810,19 +1810,17 @@ !0 = !{i32 0, i32 10} !1 = !{i32 10, i32 100} ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } -; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(none) } +; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readnone } -; CGSCC: attributes #[[ATTR5]] = { readonly willreturn } -; CGSCC: attributes #[[ATTR6]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind memory(none) } +; CGSCC: attributes #[[ATTR5]] = { willreturn } ;. ; TUNIT: [[RNG0]] = !{i32 0, i32 10} ; TUNIT: [[RNG1]] = !{i32 10, i32 100} Index: llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll =================================================================== --- llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll +++ llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll @@ -33,7 +33,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@external_ret2_nrw ; TUNIT-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree returned [[W0:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -43,7 +43,7 @@ ; TUNIT-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]]) #[[ATTR3]] ; TUNIT-NEXT: ret i32* [[W0]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@external_ret2_nrw ; CGSCC-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree returned [[W0:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -62,7 +62,7 @@ } define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@internal_ret0_nw ; TUNIT-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -87,7 +87,7 @@ ; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ] ; TUNIT-NEXT: ret i32* [[RETVAL_0]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@internal_ret0_nw ; CGSCC-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: @@ -104,8 +104,8 @@ ; CGSCC-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; CGSCC-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; CGSCC-NEXT: [[CALL2:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] -; CGSCC-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] -; CGSCC-NEXT: [[CALL4:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; CGSCC-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR4:[0-9]+]] +; CGSCC-NEXT: [[CALL4:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR4]] ; CGSCC-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; CGSCC-NEXT: br label [[RETURN]] ; CGSCC: return: @@ -139,7 +139,7 @@ } define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@internal_ret1_rrw ; TUNIT-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree align 4 [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -167,7 +167,7 @@ ; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL8]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ] ; TUNIT-NEXT: ret i32* undef ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@internal_ret1_rrw ; CGSCC-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree align 4 [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: @@ -187,8 +187,8 @@ ; CGSCC-NEXT: [[CALL3:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[W0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; CGSCC-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; CGSCC-NEXT: [[CALL5:%.*]] = call i32* @external_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] -; CGSCC-NEXT: [[CALL6:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] -; CGSCC-NEXT: [[CALL7:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; CGSCC-NEXT: [[CALL6:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR4]] +; CGSCC-NEXT: [[CALL7:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR4]] ; CGSCC-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; CGSCC-NEXT: br label [[RETURN]] ; CGSCC: return: @@ -225,7 +225,7 @@ } define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@external_sink_ret2_nrw ; CHECK-SAME: (i32* nofree [[N0:%.*]], i32* nocapture nofree readonly [[R0:%.*]], i32* nofree returned writeonly "no-capture-maybe-returned" [[W0:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: @@ -257,7 +257,7 @@ } define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@internal_ret1_rw ; TUNIT-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -279,7 +279,7 @@ ; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL4]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ] ; TUNIT-NEXT: ret i32* [[RETVAL_0]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@internal_ret1_rw ; CGSCC-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: @@ -294,7 +294,7 @@ ; CGSCC-NEXT: store i32 [[TMP1]], i32* [[W0]], align 4 ; CGSCC-NEXT: [[CALL1:%.*]] = call i32* @internal_ret0_nw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; CGSCC-NEXT: [[CALL2:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[W0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] -; CGSCC-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; CGSCC-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR4]] ; CGSCC-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; CGSCC-NEXT: br label [[RETURN]] ; CGSCC: return: @@ -325,7 +325,7 @@ } define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@external_source_ret2_nrw ; TUNIT-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree returned [[W0:%.*]]) #[[ATTR2:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -333,11 +333,11 @@ ; TUNIT-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR3]] ; TUNIT-NEXT: ret i32* [[W0]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@external_source_ret2_nrw ; CGSCC-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly [[W0]]) #[[ATTR4:[0-9]+]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly [[W0]]) #[[ATTR5:[0-9]+]] ; CGSCC-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR3]] ; CGSCC-NEXT: ret i32* [[CALL1]] ; @@ -350,15 +350,16 @@ ; Verify that we see only expected attribute sets, the above lines only check ; for a subset relation. ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind } -; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind } +; TUNIT: attributes #[[ATTR0]] = { nofree nosync nounwind memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(argmem: readwrite) } ; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind } ; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } ; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind } ; CGSCC: attributes #[[ATTR3]] = { nounwind } -; CGSCC: attributes #[[ATTR4]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR4]] = { nounwind memory(readwrite) } +; CGSCC: attributes #[[ATTR5]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/readattrs.ll =================================================================== --- llvm/test/Transforms/Attributor/readattrs.ll +++ llvm/test/Transforms/Attributor/readattrs.ll @@ -26,7 +26,7 @@ } define i8* @test2(i8* %p) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CHECK-LABEL: define {{[^@]+}}@test2 ; CHECK-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: store i32 0, i32* @x, align 4 @@ -37,7 +37,7 @@ } define i1 @test3(i8* %p, i8* %q) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test3 ; CHECK-SAME: (i8* nofree readnone [[P:%.*]], i8* nofree readnone [[Q:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = icmp ult i8* [[P]], [[Q]] @@ -50,10 +50,10 @@ declare void @test4_1(i8* nocapture) readonly define void @test4_2(i8* %p) { -; CHECK: Function Attrs: readonly +; CHECK: Function Attrs: memory(read) ; CHECK-LABEL: define {{[^@]+}}@test4_2 ; CHECK-SAME: (i8* nocapture readonly [[P:%.*]]) #[[ATTR2:[0-9]+]] { -; CHECK-NEXT: call void @test4_1(i8* nocapture readonly [[P]]) #[[ATTR2]] +; CHECK-NEXT: call void @test4_1(i8* nocapture readonly [[P]]) ; CHECK-NEXT: ret void ; call void @test4_1(i8* %p) @@ -62,7 +62,7 @@ ; Missed optz'n: we could make %q readnone, but don't break test6! define void @test5(i8** %p, i8* %q) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@test5 ; CHECK-SAME: (i8** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[P:%.*]], i8* nofree writeonly [[Q:%.*]]) #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: store i8* [[Q]], i8** [[P]], align 8 @@ -88,7 +88,7 @@ ; inalloca parameters are always considered written define void @test7_1(i32* inalloca(i32) %a) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test7_1 ; CHECK-SAME: (i32* nocapture nofree nonnull writeonly inalloca(i32) dereferenceable(4) [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: ret void @@ -97,7 +97,7 @@ } define i32* @test8_1(i32* %p) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test8_1 ; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: @@ -108,14 +108,14 @@ } define void @test8_2(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@test8_2 ; TUNIT-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: store i32 10, i32* [[P]], align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test8_2 ; CGSCC-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR4:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -135,16 +135,16 @@ ; CHECK-NOT: readnone ; CHECK-NOT: readonly define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@test9 ; TUNIT-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef ) #[[ATTR12:[0-9]+]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@test9 ; CGSCC-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] { -; CGSCC-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef ) #[[ATTR14:[0-9]+]] +; CGSCC-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef ) #[[ATTR13]] ; CGSCC-NEXT: ret void ; call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32>%val, <4 x i32*> %ptrs, i32 4, <4 x i1>) @@ -154,16 +154,16 @@ ; CHECK: declare <4 x i32> @llvm.masked.gather declare <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*>, i32, <4 x i1>, <4 x i32>) define <4 x i32> @test10(<4 x i32*> %ptrs) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@test10 ; TUNIT-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR6:[0-9]+]] { -; TUNIT-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef , <4 x i32> undef) #[[ATTR13:[0-9]+]] +; TUNIT-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef , <4 x i32> undef) #[[ATTR12]] ; TUNIT-NEXT: ret <4 x i32> [[RES]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@test10 ; CGSCC-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR7:[0-9]+]] { -; CGSCC-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef , <4 x i32> undef) #[[ATTR15:[0-9]+]] +; CGSCC-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef , <4 x i32> undef) #[[ATTR13]] ; CGSCC-NEXT: ret <4 x i32> [[RES]] ; %res = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> %ptrs, i32 4, <4 x i1>, <4 x i32>undef) @@ -173,16 +173,16 @@ ; CHECK: declare <4 x i32> @test11_1 declare <4 x i32> @test11_1(<4 x i32*>) argmemonly nounwind readonly define <4 x i32> @test11_2(<4 x i32*> %ptrs) { -; TUNIT: Function Attrs: argmemonly nounwind readonly +; TUNIT: Function Attrs: nounwind memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@test11_2 ; TUNIT-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR7:[0-9]+]] { -; TUNIT-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) #[[ATTR11:[0-9]+]] +; TUNIT-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) #[[ATTR13:[0-9]+]] ; TUNIT-NEXT: ret <4 x i32> [[RES]] ; -; CGSCC: Function Attrs: argmemonly nounwind readonly +; CGSCC: Function Attrs: nounwind memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test11_2 ; CGSCC-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR8:[0-9]+]] { -; CGSCC-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) #[[ATTR12:[0-9]+]] +; CGSCC-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) #[[ATTR14:[0-9]+]] ; CGSCC-NEXT: ret <4 x i32> [[RES]] ; %res = call <4 x i32> @test11_1(<4 x i32*> %ptrs) @@ -192,16 +192,16 @@ declare <4 x i32> @test12_1(<4 x i32*>) argmemonly nounwind ; CHECK-NOT: readnone define <4 x i32> @test12_2(<4 x i32*> %ptrs) { -; TUNIT: Function Attrs: argmemonly nounwind +; TUNIT: Function Attrs: nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@test12_2 ; TUNIT-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR8:[0-9]+]] { -; TUNIT-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR14:[0-9]+]] +; TUNIT-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR13]] ; TUNIT-NEXT: ret <4 x i32> [[RES]] ; -; CGSCC: Function Attrs: argmemonly nounwind +; CGSCC: Function Attrs: nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@test12_2 ; CGSCC-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR9:[0-9]+]] { -; CGSCC-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR16:[0-9]+]] +; CGSCC-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR14]] ; CGSCC-NEXT: ret <4 x i32> [[RES]] ; %res = call <4 x i32> @test12_1(<4 x i32*> %ptrs) @@ -209,13 +209,13 @@ } define i32 @volatile_load(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@volatile_load ; TUNIT-SAME: (i32* nofree noundef align 4 [[P:%.*]]) #[[ATTR9:[0-9]+]] { ; TUNIT-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4 ; TUNIT-NEXT: ret i32 [[LOAD]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@volatile_load ; CGSCC-SAME: (i32* nofree noundef align 4 [[P:%.*]]) #[[ATTR10:[0-9]+]] { ; CGSCC-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4 @@ -271,7 +271,7 @@ declare void @escape_i8(i8* %ptr) define void @byval_not_readonly_1(i8* byval(i8) %written) readonly { -; CHECK: Function Attrs: readonly +; CHECK: Function Attrs: memory(read) ; CHECK-LABEL: define {{[^@]+}}@byval_not_readonly_1 ; CHECK-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]]) @@ -282,7 +282,7 @@ } define void @byval_not_readonly_2(i8* byval(i8) %written) readonly { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@byval_not_readonly_2 ; CHECK-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: store i8 0, i8* [[WRITTEN]], align 1 @@ -293,13 +293,13 @@ } define void @byval_not_readnone_1(i8* byval(i8) %written) readnone { -; TUNIT: Function Attrs: readnone +; TUNIT: Function Attrs: memory(none) ; TUNIT-LABEL: define {{[^@]+}}@byval_not_readnone_1 ; TUNIT-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR10:[0-9]+]] { ; TUNIT-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]]) ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: readnone +; CGSCC: Function Attrs: memory(none) ; CGSCC-LABEL: define {{[^@]+}}@byval_not_readnone_1 ; CGSCC-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR11:[0-9]+]] { ; CGSCC-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]]) @@ -310,7 +310,7 @@ } define void @byval_not_readnone_2(i8* byval(i8) %written) readnone { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_2 ; CHECK-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: store i8 0, i8* [[WRITTEN]], align 1 @@ -321,7 +321,7 @@ } define void @byval_no_fnarg(i8* byval(i8) %written) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@byval_no_fnarg ; CHECK-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: store i8 0, i8* [[WRITTEN]], align 1 @@ -334,16 +334,16 @@ define void @testbyval(i8* %read_only) { ; TUNIT-LABEL: define {{[^@]+}}@testbyval ; TUNIT-SAME: (i8* nocapture readonly [[READ_ONLY:%.*]]) { -; TUNIT-NEXT: call void @byval_not_readonly_1(i8* nocapture readonly byval(i8) [[READ_ONLY]]) #[[ATTR2]] +; TUNIT-NEXT: call void @byval_not_readonly_1(i8* nocapture readonly byval(i8) [[READ_ONLY]]) ; TUNIT-NEXT: call void @byval_not_readnone_1(i8* noalias nocapture readnone byval(i8) [[READ_ONLY]]) -; TUNIT-NEXT: call void @byval_no_fnarg(i8* nocapture nofree readonly byval(i8) [[READ_ONLY]]) #[[ATTR15:[0-9]+]] +; TUNIT-NEXT: call void @byval_no_fnarg(i8* nocapture nofree readonly byval(i8) [[READ_ONLY]]) #[[ATTR13]] ; TUNIT-NEXT: ret void ; ; CGSCC-LABEL: define {{[^@]+}}@testbyval ; CGSCC-SAME: (i8* nocapture noundef nonnull readonly dereferenceable(1) [[READ_ONLY:%.*]]) { -; CGSCC-NEXT: call void @byval_not_readonly_1(i8* noalias nocapture noundef nonnull readonly byval(i8) dereferenceable(1) [[READ_ONLY]]) #[[ATTR2]] +; CGSCC-NEXT: call void @byval_not_readonly_1(i8* noalias nocapture noundef nonnull readonly byval(i8) dereferenceable(1) [[READ_ONLY]]) ; CGSCC-NEXT: call void @byval_not_readnone_1(i8* noalias nocapture noundef nonnull readnone byval(i8) dereferenceable(1) [[READ_ONLY]]) -; CGSCC-NEXT: call void @byval_no_fnarg(i8* noalias nocapture nofree noundef nonnull readnone byval(i8) dereferenceable(1) [[READ_ONLY]]) #[[ATTR17:[0-9]+]] +; CGSCC-NEXT: call void @byval_no_fnarg(i8* noalias nocapture nofree noundef nonnull readnone byval(i8) dereferenceable(1) [[READ_ONLY]]) #[[ATTR14]] ; CGSCC-NEXT: ret void ; call void @byval_not_readonly_1(i8* byval(i8) %read_only) @@ -360,18 +360,18 @@ declare void @val_use(i8 %ptr) readonly nounwind define void @ptr_uses(i8* %ptr) { -; TUNIT: Function Attrs: nounwind readonly +; TUNIT: Function Attrs: nounwind memory(read) ; TUNIT-LABEL: define {{[^@]+}}@ptr_uses -; TUNIT-SAME: (i8* nocapture readonly [[PTR:%.*]]) #[[ATTR11]] { -; TUNIT-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]]) #[[ATTR11]] -; TUNIT-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]]) #[[ATTR11]] +; TUNIT-SAME: (i8* nocapture readonly [[PTR:%.*]]) #[[ATTR11:[0-9]+]] { +; TUNIT-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]]) #[[ATTR13]] +; TUNIT-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]]) #[[ATTR13]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nounwind readonly +; CGSCC: Function Attrs: nounwind memory(read) ; CGSCC-LABEL: define {{[^@]+}}@ptr_uses -; CGSCC-SAME: (i8* nocapture readonly [[PTR:%.*]]) #[[ATTR12]] { -; CGSCC-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]]) #[[ATTR12]] -; CGSCC-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]]) #[[ATTR12]] +; CGSCC-SAME: (i8* nocapture readonly [[PTR:%.*]]) #[[ATTR12:[0-9]+]] { +; CGSCC-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]]) #[[ATTR14]] +; CGSCC-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]]) #[[ATTR14]] ; CGSCC-NEXT: ret void ; %call_ptr = call i8* @maybe_returned_ptr(i8* %ptr) @@ -410,7 +410,7 @@ @constant_mem = external dso_local constant i32, align 4 define i32 @read_only_constant_mem() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@read_only_constant_mem ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: [[L:%.*]] = load i32, i32* @constant_mem, align 4 @@ -420,39 +420,34 @@ ret i32 %l } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { readonly } -; TUNIT: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR7]] = { argmemonly nounwind readonly } -; TUNIT: attributes #[[ATTR8]] = { argmemonly nounwind } -; TUNIT: attributes #[[ATTR9]] = { argmemonly nofree norecurse nounwind willreturn } -; TUNIT: attributes #[[ATTR10]] = { readnone } -; TUNIT: attributes #[[ATTR11]] = { nounwind readonly } -; TUNIT: attributes #[[ATTR12]] = { willreturn writeonly } -; TUNIT: attributes #[[ATTR13]] = { readonly willreturn } -; TUNIT: attributes #[[ATTR14]] = { nounwind } -; TUNIT: attributes #[[ATTR15]] = { nounwind writeonly } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { memory(read) } +; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(write) } +; TUNIT: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(read) } +; TUNIT: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn memory(read) } +; TUNIT: attributes #[[ATTR7]] = { nounwind memory(argmem: read) } +; TUNIT: attributes #[[ATTR8]] = { nounwind memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR10]] = { memory(none) } +; TUNIT: attributes #[[ATTR11]] = { nounwind memory(read) } +; TUNIT: attributes #[[ATTR12]] = { willreturn } +; TUNIT: attributes #[[ATTR13]] = { nounwind } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { readonly } -; CGSCC: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR8]] = { argmemonly nounwind readonly } -; CGSCC: attributes #[[ATTR9]] = { argmemonly nounwind } -; CGSCC: attributes #[[ATTR10]] = { argmemonly nofree norecurse nounwind willreturn } -; CGSCC: attributes #[[ATTR11]] = { readnone } -; CGSCC: attributes #[[ATTR12]] = { nounwind readonly } -; CGSCC: attributes #[[ATTR13]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR14]] = { willreturn writeonly } -; CGSCC: attributes #[[ATTR15]] = { readonly willreturn } -; CGSCC: attributes #[[ATTR16]] = { nounwind } -; CGSCC: attributes #[[ATTR17]] = { nounwind writeonly } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { memory(read) } +; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(read) } +; CGSCC: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn memory(read) } +; CGSCC: attributes #[[ATTR8]] = { nounwind memory(argmem: read) } +; CGSCC: attributes #[[ATTR9]] = { nounwind memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR10]] = { nofree norecurse nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR11]] = { memory(none) } +; CGSCC: attributes #[[ATTR12]] = { nounwind memory(read) } +; CGSCC: attributes #[[ATTR13]] = { willreturn } +; CGSCC: attributes #[[ATTR14]] = { nounwind } ;. Index: llvm/test/Transforms/Attributor/returned.ll =================================================================== --- llvm/test/Transforms/Attributor/returned.ll +++ llvm/test/Transforms/Attributor/returned.ll @@ -41,7 +41,7 @@ ; CHECK: @[[_ZTI1Y:[a-zA-Z0-9_$"\\.-]+]] = external dso_local constant { i8*, i8*, i8* }, align 8 ;. define i32 @sink_r0(i32 %r) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@sink_r0 ; CHECK-SAME: (i32 returned [[R:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -52,14 +52,14 @@ } define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@scc_r1 ; TUNIT-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR10:[0-9]+]] ; TUNIT-NEXT: ret i32 [[R]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@scc_r1 ; CGSCC-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -73,7 +73,7 @@ } define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@scc_r2 ; TUNIT-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -108,7 +108,7 @@ ; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] ; TUNIT-NEXT: ret i32 [[R]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@scc_r2 ; CGSCC-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -188,7 +188,7 @@ } define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 { -; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@scc_rX ; TUNIT-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR2:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -223,7 +223,7 @@ ; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[B]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] ; TUNIT-NEXT: ret i32 [[RETVAL_0]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@scc_rX ; CGSCC-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -325,7 +325,7 @@ ; return a == b ? r : ptr_scc_r2(a, b, r); ; } define double* @ptr_sink_r0(double* %r) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@ptr_sink_r0 ; CHECK-SAME: (double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -336,14 +336,14 @@ } define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@ptr_scc_r1 ; TUNIT-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] ; TUNIT-NEXT: ret double* [[R]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@ptr_scc_r1 ; CGSCC-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -357,7 +357,7 @@ } define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@ptr_scc_r2 ; TUNIT-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -392,7 +392,7 @@ ; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] ; TUNIT-NEXT: ret double* [[R]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@ptr_scc_r2 ; CGSCC-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned [[R:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -479,18 +479,18 @@ ; } ; define i32* @rt0(i32* %a) #0 { -; TUNIT: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(argmem: read) uwtable ; TUNIT-LABEL: define {{[^@]+}}@rt0 ; TUNIT-SAME: (i32* nofree noundef nonnull readonly returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR3:[0-9]+]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i32* @rt0(i32* nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR11:[0-9]+]] +; TUNIT-NEXT: [[CALL:%.*]] = call i32* @rt0(i32* nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR10]] ; TUNIT-NEXT: ret i32* [[A]] ; -; CGSCC: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(argmem: read) uwtable ; CGSCC-LABEL: define {{[^@]+}}@rt0 ; CGSCC-SAME: (i32* nofree noundef nonnull readonly returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @rt0(i32* nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR9:[0-9]+]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @rt0(i32* nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR7]] ; CGSCC-NEXT: ret i32* [[A]] ; entry: @@ -508,13 +508,13 @@ ; } ; define i32* @rt1(i32* %a) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@rt1 ; TUNIT-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR4:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret i32* undef ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@rt1 ; CGSCC-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -531,14 +531,14 @@ ; TEST another SCC test ; define i32* @rt2_helper(i32* %a) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@rt2_helper ; TUNIT-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR10]] ; TUNIT-NEXT: ret i32* [[A]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@rt2_helper ; CGSCC-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -551,7 +551,7 @@ } define i32* @rt2(i32* %a, i32 *%b) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@rt2 ; TUNIT-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -564,7 +564,7 @@ ; TUNIT-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ] ; TUNIT-NEXT: ret i32* [[SEL]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@rt2 ; CGSCC-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -593,14 +593,14 @@ ; TEST another SCC test ; define i32* @rt3_helper(i32* %a, i32* %b) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@rt3_helper ; TUNIT-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR10]] ; TUNIT-NEXT: ret i32* [[B]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@rt3_helper ; CGSCC-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -613,7 +613,7 @@ } define i32* @rt3(i32* %a, i32 *%b) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@rt3 ; TUNIT-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -626,7 +626,7 @@ ; TUNIT-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ] ; TUNIT-NEXT: ret i32* [[B]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@rt3 ; CGSCC-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -667,13 +667,13 @@ ; TUNIT: Function Attrs: noinline nounwind uwtable ; TUNIT-LABEL: define {{[^@]+}}@calls_unknown_fn ; TUNIT-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR5:[0-9]+]] { -; TUNIT-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR12:[0-9]+]] +; TUNIT-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR11:[0-9]+]] ; TUNIT-NEXT: ret i32* [[R]] ; ; CGSCC: Function Attrs: noinline nounwind uwtable ; CGSCC-LABEL: define {{[^@]+}}@calls_unknown_fn ; CGSCC-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR4:[0-9]+]] { -; CGSCC-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR10:[0-9]+]] +; CGSCC-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR8]] ; CGSCC-NEXT: ret i32* [[R]] ; tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn) @@ -716,14 +716,14 @@ ; TUNIT-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn ; TUNIT-SAME: (i32* returned [[R:%.*]]) #[[ATTR6:[0-9]+]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR12]] +; TUNIT-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR11]] ; TUNIT-NEXT: ret i32* [[R]] ; ; CGSCC: Function Attrs: noinline nounwind uwtable ; CGSCC-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn ; CGSCC-SAME: (i32* returned [[R:%.*]]) #[[ATTR4]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR10]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR8]] ; CGSCC-NEXT: ret i32* [[R]] ; entry: @@ -765,14 +765,14 @@ ; TUNIT-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2 ; TUNIT-SAME: (i32* [[R:%.*]]) #[[ATTR6]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR12]] +; TUNIT-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR11]] ; TUNIT-NEXT: ret i32* [[CALL]] ; ; CGSCC: Function Attrs: noinline nounwind uwtable ; CGSCC-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2 ; CGSCC-SAME: (i32* [[R:%.*]]) #[[ATTR4]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR10]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR8]] ; CGSCC-NEXT: ret i32* [[CALL]] ; entry: @@ -791,7 +791,7 @@ ; } ; define double @select_and_phi(double %b) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@select_and_phi ; CHECK-SAME: (double returned [[B:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -827,7 +827,7 @@ ; } ; define double @recursion_select_and_phi(i32 %a, double %b) #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@recursion_select_and_phi ; TUNIT-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -840,7 +840,7 @@ ; TUNIT: if.end: ; TUNIT-NEXT: ret double [[B]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@recursion_select_and_phi ; CGSCC-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -877,7 +877,7 @@ ; } ; define double* @bitcast(i32* %b) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@bitcast ; CHECK-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -900,7 +900,7 @@ ; } ; define double* @bitcasts_select_and_phi(i32* %b) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@bitcasts_select_and_phi ; CHECK-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -950,7 +950,7 @@ ; } ; define double* @ret_arg_arg_undef(i32* %b) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@ret_arg_arg_undef ; CHECK-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -998,7 +998,7 @@ ; } ; define double* @ret_undef_arg_arg(i32* %b) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@ret_undef_arg_arg ; CHECK-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -1046,7 +1046,7 @@ ; } ; define double* @ret_undef_arg_undef(i32* %b) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@ret_undef_arg_undef ; CHECK-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -1179,7 +1179,7 @@ ; TEST inconsistent IR in dead code. ; define i32 @deadblockcall1(i32 %A) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@deadblockcall1 ; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -1197,7 +1197,7 @@ declare i32 @deadblockcall_helper(i32 returned %A); define i32 @deadblockcall2(i32 %A) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@deadblockcall2 ; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -1218,7 +1218,7 @@ } define i32 @deadblockphi1(i32 %A) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@deadblockphi1 ; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -1244,7 +1244,7 @@ } define i32 @deadblockphi2(i32 %A) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@deadblockphi2 ; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: @@ -1410,7 +1410,7 @@ @G = external global i8 define i32* @ret_const() #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@ret_const ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: ret i32* bitcast (i8* @G to i32*) @@ -1419,30 +1419,30 @@ ret i32* %bc } define i32* @use_const() #0 { -; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@use_const ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: ret i32* bitcast (i8* @G to i32*) ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@use_const ; CGSCC-SAME: () #[[ATTR3]] { -; CGSCC-NEXT: [[C:%.*]] = call noundef nonnull dereferenceable(1) i32* @ret_const() #[[ATTR11:[0-9]+]] +; CGSCC-NEXT: [[C:%.*]] = call noundef nonnull dereferenceable(1) i32* @ret_const() #[[ATTR9:[0-9]+]] ; CGSCC-NEXT: ret i32* [[C]] ; %c = call i32* @ret_const() ret i32* %c } define i32* @dont_use_const() #0 { -; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@dont_use_const ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: ret i32* bitcast (i8* @G to i32*) ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind willreturn memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@dont_use_const ; CGSCC-SAME: () #[[ATTR3]] { -; CGSCC-NEXT: [[C:%.*]] = musttail call noundef nonnull dereferenceable(1) i32* @ret_const() #[[ATTR11]] +; CGSCC-NEXT: [[C:%.*]] = musttail call noundef nonnull dereferenceable(1) i32* @ret_const() #[[ATTR9]] ; CGSCC-NEXT: ret i32* [[C]] ; %c = musttail call i32* @ret_const() @@ -1494,31 +1494,27 @@ attributes #0 = { noinline nounwind uwtable } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } -; TUNIT: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } -; TUNIT: attributes #[[ATTR3]] = { argmemonly nofree noinline nosync nounwind readonly uwtable } -; TUNIT: attributes #[[ATTR4]] = { nofree noinline nosync nounwind readnone willreturn uwtable } +; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR1]] = { nofree noinline nosync nounwind memory(none) uwtable } +; TUNIT: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind memory(none) uwtable } +; TUNIT: attributes #[[ATTR3]] = { nofree noinline nosync nounwind memory(argmem: read) uwtable } +; TUNIT: attributes #[[ATTR4]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } ; TUNIT: attributes #[[ATTR5]] = { noinline nounwind uwtable } ; TUNIT: attributes #[[ATTR6]] = { noinline norecurse nounwind uwtable } ; TUNIT: attributes #[[ATTR7]] = { noreturn } ; TUNIT: attributes #[[ATTR8]] = { norecurse } -; TUNIT: attributes #[[ATTR9:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind readnone } -; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind readonly } -; TUNIT: attributes #[[ATTR12]] = { nounwind } -; TUNIT: attributes #[[ATTR13:[0-9]+]] = { nounwind readnone } +; TUNIT: attributes #[[ATTR9:[0-9]+]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind } +; TUNIT: attributes #[[ATTR11]] = { nounwind } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } -; CGSCC: attributes #[[ATTR2]] = { argmemonly nofree noinline nosync nounwind readonly uwtable } -; CGSCC: attributes #[[ATTR3]] = { nofree noinline nosync nounwind readnone willreturn uwtable } +; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind memory(none) uwtable } +; CGSCC: attributes #[[ATTR2]] = { nofree noinline nosync nounwind memory(argmem: read) uwtable } +; CGSCC: attributes #[[ATTR3]] = { nofree noinline nosync nounwind willreturn memory(none) uwtable } ; CGSCC: attributes #[[ATTR4]] = { noinline nounwind uwtable } ; CGSCC: attributes #[[ATTR5]] = { noreturn } -; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR7]] = { nofree nosync nounwind readnone } -; CGSCC: attributes #[[ATTR8]] = { nounwind readnone } -; CGSCC: attributes #[[ATTR9]] = { nofree nosync nounwind readonly } -; CGSCC: attributes #[[ATTR10]] = { nounwind } -; CGSCC: attributes #[[ATTR11]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR7]] = { nofree nosync nounwind } +; CGSCC: attributes #[[ATTR8]] = { nounwind } +; CGSCC: attributes #[[ATTR9]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/undefined_behavior.ll =================================================================== --- llvm/test/Transforms/Attributor/undefined_behavior.ll +++ llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -11,7 +11,7 @@ ; -- Load tests -- define void @load_wholly_unreachable() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@load_wholly_unreachable ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: unreachable @@ -21,7 +21,7 @@ } define void @loads_wholly_unreachable() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@loads_wholly_unreachable ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: unreachable @@ -33,7 +33,7 @@ define void @load_single_bb_unreachable(i1 %cond) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@load_single_bb_unreachable ; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] @@ -53,7 +53,7 @@ ; Note that while the load is removed (because it's unused), the block ; is not changed to unreachable define void @load_null_pointer_is_defined() null_pointer_is_valid { -; CHECK: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@load_null_pointer_is_defined ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: ret void @@ -63,7 +63,7 @@ } define internal i32* @ret_null() { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ret_null ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: ret i32* null @@ -72,12 +72,12 @@ } define void @load_null_propagated() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@load_null_propagated ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@load_null_propagated ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: ret void @@ -90,7 +90,7 @@ ; -- Store tests -- define void @store_wholly_unreachable() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@store_wholly_unreachable ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: unreachable @@ -100,13 +100,13 @@ } define void @store_wholly_unreachable_volatile() { -; TUNIT: Function Attrs: nofree norecurse nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile ; TUNIT-SAME: () #[[ATTR2:[0-9]+]] { ; TUNIT-NEXT: store volatile i32 5, i32* null, align 4294967296 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: store volatile i32 5, i32* null, align 4294967296 @@ -117,7 +117,7 @@ } define void @store_single_bb_unreachable(i1 %cond) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@store_single_bb_unreachable ; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] @@ -135,13 +135,13 @@ } define void @store_null_pointer_is_defined() null_pointer_is_valid { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@store_null_pointer_is_defined ; TUNIT-SAME: () #[[ATTR3:[0-9]+]] { ; TUNIT-NEXT: store i32 5, i32* null, align 4294967296 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@store_null_pointer_is_defined ; CGSCC-SAME: () #[[ATTR4:[0-9]+]] { ; CGSCC-NEXT: store i32 5, i32* null, align 4294967296 @@ -155,12 +155,12 @@ ; ATTRIBUTOR-LABEL: @store_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@store_null_propagated ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@store_null_propagated ; CGSCC-SAME: () #[[ATTR5:[0-9]+]] { ; CGSCC-NEXT: [[PTR:%.*]] = call noalias align 4294967296 i32* @ret_null() #[[ATTR10:[0-9]+]] @@ -174,12 +174,12 @@ ; -- AtomicRMW tests -- define void @atomicrmw_wholly_unreachable() { -; TUNIT: Function Attrs: nofree norecurse nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable ; TUNIT-SAME: () #[[ATTR2]] { ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree norecurse nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: unreachable @@ -189,7 +189,7 @@ } define void @atomicrmw_single_bb_unreachable(i1 %cond) { -; TUNIT: Function Attrs: nofree norecurse nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable ; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] @@ -198,7 +198,7 @@ ; TUNIT: e: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable ; CGSCC-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] @@ -236,7 +236,7 @@ ; ATTRIBUTOR-LABEL: @atomicrmw_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; -; TUNIT: Function Attrs: nofree norecurse nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_null_propagated ; TUNIT-SAME: () #[[ATTR2]] { ; TUNIT-NEXT: unreachable @@ -256,12 +256,12 @@ ; -- AtomicCmpXchg tests -- define void @atomiccmpxchg_wholly_unreachable() { -; TUNIT: Function Attrs: nofree norecurse nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable ; TUNIT-SAME: () #[[ATTR2]] { ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree norecurse nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: unreachable @@ -271,7 +271,7 @@ } define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) { -; TUNIT: Function Attrs: nofree norecurse nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable ; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] @@ -280,7 +280,7 @@ ; TUNIT: e: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable ; CGSCC-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] @@ -318,7 +318,7 @@ ; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; -; TUNIT: Function Attrs: nofree norecurse nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated ; TUNIT-SAME: () #[[ATTR2]] { ; TUNIT-NEXT: unreachable @@ -340,7 +340,7 @@ ; Note: The unreachable on %t and %e is _not_ from AAUndefinedBehavior define i32 @cond_br_on_undef() { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef ; TUNIT-SAME: () #[[ATTR5:[0-9]+]] { ; TUNIT-NEXT: unreachable @@ -349,7 +349,7 @@ ; TUNIT: e: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef ; CGSCC-SAME: () #[[ATTR8:[0-9]+]] { ; CGSCC-NEXT: unreachable @@ -369,7 +369,7 @@ ; Valid branch - verify that this is not converted ; to unreachable. define void @cond_br_on_undef2(i1 %cond) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef2 ; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[COND]], label [[T1:%.*]], label [[E1:%.*]] @@ -394,7 +394,7 @@ } define i1 @ret_undef() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@ret_undef ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: ret i1 undef @@ -403,7 +403,7 @@ } define void @cond_br_on_undef_interproc() { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: unreachable @@ -412,7 +412,7 @@ ; TUNIT: e: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[COND:%.*]] = call i1 @ret_undef() #[[ATTR10]] @@ -431,7 +431,7 @@ } define i1 @ret_undef2() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@ret_undef2 ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[E:%.*]] @@ -449,7 +449,7 @@ ; More complicated interproc deduction of undef define void @cond_br_on_undef_interproc2() { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: unreachable @@ -458,7 +458,7 @@ ; TUNIT: e: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[COND:%.*]] = call i1 @ret_undef2() #[[ATTR10]] @@ -479,7 +479,7 @@ ; Branch on undef that depends on propagation of ; undef of a previous instruction. define i32 @cond_br_on_undef3() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef3 ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 1, undef @@ -500,7 +500,7 @@ ; Branch on undef because of uninitialized value. ; FIXME: Currently it doesn't propagate the undef. define i32 @cond_br_on_undef_uninit() { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: unreachable @@ -509,7 +509,7 @@ ; TUNIT: e: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit ; CGSCC-SAME: () #[[ATTR8]] { ; CGSCC-NEXT: unreachable @@ -533,7 +533,7 @@ ; MODULE-NOT: @callee( define internal i32 @callee(i1 %C, i32* %A) { ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@callee ; CGSCC-SAME: () #[[ATTR0]] { ; CGSCC-NEXT: entry: @@ -555,12 +555,12 @@ } define i32 @foo() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@foo ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: ret i32 1 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[X:%.*]] = call noundef i32 @callee() #[[ATTR10]] @@ -575,13 +575,13 @@ ; Tests for argument position define void @arg_nonnull_1(i32* nonnull %a) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_1 ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { ; TUNIT-NEXT: store i32 0, i32* [[A]], align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_1 ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9:[0-9]+]] { ; CGSCC-NEXT: store i32 0, i32* [[A]], align 4 @@ -592,13 +592,13 @@ } define void @arg_nonnull_1_noundef_1(i32* nonnull noundef %a) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6]] { ; TUNIT-NEXT: store i32 0, i32* [[A]], align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: store i32 0, i32* [[A]], align 4 @@ -609,7 +609,7 @@ } define void @arg_nonnull_12(i32* nonnull %a, i32* nonnull %b, i32* %c) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_12 ; TUNIT-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { ; TUNIT-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null @@ -623,7 +623,7 @@ ; TUNIT: ret: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_12 ; CGSCC-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null @@ -650,7 +650,7 @@ } define void @arg_nonnull_12_noundef_2(i32* nonnull %a, i32* noundef nonnull %b, i32* %c) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 ; TUNIT-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { ; TUNIT-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null @@ -664,7 +664,7 @@ ; TUNIT: ret: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 ; CGSCC-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR9]] { ; CGSCC-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null @@ -692,12 +692,12 @@ ; Pass null directly to argument with nonnull attribute define void @arg_nonnull_violation1_1() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1 ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: unreachable @@ -707,12 +707,12 @@ } define void @arg_nonnull_violation1_2() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2 ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: unreachable @@ -723,12 +723,12 @@ ; A case that depends on value simplification define void @arg_nonnull_violation2_1(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: unreachable @@ -740,12 +740,12 @@ } define void @arg_nonnull_violation2_2(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: unreachable @@ -758,7 +758,7 @@ ; Cases for single and multiple violation at a callsite define void @arg_nonnull_violation3_1(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[PTR:%.*]] = alloca i32, align 4 @@ -772,7 +772,7 @@ ; TUNIT: ret: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[PTR:%.*]] = alloca i32, align 4 @@ -805,7 +805,7 @@ } define void @arg_nonnull_violation3_2(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[PTR:%.*]] = alloca i32, align 4 @@ -819,7 +819,7 @@ ; TUNIT: ret: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[PTR:%.*]] = alloca i32, align 4 @@ -854,7 +854,7 @@ ; Tests for returned position define nonnull i32* @returned_nonnnull(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: switch i32 [[C]], label [[ONDEFAULT:%.*]] [ @@ -881,7 +881,7 @@ } define noundef i32* @returned_noundef(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@returned_noundef ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: switch i32 [[C]], label [[ONDEFAULT:%.*]] [ @@ -908,7 +908,7 @@ } define nonnull noundef i32* @returned_nonnnull_noundef(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull_noundef ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: switch i32 [[C]], label [[ONDEFAULT:%.*]] [ @@ -935,7 +935,7 @@ } define noundef i32 @returned_nonnnull_noundef_int() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull_noundef_int ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: ret i32 0 @@ -965,7 +965,7 @@ } define i32 @argument_noundef1(i32 noundef %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@argument_noundef1 ; CHECK-SAME: (i32 noundef returned [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret i32 [[C]] @@ -974,12 +974,12 @@ } define i32 @violate_noundef_nonpointer() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@violate_noundef_nonpointer ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: ret i32 undef ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@violate_noundef_nonpointer ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: unreachable @@ -989,7 +989,7 @@ } define i32* @argument_noundef2(i32* noundef %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@argument_noundef2 ; CHECK-SAME: (i32* nofree noundef readnone returned "no-capture-maybe-returned" [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret i32* [[C]] @@ -998,12 +998,12 @@ } define i32* @violate_noundef_pointer() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@violate_noundef_pointer ; TUNIT-SAME: () #[[ATTR0]] { ; TUNIT-NEXT: ret i32* undef ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@violate_noundef_pointer ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: ret i32* undef @@ -1013,7 +1013,7 @@ } define internal noundef i32 @assumed_undef_is_ok(i1 %c, i32 %arg) { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@assumed_undef_is_ok ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: br i1 [[C]], label [[REC:%.*]], label [[RET:%.*]] @@ -1035,12 +1035,12 @@ } define noundef i32 @assumed_undef_is_ok_caller(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[CALL:%.*]] = call i32 @assumed_undef_is_ok(i1 [[C]]) #[[ATTR10]] @@ -1051,25 +1051,25 @@ } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write) } ; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } -; TUNIT: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } -; CGSCC: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write) } +; CGSCC: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn memory(write) } ; CGSCC: attributes #[[ATTR6]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } ; CGSCC: attributes #[[ATTR7]] = { nofree nounwind willreturn } -; CGSCC: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR10]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR11]] = { nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR10]] = { willreturn } +; CGSCC: attributes #[[ATTR11]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/value-simplify-assume.ll =================================================================== --- llvm/test/Transforms/Attributor/value-simplify-assume.ll +++ llvm/test/Transforms/Attributor/value-simplify-assume.ll @@ -7,7 +7,7 @@ declare void @unknown() define i1 @readI1p(i1* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@readI1p ; CHECK-SAME: (i1* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[P]], align 1 @@ -37,13 +37,13 @@ } define i1 @drop_assume_1c_nr() norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c_nr ; TUNIT-SAME: () #[[ATTR3:[0-9]+]] { ; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR4:[0-9]+]] ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c_nr ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR5:[0-9]+]] @@ -156,7 +156,7 @@ } define i1 @drop_assume_1_nr(i1 %arg) norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1_nr ; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -164,7 +164,7 @@ ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]] ; TUNIT-NEXT: ret i1 [[ARG]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1_nr ; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -261,7 +261,7 @@ } define i1 @assume_1_nr(i1 %arg, i1 %cond) norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_1_nr ; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -275,7 +275,7 @@ ; TUNIT: m: ; TUNIT-NEXT: ret i1 [[ARG]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_1_nr ; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -305,7 +305,7 @@ } define void @assume_1b_nr(i1 %arg, i1 %cond) norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_1b_nr ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -320,7 +320,7 @@ ; TUNIT: m: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_1b_nr ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -351,7 +351,7 @@ } define i1 @assume_2_nr(i1 %arg, i1 %cond) norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_2_nr ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -368,7 +368,7 @@ ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] ; TUNIT-NEXT: ret i1 [[L]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_2_nr ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -401,7 +401,7 @@ } define void @assume_2b_nr(i1 %arg, i1 %cond) norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_2b_nr ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -418,7 +418,7 @@ ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_2b_nr ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -451,7 +451,7 @@ } define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_3_nr ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -469,7 +469,7 @@ ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5:[0-9]+]] ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_3_nr ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -484,7 +484,7 @@ ; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1 ; CGSCC-NEXT: br label [[M]] ; CGSCC: m: -; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6:[0-9]+]] +; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[R]] ; %stack = alloca i1 @@ -504,7 +504,7 @@ } define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_4_nr ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -522,7 +522,7 @@ ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_4_nr ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -537,7 +537,7 @@ ; CGSCC: m: ; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] -; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[R]] ; %stack = alloca i1 @@ -557,7 +557,7 @@ } define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_5_nr ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -581,7 +581,7 @@ ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_5_nr ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -602,7 +602,7 @@ ; CGSCC: m: ; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] -; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[R]] ; %stack = alloca i1 @@ -628,7 +628,7 @@ } define i1 @assume_5c_nr(i1 %cond) norecurse { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_5c_nr ; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -652,7 +652,7 @@ ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_5c_nr ; CGSCC-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -673,7 +673,7 @@ ; CGSCC: m: ; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] -; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[R]] ; %stack = alloca i1 @@ -717,13 +717,13 @@ } define i1 @drop_assume_1c() { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c ; TUNIT-SAME: () #[[ATTR3]] { ; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR4]] ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR5]] @@ -825,7 +825,7 @@ } define i1 @drop_assume_1(i1 %arg) { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1 ; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -833,7 +833,7 @@ ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]] ; TUNIT-NEXT: ret i1 [[ARG]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1 ; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -925,7 +925,7 @@ } define i1 @assume_1(i1 %arg, i1 %cond) { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_1 ; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -939,7 +939,7 @@ ; TUNIT: m: ; TUNIT-NEXT: ret i1 [[ARG]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_1 ; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -969,7 +969,7 @@ } define void @assume_1b(i1 %arg, i1 %cond) { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_1b ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -984,7 +984,7 @@ ; TUNIT: m: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_1b ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1015,7 +1015,7 @@ } define i1 @assume_2(i1 %arg, i1 %cond) { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_2 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1032,7 +1032,7 @@ ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] ; TUNIT-NEXT: ret i1 [[L]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_2 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1065,7 +1065,7 @@ } define void @assume_2b(i1 %arg, i1 %cond) { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_2b ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1082,7 +1082,7 @@ ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_2b ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1115,7 +1115,7 @@ } define i1 @assume_3(i1 %arg, i1 %cond) { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_3 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1133,7 +1133,7 @@ ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_3 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR4:[0-9]+]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1148,7 +1148,7 @@ ; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1 ; CGSCC-NEXT: br label [[M]] ; CGSCC: m: -; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[R]] ; %stack = alloca i1 @@ -1168,7 +1168,7 @@ } define i1 @assume_4(i1 %arg, i1 %cond) { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_4 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1186,7 +1186,7 @@ ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_4 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR4]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1201,7 +1201,7 @@ ; CGSCC: m: ; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] -; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[R]] ; %stack = alloca i1 @@ -1221,7 +1221,7 @@ } define i1 @assume_5(i1 %arg, i1 %cond) { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_5 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1245,7 +1245,7 @@ ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_5 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR4]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1266,7 +1266,7 @@ ; CGSCC: m: ; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] -; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[R]] ; %stack = alloca i1 @@ -1292,7 +1292,7 @@ } define i1 @assume_5c(i1 %cond) { -; TUNIT: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@assume_5c ; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1316,7 +1316,7 @@ ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@assume_5c ; CGSCC-SAME: (i1 [[COND:%.*]]) #[[ATTR4]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1 @@ -1337,7 +1337,7 @@ ; CGSCC: m: ; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] -; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] ; CGSCC-NEXT: ret i1 [[R]] ; %stack = alloca i1 @@ -1363,18 +1363,17 @@ } ;. -; TUNIT: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } ; TUNIT: attributes #[[ATTR2]] = { norecurse } -; TUNIT: attributes #[[ATTR3]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) } ; TUNIT: attributes #[[ATTR4]] = { willreturn } -; TUNIT: attributes #[[ATTR5]] = { nofree nosync nounwind readonly willreturn } +; TUNIT: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } ; CGSCC: attributes #[[ATTR2]] = { norecurse } -; CGSCC: attributes #[[ATTR3]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR4]] = { inaccessiblememonly nofree nosync nounwind willreturn } +; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) } +; CGSCC: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } ; CGSCC: attributes #[[ATTR5]] = { willreturn } -; CGSCC: attributes #[[ATTR6]] = { readonly willreturn } ;. Index: llvm/test/Transforms/Attributor/value-simplify-dbg.ll =================================================================== --- llvm/test/Transforms/Attributor/value-simplify-dbg.ll +++ llvm/test/Transforms/Attributor/value-simplify-dbg.ll @@ -24,7 +24,7 @@ declare void @use(i32 noundef) define void @src() norecurse !dbg !22 { -; CHECK: Function Attrs: norecurse nosync writeonly +; CHECK: Function Attrs: norecurse nosync memory(write) ; CHECK-LABEL: define {{[^@]+}}@src ; CHECK-SAME: () #[[ATTR0:[0-9]+]] !dbg [[DBG22:![0-9]+]] { ; CHECK-NEXT: entry: @@ -73,8 +73,8 @@ !24 = !DILocation(line: 10, column: 7, scope: !22) !25 = !DILocation(line: 11, column: 1, scope: !22) ;. -; CHECK: attributes #[[ATTR0]] = { norecurse nosync writeonly } -; CHECK: attributes #[[ATTR1:[0-9]+]] = { readnone speculatable } +; CHECK: attributes #[[ATTR0]] = { norecurse nosync memory(write) } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { speculatable memory(none) } ;. ; CHECK: [[DBG0]] = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) ; CHECK: [[META1:![0-9]+]] = distinct !DIGlobalVariable(name: "G", scope: !2, file: !5, line: 1, type: !6, isLocal: true, isDefinition: true) Index: llvm/test/Transforms/Attributor/value-simplify-gpu.ll =================================================================== --- llvm/test/Transforms/Attributor/value-simplify-gpu.ll +++ llvm/test/Transforms/Attributor/value-simplify-gpu.ll @@ -50,7 +50,7 @@ ; TUNIT-NEXT: call void @level2Kernelb() #[[ATTR3]] ; TUNIT-NEXT: br label [[IF_END]] ; TUNIT: if.end: -; TUNIT-NEXT: call void @level2Kernelall_late() #[[ATTR5:[0-9]+]] +; TUNIT-NEXT: call void @level2Kernelall_late() #[[ATTR3]] ; TUNIT-NEXT: ret void ; ; CGSCC: Function Attrs: norecurse nosync nounwind @@ -67,7 +67,7 @@ ; CGSCC-NEXT: call void @level2Kernelb() #[[ATTR4]] ; CGSCC-NEXT: br label [[IF_END]] ; CGSCC: if.end: -; CGSCC-NEXT: call void @level2Kernelall_late() #[[ATTR6:[0-9]+]] +; CGSCC-NEXT: call void @level2Kernelall_late() #[[ATTR4]] ; CGSCC-NEXT: ret void ; entry: @@ -89,7 +89,7 @@ } define internal void @level2Kernelall_early() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CHECK-LABEL: define {{[^@]+}}@level2Kernelall_early ; CHECK-SAME: () #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: entry: @@ -110,7 +110,7 @@ ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4 ; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4 -; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR6:[0-9]+]] +; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR5:[0-9]+]] ; TUNIT-NEXT: ret void ; ; CGSCC: Function Attrs: nosync nounwind @@ -138,7 +138,7 @@ ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4 ; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4 -; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR6]] +; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR5]] ; TUNIT-NEXT: ret void ; ; CGSCC: Function Attrs: nosync nounwind @@ -160,13 +160,13 @@ } define internal void @level2Kernelall_late() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@level2Kernelall_late ; TUNIT-SAME: () #[[ATTR2]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@level2Kernelall_late ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: entry: @@ -217,7 +217,7 @@ ; TUNIT-NEXT: call void @level2b() #[[ATTR3]] ; TUNIT-NEXT: br label [[IF_END]] ; TUNIT: if.end: -; TUNIT-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR5]] +; TUNIT-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR3]] ; TUNIT-NEXT: ret void ; ; CGSCC: Function Attrs: norecurse nosync nounwind @@ -235,7 +235,7 @@ ; CGSCC-NEXT: call void @level2b(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]] ; CGSCC-NEXT: br label [[IF_END]] ; CGSCC: if.end: -; CGSCC-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR6]] +; CGSCC-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]] ; CGSCC-NEXT: ret void ; entry: @@ -258,14 +258,14 @@ } define internal void @level2all_early(i32* %addr) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@level2all_early ; TUNIT-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@level2all_early ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: @@ -286,7 +286,7 @@ ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 ; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4 -; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR6]] +; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR5]] ; TUNIT-NEXT: ret void ; ; CGSCC: Function Attrs: nosync nounwind @@ -314,7 +314,7 @@ ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 ; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4 -; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR6]] +; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR5]] ; TUNIT-NEXT: ret void ; ; CGSCC: Function Attrs: nosync nounwind @@ -336,14 +336,14 @@ } define internal void @level2all_late(i32* %addr) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@level2all_late ; TUNIT-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@level2all_late ; CGSCC-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: @@ -362,17 +362,15 @@ ;. ; TUNIT: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" } ; TUNIT: attributes #[[ATTR1]] = { norecurse nosync nounwind } -; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(write) } ; TUNIT: attributes #[[ATTR3]] = { nosync nounwind } -; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR5]] = { nosync nounwind writeonly } -; TUNIT: attributes #[[ATTR6]] = { nounwind } +; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR5]] = { nounwind } ;. ; CGSCC: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" } ; CGSCC: attributes #[[ATTR1]] = { norecurse nosync nounwind } -; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(write) } ; CGSCC: attributes #[[ATTR3]] = { nosync nounwind } ; CGSCC: attributes #[[ATTR4]] = { nounwind } -; CGSCC: attributes #[[ATTR5]] = { nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR6]] = { nounwind writeonly } +; CGSCC: attributes #[[ATTR5]] = { nounwind willreturn } ;. Index: llvm/test/Transforms/Attributor/value-simplify-instances.ll =================================================================== --- llvm/test/Transforms/Attributor/value-simplify-instances.ll +++ llvm/test/Transforms/Attributor/value-simplify-instances.ll @@ -13,7 +13,7 @@ ; CHECK: @[[G3:[a-zA-Z0-9_$"\\.-]+]] = private global i1 undef ;. define internal i1 @recursive_inst_comparator(i1* %a, i1* %b) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@recursive_inst_comparator ; CHECK-SAME: (i1* noalias nofree readnone [[A:%.*]], i1* noalias nofree readnone [[B:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[B]] @@ -103,17 +103,29 @@ ; Make sure we do *not* return true. define internal i1 @recursive_alloca_compare(i1 %c, i1* %p) { -; CHECK: Function Attrs: nofree nosync nounwind readnone -; CHECK-LABEL: define {{[^@]+}}@recursive_alloca_compare -; CHECK-SAME: (i1 [[C:%.*]], i1* noalias nofree nonnull readnone [[P:%.*]]) #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: [[A:%.*]] = alloca i1, align 1 -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] -; CHECK-NEXT: ret i1 [[CMP]] -; CHECK: f: -; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 noundef true, i1* noalias nofree noundef nonnull readnone dereferenceable(1) [[A]]) #[[ATTR1]] -; CHECK-NEXT: ret i1 [[CALL]] +; TUNIT: Function Attrs: nofree nosync nounwind memory(none) +; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_compare +; TUNIT-SAME: (i1 [[C:%.*]], i1* noalias nofree nonnull readnone [[P:%.*]]) #[[ATTR1:[0-9]+]] { +; TUNIT-NEXT: [[A:%.*]] = alloca i1, align 1 +; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; TUNIT: t: +; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] +; TUNIT-NEXT: ret i1 [[CMP]] +; TUNIT: f: +; TUNIT-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 noundef true, i1* noalias nofree noundef nonnull readnone dereferenceable(1) [[A]]) #[[ATTR4:[0-9]+]] +; TUNIT-NEXT: ret i1 [[CALL]] +; +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) +; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_compare +; CGSCC-SAME: (i1 [[C:%.*]], i1* noalias nofree nonnull readnone [[P:%.*]]) #[[ATTR1:[0-9]+]] { +; CGSCC-NEXT: [[A:%.*]] = alloca i1, align 1 +; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; CGSCC: t: +; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] +; CGSCC-NEXT: ret i1 [[CMP]] +; CGSCC: f: +; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 noundef true, i1* noalias nofree noundef nonnull readnone dereferenceable(1) [[A]]) #[[ATTR3:[0-9]+]] +; CGSCC-NEXT: ret i1 [[CALL]] ; %a = alloca i1 br i1 %c, label %t, label %f @@ -127,13 +139,13 @@ ; FIXME: This should *not* return true. define i1 @recursive_alloca_compare_caller(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { -; TUNIT-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 [[C]], i1* undef) #[[ATTR1]] +; TUNIT-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 [[C]], i1* undef) #[[ATTR4]] ; TUNIT-NEXT: ret i1 [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 [[C]], i1* undef) #[[ATTR4:[0-9]+]] @@ -145,7 +157,7 @@ ; Make sure we do *not* simplify this to return 0 or 1, return 42 is ok though. define internal i8 @recursive_alloca_load_return(i1 %c, i8* %p, i8 %v) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_load_return ; TUNIT-SAME: (i1 [[C:%.*]], i8* nocapture nofree nonnull readonly [[P:%.*]], i8 noundef [[V:%.*]]) #[[ATTR3:[0-9]+]] { ; TUNIT-NEXT: [[A:%.*]] = alloca i8, align 1 @@ -156,10 +168,10 @@ ; TUNIT-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 ; TUNIT-NEXT: ret i8 [[L]] ; TUNIT: f: -; TUNIT-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR4:[0-9]+]] +; TUNIT-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR4]] ; TUNIT-NEXT: ret i8 [[CALL]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_load_return ; CGSCC-SAME: (i1 [[C:%.*]], i8* nocapture nofree nonnull readonly [[P:%.*]], i8 noundef [[V:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: [[A:%.*]] = alloca i8, align 1 @@ -170,7 +182,7 @@ ; CGSCC-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 ; CGSCC-NEXT: ret i8 [[L]] ; CGSCC: f: -; CGSCC-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR3:[0-9]+]] +; CGSCC-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR3]] ; CGSCC-NEXT: ret i8 [[CALL]] ; %a = alloca i8 @@ -186,16 +198,16 @@ } define i8 @recursive_alloca_load_return_caller(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@recursive_alloca_load_return_caller ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; TUNIT-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 [[C]], i8* undef, i8 noundef 42) #[[ATTR4]] ; TUNIT-NEXT: ret i8 [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_load_return_caller ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; CGSCC-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 [[C]], i8* undef, i8 noundef 42) #[[ATTR5:[0-9]+]] +; CGSCC-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 [[C]], i8* undef, i8 noundef 42) #[[ATTR4]] ; CGSCC-NEXT: ret i8 [[CALL]] ; %call = call i8 @recursive_alloca_load_return(i1 %c, i8* undef, i8 42) @@ -259,7 +271,7 @@ ; CGSCC: Function Attrs: nofree nosync nounwind ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global1 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 [[C]]) #[[ATTR5]] +; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 [[C]]) #[[ATTR4]] ; CGSCC-NEXT: ret i1 [[CALL]] ; %call = call i1 @recursive_alloca_compare_global1(i1 %c) @@ -318,7 +330,7 @@ ; CGSCC: Function Attrs: nofree nosync nounwind ; CGSCC-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global2 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 [[C]]) #[[ATTR5]] +; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 [[C]]) #[[ATTR4]] ; CGSCC-NEXT: ret i1 [[CALL]] ; %call = call i1 @recursive_alloca_compare_global2(i1 %c) @@ -374,25 +386,24 @@ ; CGSCC: Function Attrs: nofree nosync nounwind ; CGSCC-LABEL: define {{[^@]+}}@recursive_inst_compare_caller_global3 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 [[C]]) #[[ATTR5]] +; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 [[C]]) #[[ATTR4]] ; CGSCC-NEXT: ret i1 [[CALL]] ; %call = call i1 @recursive_inst_compare_global3(i1 %c) ret i1 %call } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind readnone } -; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } -; TUNIT: attributes #[[ATTR3]] = { argmemonly nofree nosync nounwind } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind memory(none) } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(none) } +; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind memory(argmem: readwrite) } ; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind } ; TUNIT: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind } -; TUNIT: attributes #[[ATTR6]] = { nounwind readnone } +; TUNIT: attributes #[[ATTR6]] = { nounwind } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone } -; CGSCC: attributes #[[ATTR2]] = { argmemonly nofree nosync nounwind } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind memory(argmem: readwrite) } ; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind } -; CGSCC: attributes #[[ATTR4]] = { nounwind readnone } -; CGSCC: attributes #[[ATTR5]] = { nounwind } +; CGSCC: attributes #[[ATTR4]] = { nounwind } ;. Index: llvm/test/Transforms/Attributor/value-simplify-local-remote.ll =================================================================== --- llvm/test/Transforms/Attributor/value-simplify-local-remote.ll +++ llvm/test/Transforms/Attributor/value-simplify-local-remote.ll @@ -13,7 +13,7 @@ %struct2 = type <{ ptr, i64, i64, i32, [4 x i8] }> define i64 @t1(ptr %first, ptr %first.addr, ptr %0) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@t1 ; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FIRST:%.*]], ptr nocapture nofree readnone [[FIRST_ADDR:%.*]], ptr nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -24,7 +24,7 @@ ; TUNIT-NEXT: [[CALL:%.*]] = call ptr @foo.4(ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FIRST]]) #[[ATTR3:[0-9]+]] ; TUNIT-NEXT: ret i64 0 ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@t1 ; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FIRST:%.*]], ptr nocapture nofree readnone [[FIRST_ADDR:%.*]], ptr nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -49,7 +49,7 @@ } define internal ptr @foo.4(ptr %__first) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@foo.4 ; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[__FIRST:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -57,7 +57,7 @@ ; TUNIT-NEXT: store ptr [[__FIRST]], ptr [[__FIRST]], align 8 ; TUNIT-NEXT: ret ptr undef ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@foo.4 ; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[__FIRST:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: @@ -75,7 +75,7 @@ } define internal ptr @bar(ptr %QQfirst) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@bar ; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[QQFIRST:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -101,7 +101,7 @@ } define ptr @t2(ptr %this, ptr %this.addr, ptr %this1) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@t2 ; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -110,12 +110,12 @@ ; TUNIT-NEXT: [[TEST_RET:%.*]] = extractvalue [[S]] [[CALL]], 0 ; TUNIT-NEXT: ret ptr [[TEST_RET]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@t2 ; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @foo.1(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8:[0-9]+]] +; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @foo.1(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR6]] ; CGSCC-NEXT: [[TEST_RET:%.*]] = extractvalue [[S]] [[CALL]], 0 ; CGSCC-NEXT: ret ptr [[TEST_RET]] ; @@ -128,23 +128,23 @@ } define internal %S @foo.1(ptr %foo.this) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@foo.1 ; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[FOO_THIS:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8 ; TUNIT-NEXT: store ptr [[FOO_THIS]], ptr [[FOO_THIS]], align 8 -; TUNIT-NEXT: call void @bar.2(ptr noalias nocapture nofree noundef nonnull writeonly align 8 [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FOO_THIS]]) #[[ATTR5:[0-9]+]] +; TUNIT-NEXT: call void @bar.2(ptr noalias nocapture nofree noundef nonnull writeonly align 8 [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FOO_THIS]]) #[[ATTR4]] ; TUNIT-NEXT: [[FOO_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8 ; TUNIT-NEXT: ret [[S]] [[FOO_RET]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@foo.1 ; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[FOO_THIS:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8 ; CGSCC-NEXT: store ptr [[FOO_THIS]], ptr [[FOO_THIS]], align 8 -; CGSCC-NEXT: call void @bar.2(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FOO_THIS]]) #[[ATTR6]] +; CGSCC-NEXT: call void @bar.2(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FOO_THIS]]) #[[ATTR8:[0-9]+]] ; CGSCC-NEXT: [[FOO_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8 ; CGSCC-NEXT: ret [[S]] [[FOO_RET]] ; @@ -157,20 +157,20 @@ } define internal void @bar.2(ptr %bar.this, ptr %bar.data) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@bar.2 ; TUNIT-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_THIS:%.*]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: store ptr [[BAR_DATA]], ptr [[BAR_THIS]], align 8 -; TUNIT-NEXT: call void @baz(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA]]) #[[ATTR5]] +; TUNIT-NEXT: call void @baz(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA]]) #[[ATTR4]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@bar.2 ; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_THIS:%.*]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: store ptr [[BAR_DATA]], ptr [[BAR_THIS]], align 8 -; CGSCC-NEXT: call void @baz(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA]]) #[[ATTR6]] +; CGSCC-NEXT: call void @baz(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA]]) #[[ATTR8]] ; CGSCC-NEXT: ret void ; entry: @@ -180,14 +180,14 @@ } define internal void @baz(ptr %baz.this, ptr %baz.data) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@baz ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAZ_THIS:%.*]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAZ_DATA:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: store ptr [[BAZ_DATA]], ptr [[BAZ_THIS]], align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@baz ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAZ_THIS:%.*]], ptr nofree writeonly [[BAZ_DATA:%.*]]) #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -200,7 +200,7 @@ } define ptr @foo(ptr %this, ptr %this.addr, ptr %this1) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@foo ; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -209,12 +209,12 @@ ; TUNIT-NEXT: [[FOO_RET:%.*]] = extractvalue [[S]] [[CALL]], 0 ; TUNIT-NEXT: ret ptr [[FOO_RET]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@foo ; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @bar.5(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]] +; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @bar.5(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR6]] ; CGSCC-NEXT: [[FOO_RET:%.*]] = extractvalue [[S]] [[CALL]], 0 ; CGSCC-NEXT: ret ptr [[FOO_RET]] ; @@ -227,7 +227,7 @@ } define internal %S @bar.5(ptr %this) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@bar.5 ; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -237,13 +237,13 @@ ; TUNIT-NEXT: [[BAR_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8 ; TUNIT-NEXT: ret [[S]] [[BAR_RET]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@bar.5 ; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8 ; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; CGSCC-NEXT: call void @baz.6(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[RETVAL]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]] +; CGSCC-NEXT: call void @baz.6(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[RETVAL]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR9:[0-9]+]] ; CGSCC-NEXT: [[BAR_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8 ; CGSCC-NEXT: ret [[S]] [[BAR_RET]] ; @@ -257,7 +257,7 @@ } define internal void @baz.6(ptr %this, ptr %data) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@baz.6 ; TUNIT-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -265,12 +265,12 @@ ; TUNIT-NEXT: call void @boom(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA]]) #[[ATTR4]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@baz.6 ; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: store ptr [[DATA]], ptr [[THIS]], align 8 -; CGSCC-NEXT: call void @boom(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA]]) #[[ATTR8]] +; CGSCC-NEXT: call void @boom(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA]]) #[[ATTR9]] ; CGSCC-NEXT: ret void ; entry: @@ -280,7 +280,7 @@ } define internal void @boom(ptr %this, ptr %data) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@boom ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -290,7 +290,7 @@ ; TUNIT-NEXT: store ptr [[V]], ptr [[THIS]], align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@boom ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree [[DATA:%.*]]) #[[ATTR4:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -371,7 +371,7 @@ ; Taken from https://github.com/llvm/llvm-project/issues/54981 define dso_local void @spam() { -; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@spam ; TUNIT-SAME: () #[[ATTR2:[0-9]+]] { ; TUNIT-NEXT: bb: @@ -402,7 +402,7 @@ ; TUNIT: bb35: ; TUNIT-NEXT: unreachable ; -; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@spam ; CGSCC-SAME: () #[[ATTR5:[0-9]+]] { ; CGSCC-NEXT: bb: @@ -475,22 +475,22 @@ } define double @t4(ptr %this, ptr %this.addr, ptr %this1) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@t4 ; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[THIS_ADDR1:%.*]] = alloca ptr, i32 0, align 8 ; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @t4a(ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR5]] +; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @t4a(ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR4]] ; TUNIT-NEXT: ret double 0.000000e+00 ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@t4 ; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[THIS_ADDR1:%.*]] = alloca ptr, i32 0, align 8 ; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @t4a(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]] +; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @t4a(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR6]] ; CGSCC-NEXT: [[TMP0:%.*]] = extractvalue [[S]] [[CALL]], 0 ; CGSCC-NEXT: ret double 0.000000e+00 ; @@ -504,24 +504,24 @@ } define internal %S @t4a(ptr %this) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@t4a ; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8 ; TUNIT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; TUNIT-NEXT: call void @t4b(ptr noalias nocapture nofree noundef nonnull writeonly align 8 [[RETVAL]]) #[[ATTR5]] +; TUNIT-NEXT: call void @t4b(ptr noalias nocapture nofree noundef nonnull writeonly align 8 [[RETVAL]]) #[[ATTR4]] ; TUNIT-NEXT: ret [[S]] undef ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@t4a ; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8 ; CGSCC-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; CGSCC-NEXT: call void @t4b(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR6]] +; CGSCC-NEXT: call void @t4b(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]] ; CGSCC-NEXT: [[TMP0:%.*]] = load [[S]], ptr [[RETVAL]], align 8 ; CGSCC-NEXT: ret [[S]] [[TMP0]] ; @@ -539,23 +539,23 @@ } define internal void @t4b(ptr %this, ptr %data) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@t4b ; TUNIT-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; TUNIT-NEXT: [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8 -; TUNIT-NEXT: call void @t4c(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR5]] +; TUNIT-NEXT: call void @t4c(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR4]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@t4b ; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; CGSCC-NEXT: [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; CGSCC-NEXT: store ptr [[DATA]], ptr [[THIS]], align 8 -; CGSCC-NEXT: call void @t4c(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[DATA]]) #[[ATTR6]] +; CGSCC-NEXT: call void @t4c(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[DATA]]) #[[ATTR8]] ; CGSCC-NEXT: ret void ; entry: @@ -570,7 +570,7 @@ } define internal void @t4c(ptr %this, ptr %data) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@t4c ; TUNIT-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: @@ -578,7 +578,7 @@ ; TUNIT-NEXT: [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@t4c ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree writeonly [[DATA:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: entry: @@ -611,22 +611,22 @@ !6 = !{i32 7, !"Dwarf Version", i32 2} !7 = !{i32 2, !"Debug Info Version", i32 3} ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone } -; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind memory(none) } +; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn } ; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn writeonly } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { argmemonly nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind readnone } -; CGSCC: attributes #[[ATTR6]] = { nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR7]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR8]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind memory(none) } +; CGSCC: attributes #[[ATTR6]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR7]] = { willreturn } +; CGSCC: attributes #[[ATTR8]] = { nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR9]] = { nounwind willreturn memory(readwrite) } ;. ; CHECK: [[META0:![0-9]+]] = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]} ; CHECK: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} Index: llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll =================================================================== --- llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll +++ llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll @@ -36,7 +36,7 @@ ; CHECK: @[[GLOBALS:[a-zA-Z0-9_$"\\.-]+]] = internal constant [[STRUCT_S:%.*]] { i32 42, double 3.140000e+00, ptr null, i32 0 }, align 8 ;. define i32 @testOneFieldGlobalS(i32 %cmpx) { -; CHECK: Function Attrs: nofree norecurse nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS ; CHECK-SAME: (i32 [[CMPX:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: @@ -95,7 +95,7 @@ } define i32 @testOneFieldGlobalS_type_mismatch() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_type_mismatch ; CHECK-SAME: () #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: entry: @@ -152,7 +152,7 @@ } define i32 @testOneFieldGlobalS_byte_offset_wrong() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_byte_offset_wrong ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: entry: @@ -210,7 +210,7 @@ ret i32 %r.2 } ;. -; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR1]] = { nofree norecurse nounwind readnone willreturn } -; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree norecurse nosync nounwind willreturn memory(none) } +; CHECK: attributes #[[ATTR1]] = { nofree norecurse nounwind willreturn memory(none) } +; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(none) } ;. Index: llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll =================================================================== --- llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll +++ llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll @@ -57,7 +57,7 @@ ; CHECK: @[[GLOBAL:[a-zA-Z0-9_$"\\.-]+]] = internal global [[STRUCT_STY:%.*]] zeroinitializer, align 8 ;. define void @write_arg(i32* %p, i32 %v) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@write_arg ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: @@ -103,7 +103,7 @@ ; return r; ; } define void @local_alloca_simplifiable_1(%struct.S* noalias sret(%struct.S) align 4 %agg.result) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@local_alloca_simplifiable_1 ; TUNIT-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -135,7 +135,7 @@ ; TUNIT-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR15]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@local_alloca_simplifiable_1 ; CGSCC-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -538,7 +538,7 @@ ; } ; define i32 @local_alloca_simplifiable_3() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3 ; CHECK-SAME: () #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 @@ -563,7 +563,7 @@ ; } ; define i32 @local_alloca_simplifiable_4() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@local_alloca_simplifiable_4 ; CHECK-SAME: () #[[ATTR4]] { ; CHECK-NEXT: ret i32 undef @@ -725,7 +725,7 @@ ; } ; define void @static_global_simplifiable_1(%struct.S* noalias sret(%struct.S) align 4 %agg.result) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@static_global_simplifiable_1 ; TUNIT-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -832,7 +832,7 @@ ; } ; define void @static_global_simplifiable_2() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@static_global_simplifiable_2 ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: entry: @@ -1075,13 +1075,13 @@ ; return Flag3; ; } define i32 @static_global_simplifiable_3() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@static_global_simplifiable_3 ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: store i32 1, i32* @Flag3, align 4, !tbaa [[TBAA3]] ; TUNIT-NEXT: ret i32 1 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@static_global_simplifiable_3 ; CGSCC-SAME: () #[[ATTR6:[0-9]+]] { ; CGSCC-NEXT: store i32 1, i32* @Flag3, align 4, !tbaa [[TBAA3]] @@ -1110,7 +1110,7 @@ ; } ; define void @noalias_arg_simplifiable_1(%struct.S* noalias sret(%struct.S) align 4 %agg.result, %struct.S* byval(%struct.S) align 8 %s) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_1 ; TUNIT-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]], %struct.S* noalias nocapture nofree nonnull byval([[STRUCT_S]]) align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -1160,7 +1160,7 @@ ; TUNIT-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_1 ; CGSCC-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]], %struct.S* noalias nocapture nofree nonnull byval([[STRUCT_S]]) align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: entry: @@ -1683,7 +1683,7 @@ ; We could simplify these if we separate accessed bins wrt. alignment (here mod 4). define i32 @unknown_access_mixed_simplifiable(i32 %arg1, i32 %arg2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@unknown_access_mixed_simplifiable ; CHECK-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: entry: @@ -1721,7 +1721,7 @@ ; The access to bc4b could go anywhere, nothing is simplifiable. define i32 @unknown_access_mixed_not_simplifiable(i32 %arg1, i32 %arg2, i32 %arg3) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@unknown_access_mixed_not_simplifiable ; CHECK-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: entry: @@ -1777,14 +1777,14 @@ ; } ; define i32 @global_not_simplifiable_1(i32 %cnd) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@global_not_simplifiable_1 ; TUNIT-SAME: (i32 [[CND:%.*]]) #[[ATTR6:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[I:%.*]] = load i32, i32* @Flag0, align 4, !tbaa [[TBAA3]] ; TUNIT-NEXT: ret i32 [[I]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@global_not_simplifiable_1 ; CGSCC-SAME: (i32 [[CND:%.*]]) #[[ATTR7:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -1891,13 +1891,13 @@ ret i32 %i } define void @static_global_not_simplifiable_2_helper() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2_helper ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: store i32 2, i32* @Flag4, align 4, !tbaa [[TBAA3]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2_helper ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: store i32 2, i32* @Flag4, align 4, !tbaa [[TBAA3]] @@ -1964,13 +1964,13 @@ ret i32 %l } define void @write_global() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@write_global ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: store i32 7, i32* @Gint2, align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@write_global ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: store i32 7, i32* @Gint2, align 4 @@ -1980,13 +1980,13 @@ ret void } define i32 @read_global() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@read_global ; TUNIT-SAME: () #[[ATTR6]] { ; TUNIT-NEXT: [[L:%.*]] = load i32, i32* @Gint2, align 4 ; TUNIT-NEXT: ret i32 [[L]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@read_global ; CGSCC-SAME: () #[[ATTR7]] { ; CGSCC-NEXT: [[L:%.*]] = load i32, i32* @Gint2, align 4 @@ -1996,12 +1996,12 @@ ret i32 %l } define i32 @write_read_static_global() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@write_read_static_global ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: ret i32 7 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@write_read_static_global ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: ret i32 7 @@ -2011,13 +2011,13 @@ ret i32 %l } define void @write_static_global() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@write_static_global ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: store i32 7, i32* @Gstatic_int2, align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@write_static_global ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: store i32 7, i32* @Gstatic_int2, align 4 @@ -2027,13 +2027,13 @@ ret void } define i32 @read_static_global() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@read_static_global ; TUNIT-SAME: () #[[ATTR6]] { ; TUNIT-NEXT: [[L:%.*]] = load i32, i32* @Gstatic_int2, align 4 ; TUNIT-NEXT: ret i32 [[L]] ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@read_static_global ; CGSCC-SAME: () #[[ATTR7]] { ; CGSCC-NEXT: [[L:%.*]] = load i32, i32* @Gstatic_int2, align 4 @@ -2043,12 +2043,12 @@ ret i32 %l } define i32 @write_read_static_undef_global() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@write_read_static_undef_global ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: ret i32 7 ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@write_read_static_undef_global ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: ret i32 7 @@ -2058,12 +2058,12 @@ ret i32 %l } define void @write_static_undef_global() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@write_static_undef_global ; TUNIT-SAME: () #[[ATTR5]] { ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@write_static_undef_global ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: store i32 7, i32* @Gstatic_undef_int2, align 4 @@ -2073,7 +2073,7 @@ ret void } define i32 @read_static_undef_global() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@read_static_undef_global ; CHECK-SAME: () #[[ATTR4]] { ; CHECK-NEXT: ret i32 7 @@ -2083,7 +2083,7 @@ } define i32 @single_read_of_static_global() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@single_read_of_static_global ; CHECK-SAME: () #[[ATTR4]] { ; CHECK-NEXT: ret i32 0 @@ -2383,7 +2383,7 @@ define void @recursive_load_store(i64 %N, i32 %v) { ; -; TUNIT: Function Attrs: nofree norecurse nosync nounwind writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(write) ; TUNIT-LABEL: define {{[^@]+}}@recursive_load_store ; TUNIT-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR7:[0-9]+]] { ; TUNIT-NEXT: entry: @@ -2398,7 +2398,7 @@ ; TUNIT: for.end: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree norecurse nosync nounwind writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind memory(write) ; CGSCC-LABEL: define {{[^@]+}}@recursive_load_store ; CGSCC-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR8:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -2857,7 +2857,7 @@ ; Make sure the access %1 is not forwarded to the loads %2 and %3 as the indices are ; varying and the accesses thus not "exact". This used to simplify %cmp12 to true. define hidden void @no_propagation_of_unknown_index_access(i32* %in, i32* %out, i32 %idx) #0 { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access ; TUNIT-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -2900,7 +2900,7 @@ ; TUNIT-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1 ; TUNIT-NEXT: br label [[FOR_COND4]], !llvm.loop [[TBAA12]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access ; CGSCC-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR13:[0-9]+]] { ; CGSCC-NEXT: entry: @@ -2992,7 +2992,7 @@ ; Ensure we do not return true. define internal i1 @alloca_non_unique(i32* %p, i32 %in, i1 %c) { -; TUNIT: Function Attrs: argmemonly nofree nosync nounwind +; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@alloca_non_unique ; TUNIT-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR12:[0-9]+]] { ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 @@ -3006,7 +3006,7 @@ ; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]] ; TUNIT-NEXT: ret i1 [[CMP]] ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind +; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@alloca_non_unique ; CGSCC-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR14:[0-9]+]] { ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 @@ -3034,13 +3034,13 @@ ; Ensure we do not return true. define i1 @alloca_non_unique_caller(i32 %in, i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@alloca_non_unique_caller ; TUNIT-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR13:[0-9]+]] { ; TUNIT-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR20]] ; TUNIT-NEXT: ret i1 [[R]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@alloca_non_unique_caller ; CGSCC-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR15:[0-9]+]] { ; CGSCC-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR22]] @@ -3052,22 +3052,22 @@ ; Ensure we do not return %bad or %l, but %sel define i32 @scope_value_traversal(i32 %bad, i1 %c, i1 %c2) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@scope_value_traversal ; TUNIT-SAME: (i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR4]] { ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: store i32 [[BAD]], i32* [[A]], align 4 -; TUNIT-NEXT: call void @scope_value_traversal_helper(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR21:[0-9]+]] +; TUNIT-NEXT: call void @scope_value_traversal_helper(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR16]] ; TUNIT-NEXT: [[L:%.*]] = load i32, i32* [[A]], align 4 ; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]] ; TUNIT-NEXT: ret i32 [[SEL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@scope_value_traversal ; CGSCC-SAME: (i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR16:[0-9]+]] { ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 ; CGSCC-NEXT: store i32 [[BAD]], i32* [[A]], align 4 -; CGSCC-NEXT: call void @scope_value_traversal_helper(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR24:[0-9]+]] +; CGSCC-NEXT: call void @scope_value_traversal_helper(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR19]] ; CGSCC-NEXT: [[L:%.*]] = load i32, i32* [[A]], align 4 ; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]] ; CGSCC-NEXT: ret i32 [[SEL]] @@ -3081,7 +3081,7 @@ } define void @scope_value_traversal_helper(i32* %a, i1 %c) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@scope_value_traversal_helper ; TUNIT-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]], i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[L:%.*]] = load i32, i32* [[A]], align 4 @@ -3089,7 +3089,7 @@ ; TUNIT-NEXT: store i32 [[SEL]], i32* [[A]], align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@scope_value_traversal_helper ; CGSCC-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]], i1 [[C:%.*]]) #[[ATTR13]] { ; CGSCC-NEXT: [[L:%.*]] = load i32, i32* [[A]], align 4 @@ -3139,54 +3139,52 @@ !30 = distinct !{!30, !17} !31 = distinct !{!31, !17} ;. -; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind writeonly } +; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; TUNIT: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn memory(read) } +; TUNIT: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind memory(write) } ; TUNIT: attributes #[[ATTR8:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" } ; TUNIT: attributes #[[ATTR9:[0-9]+]] = { allockind("free") "alloc-family"="malloc" } ; TUNIT: attributes #[[ATTR10:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" } ; TUNIT: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind willreturn uwtable } -; TUNIT: attributes #[[ATTR12]] = { argmemonly nofree nosync nounwind } -; TUNIT: attributes #[[ATTR13]] = { nofree norecurse nosync nounwind readnone } -; TUNIT: attributes #[[ATTR14:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR13]] = { nofree norecurse nosync nounwind memory(none) } +; TUNIT: attributes #[[ATTR14:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } ; TUNIT: attributes #[[ATTR15]] = { willreturn } -; TUNIT: attributes #[[ATTR16]] = { nofree nosync nounwind willreturn writeonly } +; TUNIT: attributes #[[ATTR16]] = { nofree nosync nounwind willreturn } ; TUNIT: attributes #[[ATTR17]] = { nocallback } ; TUNIT: attributes #[[ATTR18]] = { norecurse } ; TUNIT: attributes #[[ATTR19]] = { nounwind } ; TUNIT: attributes #[[ATTR20]] = { nofree nosync nounwind } -; TUNIT: attributes #[[ATTR21]] = { nofree nosync nounwind willreturn } ;. -; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind writeonly } +; CGSCC: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; CGSCC: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn memory(read) } +; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind memory(write) } ; CGSCC: attributes #[[ATTR9:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" } ; CGSCC: attributes #[[ATTR10:[0-9]+]] = { allockind("free") "alloc-family"="malloc" } ; CGSCC: attributes #[[ATTR11:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" } ; CGSCC: attributes #[[ATTR12]] = { nofree norecurse nosync nounwind willreturn uwtable } -; CGSCC: attributes #[[ATTR13]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR14]] = { argmemonly nofree nosync nounwind } -; CGSCC: attributes #[[ATTR15]] = { nofree nosync nounwind readnone } -; CGSCC: attributes #[[ATTR16]] = { nofree nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR17:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR13]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR14]] = { nofree nosync nounwind memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR15]] = { nofree nosync nounwind memory(none) } +; CGSCC: attributes #[[ATTR16]] = { nofree nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR17:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } ; CGSCC: attributes #[[ATTR18]] = { willreturn } -; CGSCC: attributes #[[ATTR19]] = { nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR19]] = { nounwind willreturn } ; CGSCC: attributes #[[ATTR20]] = { nocallback } ; CGSCC: attributes #[[ATTR21]] = { norecurse } ; CGSCC: attributes #[[ATTR22]] = { nounwind } ; CGSCC: attributes #[[ATTR23]] = { nofree nosync nounwind } -; CGSCC: attributes #[[ATTR24]] = { nounwind willreturn } ;. ; TUNIT: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} ; TUNIT: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1} Index: llvm/test/Transforms/Attributor/value-simplify.ll =================================================================== --- llvm/test/Transforms/Attributor/value-simplify.ll +++ llvm/test/Transforms/Attributor/value-simplify.ll @@ -15,7 +15,7 @@ ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = internal constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (void (i8***)* @f1 to i8*), i8* bitcast (void (i1 (i8*)*)* @f2 to i8*)] } ;. define internal i32 addrspace(3)* @const_ptr_return_as3() { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@const_ptr_return_as3 ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: ret i32 addrspace(3)* @ConstAS3Ptr @@ -23,7 +23,7 @@ ret i32 addrspace(3)* @ConstAS3Ptr } define internal i32* @const_ptr_return() { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@const_ptr_return ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: ret i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*) @@ -52,7 +52,7 @@ ; TEST 2 : Simplify return value define i32 @return0() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@return0 ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: ret i32 0 @@ -61,7 +61,7 @@ } define i32 @return1() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@return1 ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: ret i32 1 @@ -70,7 +70,7 @@ } define i32 @test2_1(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test2_1 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] @@ -83,7 +83,7 @@ ; TUNIT-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] ; TUNIT-NEXT: ret i32 1 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test2_1 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] @@ -116,12 +116,12 @@ define i32 @test2_2(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test2_2 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: ret i32 1 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test2_2 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[RET:%.*]] = tail call noundef i32 @test2_1(i1 [[C]]) #[[ATTR12]] @@ -229,7 +229,7 @@ } define i32 @ipccp1(i32 %a) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@ipccp1 ; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]] @@ -247,7 +247,7 @@ } define internal i1 @ipccp2i(i1 %a) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ipccp2i ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: br label [[T:%.*]] @@ -265,12 +265,12 @@ } define i1 @ipccp2() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ipccp2 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ipccp2 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @ipccp2i() #[[ATTR12]] @@ -281,7 +281,7 @@ } define internal i1 @ipccp2ib(i1 %a) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ipccp2ib ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: br label [[T:%.*]] @@ -299,12 +299,12 @@ } define i1 @ipccp2b() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ipccp2b ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ipccp2b ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @ipccp2ib() #[[ATTR12]] @@ -315,7 +315,7 @@ } define internal i32 @ipccp3i(i32 %a) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ipccp3i ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: br label [[T:%.*]] @@ -334,12 +334,12 @@ } define i32 @ipccp3() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ipccp3 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i32 7 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ipccp3 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[R:%.*]] = call noundef i32 @ipccp3i() #[[ATTR12]] @@ -350,7 +350,7 @@ } define internal i32 @ipccp4ia(i1 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ipccp4ia ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -366,7 +366,7 @@ ret i32 1 } define internal i32 @ipccp4ib(i32 %a) { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ipccp4ib ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: br label [[T:%.*]] @@ -386,7 +386,7 @@ } define i32 @ipccp4(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@ipccp4 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -395,7 +395,7 @@ ; TUNIT: f: ; TUNIT-NEXT: ret i32 0 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@ipccp4 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] @@ -417,7 +417,7 @@ ; Do not touch complicated arguments (for now) %struct.X = type { i8* } define internal i32* @test_inalloca(i32* inalloca(i32) %a) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test_inalloca ; CHECK-SAME: (i32* noalias nofree nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: ret i32* [[A]] @@ -425,13 +425,13 @@ ret i32* %a } define i32* @complicated_args_inalloca(i32* %arg) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@complicated_args_inalloca ; TUNIT-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: [[CALL:%.*]] = call nonnull dereferenceable(4) i32* @test_inalloca(i32* noalias nofree writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR9:[0-9]+]] ; TUNIT-NEXT: ret i32* [[CALL]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@complicated_args_inalloca ; CGSCC-SAME: (i32* nofree noundef nonnull readnone dereferenceable(4) [[ARG:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[CALL:%.*]] = call noalias nonnull dereferenceable(4) i32* @test_inalloca(i32* noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) [[ARG]]) #[[ATTR12]] @@ -442,7 +442,7 @@ } define internal i32* @test_preallocated(i32* preallocated(i32) %a) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test_preallocated ; CHECK-SAME: (i32* noalias nofree noundef nonnull returned writeonly preallocated(i32) align 4294967296 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: ret i32* [[A]] @@ -460,7 +460,8 @@ ; CGSCC: Function Attrs: nofree nosync nounwind willreturn ; CGSCC-LABEL: define {{[^@]+}}@complicated_args_preallocated ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] { -; CGSCC-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR13:[0-9]+]] +; CGSCC-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR12]] +; CGSCC-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 4294967296 null) #[[ATTR13:[0-9]+]] [ "preallocated"(token [[C]]) ] ; CGSCC-NEXT: ret i32* null ; %c = call token @llvm.call.preallocated.setup(i32 1) @@ -470,13 +471,13 @@ define internal void @test_sret(%struct.X* sret(%struct.X) %a, %struct.X** %b) { ; -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@test_sret ; TUNIT-SAME: (%struct.X* noalias nofree noundef nonnull writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR3:[0-9]+]] { ; TUNIT-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@test_sret ; CGSCC-SAME: (%struct.X* noalias nofree noundef nonnull writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR4:[0-9]+]] { ; CGSCC-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8 @@ -489,13 +490,13 @@ define void @complicated_args_sret(%struct.X** %b) { ; ; -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@complicated_args_sret ; TUNIT-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]]) #[[ATTR3]] { -; TUNIT-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 null, %struct.X** nocapture nofree writeonly align 8 [[B]]) #[[ATTR11:[0-9]+]] +; TUNIT-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 null, %struct.X** nocapture nofree writeonly align 8 [[B]]) #[[ATTR9]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@complicated_args_sret ; CGSCC-SAME: (%struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR5:[0-9]+]] { ; CGSCC-NEXT: unreachable @@ -505,7 +506,7 @@ } define internal %struct.X* @test_nest(%struct.X* nest %a) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_nest ; CGSCC-SAME: (%struct.X* nest noalias nocapture nofree readnone align 4294967296 [[A:%.*]]) #[[ATTR1]] { ; CGSCC-NEXT: ret %struct.X* null @@ -513,12 +514,12 @@ ret %struct.X* %a } define %struct.X* @complicated_args_nest() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@complicated_args_nest ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret %struct.X* null ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@complicated_args_nest ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[CALL:%.*]] = call noalias noundef align 4294967296 %struct.X* @test_nest(%struct.X* noalias nocapture nofree noundef readnone align 4294967296 null) #[[ATTR12]] @@ -530,7 +531,7 @@ @S = external global %struct.X define internal void @test_byval(%struct.X* byval(%struct.X) %a) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@test_byval ; TUNIT-SAME: (i8* [[TMP0:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 @@ -540,7 +541,7 @@ ; TUNIT-NEXT: store i8* null, i8** [[G0]], align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@test_byval ; CGSCC-SAME: (i8* [[TMP0:%.*]]) #[[ATTR4]] { ; CGSCC-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 @@ -555,19 +556,19 @@ ret void } define void @complicated_args_byval() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@complicated_args_byval ; TUNIT-SAME: () #[[ATTR4:[0-9]+]] { ; TUNIT-NEXT: [[S_CAST:%.*]] = bitcast %struct.X* @S to i8** ; TUNIT-NEXT: [[TMP1:%.*]] = load i8*, i8** [[S_CAST]], align 8 -; TUNIT-NEXT: call void @test_byval(i8* [[TMP1]]) #[[ATTR11]] +; TUNIT-NEXT: call void @test_byval(i8* [[TMP1]]) #[[ATTR9]] ; TUNIT-NEXT: ret void ; ; CGSCC: Function Attrs: nofree nosync nounwind willreturn ; CGSCC-LABEL: define {{[^@]+}}@complicated_args_byval ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: [[TMP1:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0), align 8 -; CGSCC-NEXT: call void @test_byval(i8* nofree writeonly [[TMP1]]) #[[ATTR14:[0-9]+]] +; CGSCC-NEXT: call void @test_byval(i8* nofree writeonly [[TMP1]]) #[[ATTR13]] ; CGSCC-NEXT: ret void ; call void @test_byval(%struct.X* byval(%struct.X) @S) @@ -610,7 +611,7 @@ } define void @fixpoint_changed(i32* %p) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@fixpoint_changed ; TUNIT-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: entry: @@ -633,7 +634,7 @@ ; TUNIT: for.end: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@fixpoint_changed ; CGSCC-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR4]] { ; CGSCC-NEXT: entry: @@ -684,12 +685,12 @@ ; Check we merge undef and a constant properly. define i8 @caller0() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller0 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 49 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller0 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] @@ -699,12 +700,12 @@ ret i8 %c } define i8 @caller1() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller1 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 49 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller1 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] @@ -714,12 +715,12 @@ ret i8 %c } define i8 @caller2() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller2 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 49 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller2 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] @@ -729,12 +730,12 @@ ret i8 %c } define i8 @caller_middle() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller_middle ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 49 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller_middle ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] @@ -744,12 +745,12 @@ ret i8 %c } define i8 @caller3() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller3 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 49 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller3 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] @@ -759,12 +760,12 @@ ret i8 %c } define i8 @caller4() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller4 ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i8 49 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller4 ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] @@ -774,7 +775,7 @@ ret i8 %c } define internal i8 @callee(i8 %a) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@callee ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: ret i8 49 @@ -784,13 +785,13 @@ } define void @user_as3() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@user_as3 ; TUNIT-SAME: () #[[ATTR4]] { ; TUNIT-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@user_as3 ; CGSCC-SAME: () #[[ATTR6:[0-9]+]] { ; CGSCC-NEXT: [[CALL:%.*]] = call fastcc align 4 i32 addrspace(3)* @const_ptr_return_as3() #[[ATTR12]] @@ -802,13 +803,13 @@ ret void } define void @user() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) ; TUNIT-LABEL: define {{[^@]+}}@user ; TUNIT-SAME: () #[[ATTR4]] { ; TUNIT-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(write) ; CGSCC-LABEL: define {{[^@]+}}@user ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: [[CALL:%.*]] = call fastcc align 4 i32* @const_ptr_return() #[[ATTR12]] @@ -822,12 +823,12 @@ define i1 @test_merge_with_undef_values_ptr(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: ret i1 false ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_null(i1 [[C]]) #[[ATTR12]] @@ -837,7 +838,7 @@ ret i1 %r1 } define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) { -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@undef_then_null ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] @@ -858,12 +859,12 @@ } define i1 @test_merge_with_undef_values(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test_merge_with_undef_values ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: ret i1 false ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_1(i1 [[C]]) #[[ATTR12]] @@ -874,7 +875,7 @@ } define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) { ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@undef_then_1 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] @@ -895,12 +896,12 @@ } define i32 @test_select(i32 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test_select ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: ret i32 42 ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_select ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: [[CALL:%.*]] = call noundef i32 @select() #[[ATTR12]] @@ -911,7 +912,7 @@ } define internal i32 @select(i1 %a, i32 %b, i32 %c) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@select ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: ret i32 42 @@ -921,7 +922,7 @@ } define i1 @icmp() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@icmp ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: ret i1 true @@ -973,14 +974,14 @@ @g = internal constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (void (i8***)* @f1 to i8*), i8* bitcast (void (i1 (i8*)*)* @f2 to i8*)] } define internal void @f1(i8*** %a) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; TUNIT-LABEL: define {{[^@]+}}@f1 ; TUNIT-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR3]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: store i8** getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0), i8*** [[A]], align 8 ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CGSCC-LABEL: define {{[^@]+}}@f1 ; CGSCC-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] { ; CGSCC-NEXT: entry: @@ -1044,12 +1045,12 @@ define i1 @test_cmp_null_after_cast() { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test_cmp_null_after_cast ; TUNIT-SAME: () #[[ATTR1]] { ; TUNIT-NEXT: ret i1 true ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_cmp_null_after_cast ; CGSCC-SAME: () #[[ATTR2]] { ; CGSCC-NEXT: [[C:%.*]] = call noundef i1 @cmp_null_after_cast() #[[ATTR12]] @@ -1059,7 +1060,7 @@ ret i1 %c } define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) { -; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@cmp_null_after_cast ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: ret i1 true @@ -1145,7 +1146,7 @@ } define i1 @test_liveness(i1 %c) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test_liveness ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: @@ -1157,7 +1158,7 @@ ; TUNIT-NEXT: [[RC1:%.*]] = call i1 @ret(i1 noundef [[P]]) #[[ATTR9]] ; TUNIT-NEXT: ret i1 [[RC1]] ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn +; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_liveness ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: @@ -1180,7 +1181,7 @@ } define internal i1 @ret(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@ret ; CHECK-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: @@ -1228,7 +1229,7 @@ ; TUNIT-NEXT: [[SRC:%.*]] = alloca i8, align 1 ; TUNIT-NEXT: [[DST:%.*]] = alloca i8, align 1 ; TUNIT-NEXT: store i8 [[ARG]], i8* [[SRC]], align 1 -; TUNIT-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR10]] +; TUNIT-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR11:[0-9]+]] ; TUNIT-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 ; TUNIT-NEXT: ret i8 [[L]] ; @@ -1238,7 +1239,7 @@ ; CGSCC-NEXT: [[SRC:%.*]] = alloca i8, align 1 ; CGSCC-NEXT: [[DST:%.*]] = alloca i8, align 1 ; CGSCC-NEXT: store i8 [[ARG]], i8* [[SRC]], align 1 -; CGSCC-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR13]] +; CGSCC-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR14:[0-9]+]] ; CGSCC-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 ; CGSCC-NEXT: ret i8 [[L]] ; @@ -1254,13 +1255,13 @@ ; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn ; TUNIT-LABEL: define {{[^@]+}}@memcpy_uses_store_caller ; TUNIT-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] { -; TUNIT-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR12:[0-9]+]] +; TUNIT-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR9]] ; TUNIT-NEXT: ret i8 [[R]] ; ; CGSCC: Function Attrs: nofree nosync nounwind willreturn ; CGSCC-LABEL: define {{[^@]+}}@memcpy_uses_store_caller ; CGSCC-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR15:[0-9]+]] +; CGSCC-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR13]] ; CGSCC-NEXT: ret i8 [[R]] ; %r = call i8 @memcpy_uses_store(i8 %arg) @@ -1271,7 +1272,7 @@ declare i32 @speculatable() speculatable readnone define i32 @test_speculatable_expr() norecurse { -; TUNIT: Function Attrs: norecurse nosync readnone +; TUNIT: Function Attrs: norecurse nosync memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test_speculatable_expr ; TUNIT-SAME: () #[[ATTR6:[0-9]+]] { ; TUNIT-NEXT: [[STACK:%.*]] = alloca i32, align 4 @@ -1279,10 +1280,10 @@ ; TUNIT-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1 ; TUNIT-NEXT: store i32 [[PLUS1]], i32* [[STACK]], align 4 ; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* [[STACK]], align 4 -; TUNIT-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[TMP1]]) #[[ATTR13:[0-9]+]] +; TUNIT-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[TMP1]]) #[[ATTR12:[0-9]+]] ; TUNIT-NEXT: ret i32 [[RSPEC]] ; -; CGSCC: Function Attrs: norecurse nosync readnone +; CGSCC: Function Attrs: norecurse nosync memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_speculatable_expr ; CGSCC-SAME: () #[[ATTR9:[0-9]+]] { ; CGSCC-NEXT: [[STACK:%.*]] = alloca i32, align 4 @@ -1301,7 +1302,7 @@ } define internal i32 @ret_speculatable_expr(i32* %mem, i32 %a2) { -; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; TUNIT-LABEL: define {{[^@]+}}@ret_speculatable_expr ; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR7:[0-9]+]] { ; TUNIT-NEXT: [[MEM_PRIV:%.*]] = alloca i32, align 4 @@ -1311,7 +1312,7 @@ ; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 7 ; TUNIT-NEXT: ret i32 [[ADD]] ; -; CGSCC: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@ret_speculatable_expr ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR10:[0-9]+]] { ; CGSCC-NEXT: [[MEM_PRIV:%.*]] = alloca i32, align 4 @@ -1330,34 +1331,32 @@ ;. ; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } ; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR5:[0-9]+]] = { readnone speculatable } -; TUNIT: attributes #[[ATTR6]] = { norecurse nosync readnone } -; TUNIT: attributes #[[ATTR7]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; TUNIT: attributes #[[ATTR8:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } -; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn } +; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(write) } +; TUNIT: attributes #[[ATTR5:[0-9]+]] = { speculatable memory(none) } +; TUNIT: attributes #[[ATTR6]] = { norecurse nosync memory(none) } +; TUNIT: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; TUNIT: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn } ; TUNIT: attributes #[[ATTR10]] = { willreturn } -; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn writeonly } -; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR13]] = { nosync nounwind readonly } +; TUNIT: attributes #[[ATTR11]] = { willreturn memory(readwrite) } +; TUNIT: attributes #[[ATTR12]] = { nosync nounwind } ;. ; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } +; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn writeonly } +; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn memory(argmem: write) } +; CGSCC: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn memory(write) } ; CGSCC: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR8:[0-9]+]] = { readnone speculatable } -; CGSCC: attributes #[[ATTR9]] = { norecurse nosync readnone } -; CGSCC: attributes #[[ATTR10]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; CGSCC: attributes #[[ATTR11:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } -; CGSCC: attributes #[[ATTR12]] = { readnone willreturn } -; CGSCC: attributes #[[ATTR13]] = { willreturn } -; CGSCC: attributes #[[ATTR14]] = { nounwind willreturn writeonly } -; CGSCC: attributes #[[ATTR15]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR8:[0-9]+]] = { speculatable memory(none) } +; CGSCC: attributes #[[ATTR9]] = { norecurse nosync memory(none) } +; CGSCC: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) } +; CGSCC: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR12]] = { willreturn } +; CGSCC: attributes #[[ATTR13]] = { nounwind willreturn } +; CGSCC: attributes #[[ATTR14]] = { willreturn memory(readwrite) } ;. Index: llvm/test/Transforms/Attributor/willreturn.ll =================================================================== --- llvm/test/Transforms/Attributor/willreturn.ll +++ llvm/test/Transforms/Attributor/willreturn.ll @@ -10,7 +10,7 @@ ; TEST 1 (positive case) define void @only_return() #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@only_return ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret void @@ -28,7 +28,7 @@ ; FIXME: missing willreturn define i32 @fib(i32 %0) local_unnamed_addr #0 { -; TUNIT: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; TUNIT: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; TUNIT-LABEL: define {{[^@]+}}@fib ; TUNIT-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 @@ -43,16 +43,16 @@ ; TUNIT: 9: ; TUNIT-NEXT: ret i32 [[TMP0]] ; -; CGSCC: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; CGSCC-LABEL: define {{[^@]+}}@fib ; CGSCC-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 ; CGSCC-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] ; CGSCC: 3: ; CGSCC-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 -; CGSCC-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR19:[0-9]+]] +; CGSCC-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR27:[0-9]+]] ; CGSCC-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 -; CGSCC-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR19]] +; CGSCC-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR27]] ; CGSCC-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] ; CGSCC-NEXT: ret i32 [[TMP8]] ; CGSCC: 9: @@ -84,7 +84,7 @@ ; fact_maybe_not(-1) doesn't stop. define i32 @fact_maybe_not_halt(i32 %0) local_unnamed_addr #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@fact_maybe_not_halt ; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 @@ -132,7 +132,7 @@ ; } define i32 @fact_loop(i32 %0) local_unnamed_addr #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@fact_loop ; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 @@ -176,16 +176,27 @@ declare void @sink() nounwind willreturn nosync nofree define void @mutual_recursion1(i1 %c) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@mutual_recursion1 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR4:[0-9]+]] { -; CHECK-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] -; CHECK: rec: -; CHECK-NEXT: call void @sink() #[[ATTR12:[0-9]+]] -; CHECK-NEXT: call void @mutual_recursion2(i1 noundef [[C]]) #[[ATTR27:[0-9]+]] -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: ret void +; TUNIT: Function Attrs: nofree noinline nosync nounwind uwtable +; TUNIT-LABEL: define {{[^@]+}}@mutual_recursion1 +; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR4:[0-9]+]] { +; TUNIT-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] +; TUNIT: rec: +; TUNIT-NEXT: call void @sink() #[[ATTR12:[0-9]+]] +; TUNIT-NEXT: call void @mutual_recursion2(i1 noundef [[C]]) #[[ATTR26]] +; TUNIT-NEXT: br label [[END]] +; TUNIT: end: +; TUNIT-NEXT: ret void +; +; CGSCC: Function Attrs: nofree noinline nosync nounwind uwtable +; CGSCC-LABEL: define {{[^@]+}}@mutual_recursion1 +; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR4:[0-9]+]] { +; CGSCC-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] +; CGSCC: rec: +; CGSCC-NEXT: call void @sink() #[[ATTR12:[0-9]+]] +; CGSCC-NEXT: call void @mutual_recursion2(i1 noundef [[C]]) #[[ATTR27]] +; CGSCC-NEXT: br label [[END]] +; CGSCC: end: +; CGSCC-NEXT: ret void ; br i1 %c, label %rec, label %end rec: @@ -198,11 +209,17 @@ define void @mutual_recursion2(i1 %c) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@mutual_recursion2 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { -; CHECK-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR27]] -; CHECK-NEXT: ret void +; TUNIT: Function Attrs: nofree noinline nosync nounwind uwtable +; TUNIT-LABEL: define {{[^@]+}}@mutual_recursion2 +; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { +; TUNIT-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR26]] +; TUNIT-NEXT: ret void +; +; CGSCC: Function Attrs: nofree noinline nosync nounwind uwtable +; CGSCC-LABEL: define {{[^@]+}}@mutual_recursion2 +; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { +; CGSCC-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR27]] +; CGSCC-NEXT: ret void ; call void @mutual_recursion1(i1 %c) ret void @@ -277,12 +294,12 @@ ; TEST 6 (positive case) ; Call intrinsic function -; CHECK: Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) ; CHECK-NEXT: declare float @llvm.floor.f32(float) declare float @llvm.floor.f32(float) define void @call_floor(float %a) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@call_floor ; CHECK-SAME: (float [[A:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret void @@ -292,11 +309,17 @@ } define float @call_floor2(float %a) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@call_floor2 -; CHECK-SAME: (float [[A:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR28:[0-9]+]] -; CHECK-NEXT: ret float [[C]] +; TUNIT: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable +; TUNIT-LABEL: define {{[^@]+}}@call_floor2 +; TUNIT-SAME: (float [[A:%.*]]) #[[ATTR0]] { +; TUNIT-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR27:[0-9]+]] +; TUNIT-NEXT: ret float [[C]] +; +; CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable +; CGSCC-LABEL: define {{[^@]+}}@call_floor2 +; CGSCC-SAME: (float [[A:%.*]]) #[[ATTR0]] { +; CGSCC-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR28:[0-9]+]] +; CGSCC-NEXT: ret float [[C]] ; %c = tail call float @llvm.floor.f32(float %a) ret float %c @@ -312,11 +335,17 @@ declare void @maybe_noreturn() #0 define void @call_maybe_noreturn() #0 { -; CHECK: Function Attrs: noinline nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@call_maybe_noreturn -; CHECK-SAME: () #[[ATTR7]] { -; CHECK-NEXT: tail call void @maybe_noreturn() #[[ATTR29:[0-9]+]] -; CHECK-NEXT: ret void +; TUNIT: Function Attrs: noinline nounwind uwtable +; TUNIT-LABEL: define {{[^@]+}}@call_maybe_noreturn +; TUNIT-SAME: () #[[ATTR7]] { +; TUNIT-NEXT: tail call void @maybe_noreturn() #[[ATTR28:[0-9]+]] +; TUNIT-NEXT: ret void +; +; CGSCC: Function Attrs: noinline nounwind uwtable +; CGSCC-LABEL: define {{[^@]+}}@call_maybe_noreturn +; CGSCC-SAME: () #[[ATTR7]] { +; CGSCC-NEXT: tail call void @maybe_noreturn() #[[ATTR29:[0-9]+]] +; CGSCC-NEXT: ret void ; tail call void @maybe_noreturn() ret void @@ -331,11 +360,17 @@ declare void @will_return() willreturn norecurse define void @f1() #0 { -; CHECK: Function Attrs: noinline nounwind willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@f1 -; CHECK-SAME: () #[[ATTR10:[0-9]+]] { -; CHECK-NEXT: tail call void @will_return() #[[ATTR30:[0-9]+]] -; CHECK-NEXT: ret void +; TUNIT: Function Attrs: noinline nounwind willreturn uwtable +; TUNIT-LABEL: define {{[^@]+}}@f1 +; TUNIT-SAME: () #[[ATTR10:[0-9]+]] { +; TUNIT-NEXT: tail call void @will_return() #[[ATTR27]] +; TUNIT-NEXT: ret void +; +; CGSCC: Function Attrs: noinline nounwind willreturn uwtable +; CGSCC-LABEL: define {{[^@]+}}@f1 +; CGSCC-SAME: () #[[ATTR10:[0-9]+]] { +; CGSCC-NEXT: tail call void @will_return() #[[ATTR28]] +; CGSCC-NEXT: ret void ; tail call void @will_return() ret void @@ -344,8 +379,8 @@ define void @f2() #0 { ; CHECK: Function Attrs: noinline nounwind willreturn uwtable ; CHECK-LABEL: define {{[^@]+}}@f2 -; CHECK-SAME: () #[[ATTR10]] { -; CHECK-NEXT: tail call void @f1() #[[ATTR12]] +; CHECK-SAME: () #[[ATTR10:[0-9]+]] { +; CHECK-NEXT: tail call void @f1() #[[ATTR12:[0-9]+]] ; CHECK-NEXT: ret void ; tail call void @f1() @@ -384,17 +419,29 @@ declare i1 @maybe_raise_exception() #1 willreturn define void @invoke_test() personality i32 (...)* @__gxx_personality_v0 { -; CHECK: Function Attrs: nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@invoke_test -; CHECK-SAME: () #[[ATTR12]] personality i32 (...)* @__gxx_personality_v0 { -; CHECK-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR30]] -; CHECK-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] -; CHECK: N: -; CHECK-NEXT: ret void -; CHECK: F: -; CHECK-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 } -; CHECK-NEXT: catch i8* null -; CHECK-NEXT: ret void +; TUNIT: Function Attrs: nounwind willreturn +; TUNIT-LABEL: define {{[^@]+}}@invoke_test +; TUNIT-SAME: () #[[ATTR12]] personality i32 (...)* @__gxx_personality_v0 { +; TUNIT-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR27]] +; TUNIT-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] +; TUNIT: N: +; TUNIT-NEXT: ret void +; TUNIT: F: +; TUNIT-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 } +; TUNIT-NEXT: catch i8* null +; TUNIT-NEXT: ret void +; +; CGSCC: Function Attrs: nounwind willreturn +; CGSCC-LABEL: define {{[^@]+}}@invoke_test +; CGSCC-SAME: () #[[ATTR12]] personality i32 (...)* @__gxx_personality_v0 { +; CGSCC-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR28]] +; CGSCC-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] +; CGSCC: N: +; CGSCC-NEXT: ret void +; CGSCC: F: +; CGSCC-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 } +; CGSCC-NEXT: catch i8* null +; CGSCC-NEXT: ret void ; invoke i1 @maybe_raise_exception() to label %N unwind label %F @@ -420,7 +467,7 @@ ; } define i32 @loop_constant_trip_count(i32* nocapture readonly %0) #0 { -; CHECK: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable ; CHECK-LABEL: define {{[^@]+}}@loop_constant_trip_count ; CHECK-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[TMP0:%.*]]) #[[ATTR13:[0-9]+]] { ; CHECK-NEXT: br label [[TMP3:%.*]] @@ -464,7 +511,7 @@ ; return ans; ; } define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32* nocapture readonly %2, i32 %3) local_unnamed_addr #0 { -; CHECK: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind memory(argmem: read) uwtable ; CHECK-LABEL: define {{[^@]+}}@loop_trip_count_unbound ; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* nocapture nofree readonly [[TMP2:%.*]], i32 [[TMP3:%.*]]) local_unnamed_addr #[[ATTR14:[0-9]+]] { ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] @@ -515,7 +562,7 @@ define i32 @loop_trip_dec(i32 %0, i32* nocapture readonly %1) local_unnamed_addr #0 { -; CHECK: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable ; CHECK-LABEL: define {{[^@]+}}@loop_trip_dec ; CHECK-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr #[[ATTR13]] { ; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1 @@ -562,7 +609,7 @@ ; multiple return define i32 @multiple_return(i32 %a) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@multiple_return ; CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[A]], 0 @@ -586,13 +633,21 @@ ; 15.1 (positive case) define void @unreachable_exit_positive1() #0 { -; CHECK: Function Attrs: noinline nounwind willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_positive1 -; CHECK-SAME: () #[[ATTR10]] { -; CHECK-NEXT: tail call void @will_return() #[[ATTR30]] -; CHECK-NEXT: ret void -; CHECK: unreachable_label: -; CHECK-NEXT: unreachable +; TUNIT: Function Attrs: noinline nounwind willreturn uwtable +; TUNIT-LABEL: define {{[^@]+}}@unreachable_exit_positive1 +; TUNIT-SAME: () #[[ATTR10]] { +; TUNIT-NEXT: tail call void @will_return() #[[ATTR27]] +; TUNIT-NEXT: ret void +; TUNIT: unreachable_label: +; TUNIT-NEXT: unreachable +; +; CGSCC: Function Attrs: noinline nounwind willreturn uwtable +; CGSCC-LABEL: define {{[^@]+}}@unreachable_exit_positive1 +; CGSCC-SAME: () #[[ATTR10]] { +; CGSCC-NEXT: tail call void @will_return() #[[ATTR28]] +; CGSCC-NEXT: ret void +; CGSCC: unreachable_label: +; CGSCC-NEXT: unreachable ; tail call void @will_return() ret void @@ -603,7 +658,7 @@ } define i32 @unreachable_exit_positive2(i32) local_unnamed_addr #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_positive2 ; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 @@ -662,7 +717,7 @@ } define void @unreachable_exit_negative2() #0 { -; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable +; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_negative2 ; CHECK-SAME: () #[[ATTR15:[0-9]+]] { ; CHECK-NEXT: br label [[L1:%.*]] @@ -711,7 +766,7 @@ ; } define i32 @infinite_loop_inside_bounded_loop(i32 %n) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone +; CHECK: Function Attrs: nofree norecurse nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@infinite_loop_inside_bounded_loop ; CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR17:[0-9]+]] { ; CHECK-NEXT: entry: @@ -772,7 +827,7 @@ ; } define i32 @bounded_nested_loops(i32 %n) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@bounded_nested_loops ; CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR18:[0-9]+]] { ; CHECK-NEXT: entry: @@ -849,7 +904,7 @@ ; } define i32 @bounded_loop_inside_unbounded_loop(i32 %n) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone +; CHECK: Function Attrs: nofree norecurse nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@bounded_loop_inside_unbounded_loop ; CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { ; CHECK-NEXT: entry: @@ -933,7 +988,7 @@ ; } define i32 @nested_unbounded_loops(i32 %n) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone +; CHECK: Function Attrs: nofree norecurse nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@nested_unbounded_loops ; CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { ; CHECK-NEXT: entry: @@ -1023,7 +1078,7 @@ ; } define void @non_loop_cycle(i32 %n) { -; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone +; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none) ; TUNIT-LABEL: define {{[^@]+}}@non_loop_cycle ; TUNIT-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { ; TUNIT-NEXT: entry: @@ -1053,9 +1108,9 @@ ; TUNIT: exit: ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: nofree nosync nounwind readnone +; CGSCC: Function Attrs: nofree nosync nounwind memory(none) ; CGSCC-LABEL: define {{[^@]+}}@non_loop_cycle -; CGSCC-SAME: (i32 [[N:%.*]]) #[[ATTR19]] { +; CGSCC-SAME: (i32 [[N:%.*]]) #[[ATTR19:[0-9]+]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) ; CGSCC-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 @@ -1143,29 +1198,29 @@ ret void } define void @willreturn_mustprogress_caller_2() mustprogress { -; TUNIT: Function Attrs: mustprogress readonly willreturn +; TUNIT: Function Attrs: mustprogress willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 ; TUNIT-SAME: () #[[ATTR23:[0-9]+]] { -; TUNIT-NEXT: call void @readonly() #[[ATTR19:[0-9]+]] +; TUNIT-NEXT: call void @readonly() ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: mustprogress readonly willreturn +; CGSCC: Function Attrs: mustprogress willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 ; CGSCC-SAME: () #[[ATTR24:[0-9]+]] { -; CGSCC-NEXT: call void @readonly() #[[ATTR20:[0-9]+]] +; CGSCC-NEXT: call void @readonly() ; CGSCC-NEXT: ret void ; call void @readonly() ret void } define void @willreturn_mustprogress_caller_3() mustprogress { -; TUNIT: Function Attrs: mustprogress nosync readnone willreturn +; TUNIT: Function Attrs: mustprogress nosync willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 ; TUNIT-SAME: () #[[ATTR24:[0-9]+]] { ; TUNIT-NEXT: call void @readnone() ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: mustprogress nosync readnone willreturn +; CGSCC: Function Attrs: mustprogress nosync willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 ; CGSCC-SAME: () #[[ATTR25:[0-9]+]] { ; CGSCC-NEXT: call void @readnone() @@ -1183,16 +1238,16 @@ ret void } define void @willreturn_mustprogress_callee_2() { -; TUNIT: Function Attrs: readonly willreturn +; TUNIT: Function Attrs: willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 ; TUNIT-SAME: () #[[ATTR25:[0-9]+]] { -; TUNIT-NEXT: call void @readonly_mustprogress() #[[ATTR25]] +; TUNIT-NEXT: call void @readonly_mustprogress() #[[ATTR27]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: readonly willreturn +; CGSCC: Function Attrs: willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 ; CGSCC-SAME: () #[[ATTR26:[0-9]+]] { -; CGSCC-NEXT: call void @readonly_mustprogress() #[[ATTR26]] +; CGSCC-NEXT: call void @readonly_mustprogress() #[[ATTR28]] ; CGSCC-NEXT: ret void ; call void @readonly_mustprogress() @@ -1207,16 +1262,16 @@ ret void } define void @willreturn_mustprogress_callee_4() { -; TUNIT: Function Attrs: readonly willreturn +; TUNIT: Function Attrs: willreturn memory(read) ; TUNIT-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 ; TUNIT-SAME: () #[[ATTR25]] { -; TUNIT-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR25]] +; TUNIT-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR27]] ; TUNIT-NEXT: ret void ; -; CGSCC: Function Attrs: readonly willreturn +; CGSCC: Function Attrs: willreturn memory(read) ; CGSCC-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 ; CGSCC-SAME: () #[[ATTR26]] { -; CGSCC-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR26]] +; CGSCC-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR28]] ; CGSCC-NEXT: ret void ; call void @willreturn_mustprogress_callee_2() @@ -1226,67 +1281,64 @@ attributes #0 = { nounwind uwtable noinline } attributes #1 = { uwtable noinline } ;. -; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; TUNIT: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } -; TUNIT: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } +; TUNIT: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } +; TUNIT: attributes #[[ATTR1]] = { nofree noinline nosync nounwind memory(none) uwtable } +; TUNIT: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind memory(none) uwtable } ; TUNIT: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } ; TUNIT: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } ; TUNIT: attributes #[[ATTR5]] = { noreturn } ; TUNIT: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } ; TUNIT: attributes #[[ATTR7]] = { noinline nounwind uwtable } -; TUNIT: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; TUNIT: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; TUNIT: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } ; TUNIT: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } ; TUNIT: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } ; TUNIT: attributes #[[ATTR12]] = { nounwind willreturn } -; TUNIT: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } -; TUNIT: attributes #[[ATTR14]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } -; TUNIT: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } +; TUNIT: attributes #[[ATTR13]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable } +; TUNIT: attributes #[[ATTR14]] = { nofree noinline norecurse nosync nounwind memory(argmem: read) uwtable } +; TUNIT: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind memory(none) uwtable } ; TUNIT: attributes #[[ATTR16:[0-9]+]] = { noreturn nounwind } -; TUNIT: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind readnone } -; TUNIT: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone willreturn } -; TUNIT: attributes #[[ATTR19]] = { readonly } -; TUNIT: attributes #[[ATTR20:[0-9]+]] = { readnone } +; TUNIT: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind memory(none) } +; TUNIT: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; TUNIT: attributes #[[ATTR19:[0-9]+]] = { memory(read) } +; TUNIT: attributes #[[ATTR20:[0-9]+]] = { memory(none) } ; TUNIT: attributes #[[ATTR21]] = { mustprogress } -; TUNIT: attributes #[[ATTR22:[0-9]+]] = { mustprogress readonly } -; TUNIT: attributes #[[ATTR23]] = { mustprogress readonly willreturn } -; TUNIT: attributes #[[ATTR24]] = { mustprogress nosync readnone willreturn } -; TUNIT: attributes #[[ATTR25]] = { readonly willreturn } -; TUNIT: attributes #[[ATTR26]] = { nofree nosync nounwind readnone } -; TUNIT: attributes #[[ATTR27]] = { nofree nosync nounwind } -; TUNIT: attributes #[[ATTR28]] = { readnone willreturn } -; TUNIT: attributes #[[ATTR29]] = { nounwind } -; TUNIT: attributes #[[ATTR30]] = { willreturn } +; TUNIT: attributes #[[ATTR22:[0-9]+]] = { mustprogress memory(read) } +; TUNIT: attributes #[[ATTR23]] = { mustprogress willreturn memory(read) } +; TUNIT: attributes #[[ATTR24]] = { mustprogress nosync willreturn memory(none) } +; TUNIT: attributes #[[ATTR25]] = { willreturn memory(read) } +; TUNIT: attributes #[[ATTR26]] = { nofree nosync nounwind } +; TUNIT: attributes #[[ATTR27]] = { willreturn } +; TUNIT: attributes #[[ATTR28]] = { nounwind } ;. -; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } -; CGSCC: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } +; CGSCC: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable } +; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind memory(none) uwtable } +; CGSCC: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind memory(none) uwtable } ; CGSCC: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } ; CGSCC: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } ; CGSCC: attributes #[[ATTR5]] = { noreturn } ; CGSCC: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } ; CGSCC: attributes #[[ATTR7]] = { noinline nounwind uwtable } -; CGSCC: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CGSCC: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CGSCC: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } ; CGSCC: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } ; CGSCC: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } ; CGSCC: attributes #[[ATTR12]] = { nounwind willreturn } -; CGSCC: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } -; CGSCC: attributes #[[ATTR14]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } -; CGSCC: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } +; CGSCC: attributes #[[ATTR13]] = { nofree noinline norecurse nosync nounwind willreturn memory(argmem: read) uwtable } +; CGSCC: attributes #[[ATTR14]] = { nofree noinline norecurse nosync nounwind memory(argmem: read) uwtable } +; CGSCC: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind memory(none) uwtable } ; CGSCC: attributes #[[ATTR16:[0-9]+]] = { noreturn nounwind } -; CGSCC: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind readnone } -; CGSCC: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone willreturn } -; CGSCC: attributes #[[ATTR19]] = { nofree nosync nounwind readnone } -; CGSCC: attributes #[[ATTR20]] = { readonly } -; CGSCC: attributes #[[ATTR21:[0-9]+]] = { readnone } +; CGSCC: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind memory(none) } +; CGSCC: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind willreturn memory(none) } +; CGSCC: attributes #[[ATTR19]] = { nofree nosync nounwind memory(none) } +; CGSCC: attributes #[[ATTR20:[0-9]+]] = { memory(read) } +; CGSCC: attributes #[[ATTR21:[0-9]+]] = { memory(none) } ; CGSCC: attributes #[[ATTR22]] = { mustprogress } -; CGSCC: attributes #[[ATTR23:[0-9]+]] = { mustprogress readonly } -; CGSCC: attributes #[[ATTR24]] = { mustprogress readonly willreturn } -; CGSCC: attributes #[[ATTR25]] = { mustprogress nosync readnone willreturn } -; CGSCC: attributes #[[ATTR26]] = { readonly willreturn } +; CGSCC: attributes #[[ATTR23:[0-9]+]] = { mustprogress memory(read) } +; CGSCC: attributes #[[ATTR24]] = { mustprogress willreturn memory(read) } +; CGSCC: attributes #[[ATTR25]] = { mustprogress nosync willreturn memory(none) } +; CGSCC: attributes #[[ATTR26]] = { willreturn memory(read) } ; CGSCC: attributes #[[ATTR27]] = { nofree nosync nounwind } -; CGSCC: attributes #[[ATTR28]] = { readnone willreturn } +; CGSCC: attributes #[[ATTR28]] = { willreturn } ; CGSCC: attributes #[[ATTR29]] = { nounwind } -; CGSCC: attributes #[[ATTR30]] = { willreturn } ;. Index: llvm/test/Transforms/Attributor/wrapper.ll =================================================================== --- llvm/test/Transforms/Attributor/wrapper.ll +++ llvm/test/Transforms/Attributor/wrapper.ll @@ -8,7 +8,7 @@ ; CHECK: ret ; ; Check the original function, which is wrapped and becomes anonymous -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK: define internal noundef i32 @0() ; CHECK: ret i32 1 define linkonce i32 @inner1() { @@ -35,7 +35,7 @@ ; CHECK: tail call i32 @1(i32 %a, i32 %b) ; CHECK: ret ; -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; CHECK: define internal i32 @1(i32 %a, i32 %b) ; CHECK: %c = add i32 %a, %b ; CHECK: ret i32 %c Index: llvm/test/Transforms/Coroutines/coro-readnone-02.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-readnone-02.ll +++ llvm/test/Transforms/Coroutines/coro-readnone-02.ll @@ -50,7 +50,7 @@ ; CHECK_SPLITTED-NEXT: call void @nop() ; CHECK_SPLITTED-NEXT: call void @print_same() ; -; CHECK_SPLITTED: attributes #[[ATTR_NUM]] = { readnone } +; CHECK_SPLITTED: attributes #[[ATTR_NUM]] = { memory(none) } ; ; CHECK_UNSPLITTED-LABEL: @f( ; CHECK_UNSPLITTED: br i1 %cmp, label %same, label %diff Index: llvm/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll =================================================================== --- llvm/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll +++ llvm/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll @@ -45,7 +45,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) nounwind readnone ; CHECK: attributes #0 = { nounwind ssp } -; CHECK: attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CHECK: attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CHECK: attributes #2 = { noinline nounwind ssp } ; CHECK: attributes [[NUW]] = { nounwind } Index: llvm/test/Transforms/FunctionAttrs/2008-09-03-Mutual.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/2008-09-03-Mutual.ll +++ llvm/test/Transforms/FunctionAttrs/2008-09-03-Mutual.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -passes=function-attrs -S | FileCheck %s define i32 @a() { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@a ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[TMP:%.*]] = call i32 @b() @@ -13,7 +13,7 @@ } define i32 @b() { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@b ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: [[TMP:%.*]] = call i32 @a() Index: llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadNone.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadNone.ll +++ llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadNone.ll @@ -6,7 +6,7 @@ declare i32 @e() readnone define i32 @f() { -; CHECK: Function Attrs: nofree nosync readnone +; CHECK: Function Attrs: nofree nosync memory(none) ; CHECK-LABEL: @f( ; CHECK-NEXT: [[TMP:%.*]] = call i32 @e() ; CHECK-NEXT: ret i32 [[TMP]] @@ -16,7 +16,7 @@ } define i32 @g() readonly { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @g( ; CHECK-NEXT: ret i32 0 ; @@ -24,7 +24,7 @@ } define i32 @h() readnone { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @h( ; CHECK-NEXT: [[TMP:%.*]] = load i32, ptr @x, align 4 ; CHECK-NEXT: ret i32 [[TMP]] Index: llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadOnly.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadOnly.ll +++ llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadOnly.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -passes=function-attrs -S | FileCheck %s define i32 @f() { -; CHECK: Function Attrs: nofree readonly +; CHECK: Function Attrs: nofree memory(read) ; CHECK-LABEL: @f( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP:%.*]] = call i32 @e() Index: llvm/test/Transforms/FunctionAttrs/2008-12-29-Constant.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/2008-12-29-Constant.ll +++ llvm/test/Transforms/FunctionAttrs/2008-12-29-Constant.ll @@ -4,7 +4,7 @@ @s = external constant i8 define i8 @f() { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @f( ; CHECK-NEXT: [[TMP:%.*]] = load i8, ptr @s, align 1 ; CHECK-NEXT: ret i8 [[TMP]] Index: llvm/test/Transforms/FunctionAttrs/argmemonly.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/argmemonly.ll +++ llvm/test/Transforms/FunctionAttrs/argmemonly.ll @@ -4,7 +4,7 @@ @g = global i32 20 define void @test_no_read_or_write() { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @test_no_read_or_write( ; CHECK-NEXT: entry: ; CHECK-NEXT: ret void @@ -14,7 +14,7 @@ } define i32 @test_only_read_arg(ptr %ptr) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: @test_only_read_arg( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[PTR:%.*]], align 4 @@ -26,7 +26,7 @@ } define i32 @test_only_read_arg_already_has_argmemonly(ptr %ptr) argmemonly { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: @test_only_read_arg_already_has_argmemonly( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[PTR:%.*]], align 4 @@ -38,7 +38,7 @@ } define i32 @test_read_global() { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none) ; CHECK-LABEL: @test_read_global( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L:%.*]] = load i32, ptr @g, align 4 @@ -50,7 +50,7 @@ } define i32 @test_read_loaded_ptr(ptr %ptr) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none) ; CHECK-LABEL: @test_read_loaded_ptr( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L:%.*]] = load ptr, ptr [[PTR:%.*]], align 8 @@ -64,7 +64,7 @@ } define void @test_only_write_arg(ptr %ptr) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: @test_only_write_arg( ; CHECK-NEXT: entry: ; CHECK-NEXT: store i32 0, ptr [[PTR:%.*]], align 4 @@ -76,7 +76,7 @@ } define void @test_write_global() { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) ; CHECK-LABEL: @test_write_global( ; CHECK-NEXT: entry: ; CHECK-NEXT: store i32 0, ptr @g, align 4 @@ -103,7 +103,7 @@ declare i32 @fn_readnone() readnone define void @test_call_readnone(ptr %ptr) { -; CHECK: Function Attrs: argmemonly writeonly +; CHECK: Function Attrs: memory(argmem: write) ; CHECK-LABEL: @test_call_readnone( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C:%.*]] = call i32 @fn_readnone() @@ -119,7 +119,7 @@ declare i32 @fn_argmemonly(ptr) argmemonly define i32 @test_call_argmemonly(ptr %ptr) { -; CHECK: Function Attrs: argmemonly +; CHECK: Function Attrs: memory(argmem: readwrite) ; CHECK-LABEL: @test_call_argmemonly( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C:%.*]] = call i32 @fn_argmemonly(ptr [[PTR:%.*]]) @@ -131,7 +131,7 @@ } define i32 @test_call_fn_where_argmemonly_can_be_inferred(ptr %ptr) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: @test_call_fn_where_argmemonly_can_be_inferred( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C:%.*]] = call i32 @test_only_read_arg(ptr [[PTR:%.*]]) @@ -143,7 +143,7 @@ } define void @test_memcpy_argonly(ptr %dst, ptr %src) { -; CHECK: Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: @test_memcpy_argonly( ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 32, i1 false) @@ -159,7 +159,7 @@ @arr = global [32 x i8] zeroinitializer define void @test_memcpy_src_global(ptr %dst) { -; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) ; CHECK-LABEL: @test_memcpy_src_global( ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr @arr, i64 32, i1 false) @@ -171,7 +171,7 @@ } define void @test_memcpy_dst_global(ptr %src) { -; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) ; CHECK-LABEL: @test_memcpy_dst_global( ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr @arr, ptr [[SRC:%.*]], i64 32, i1 false) @@ -183,7 +183,7 @@ } define i32 @test_read_arg_access_alloca(ptr %ptr) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: @test_read_arg_access_alloca( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 @@ -203,7 +203,7 @@ declare void @fn_inaccessiblememonly() inaccessiblememonly define void @test_inaccessiblememonly() { -; CHECK: Function Attrs: inaccessiblememonly +; CHECK: Function Attrs: memory(inaccessiblemem: readwrite) ; CHECK-LABEL: @test_inaccessiblememonly( ; CHECK-NEXT: call void @fn_inaccessiblememonly() ; CHECK-NEXT: ret void @@ -213,9 +213,9 @@ } define void @test_inaccessiblememonly_readonly() { -; CHECK: Function Attrs: inaccessiblememonly nofree readonly +; CHECK: Function Attrs: nofree memory(inaccessiblemem: read) ; CHECK-LABEL: @test_inaccessiblememonly_readonly( -; CHECK-NEXT: call void @fn_inaccessiblememonly() #[[ATTR15:[0-9]+]] +; CHECK-NEXT: call void @fn_inaccessiblememonly() #[[ATTR16:[0-9]+]] ; CHECK-NEXT: ret void ; call void @fn_inaccessiblememonly() readonly @@ -223,10 +223,10 @@ } define void @test_inaccessibleorargmemonly_readonly(ptr %arg) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree readonly +; CHECK: Function Attrs: nofree memory(argmem: read, inaccessiblemem: read) ; CHECK-LABEL: @test_inaccessibleorargmemonly_readonly( ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG:%.*]], align 4 -; CHECK-NEXT: call void @fn_inaccessiblememonly() #[[ATTR15]] +; CHECK-NEXT: call void @fn_inaccessiblememonly() #[[ATTR16]] ; CHECK-NEXT: ret void ; load i32, ptr %arg @@ -235,10 +235,10 @@ } define void @test_inaccessibleorargmemonly_readwrite(ptr %arg) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly +; CHECK: Function Attrs: memory(argmem: write, inaccessiblemem: read) ; CHECK-LABEL: @test_inaccessibleorargmemonly_readwrite( ; CHECK-NEXT: store i32 0, ptr [[ARG:%.*]], align 4 -; CHECK-NEXT: call void @fn_inaccessiblememonly() #[[ATTR15]] +; CHECK-NEXT: call void @fn_inaccessiblememonly() #[[ATTR16]] ; CHECK-NEXT: ret void ; store i32 0, ptr %arg Index: llvm/test/Transforms/FunctionAttrs/atomic.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/atomic.ll +++ llvm/test/Transforms/FunctionAttrs/atomic.ll @@ -4,7 +4,7 @@ ; Atomic load/store to local doesn't affect whether a function is ; readnone/readonly. define i32 @test1(i32 %x) uwtable ssp { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone ssp willreturn uwtable +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind ssp willreturn memory(none) uwtable ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 @@ -21,7 +21,7 @@ ; A function with an Acquire load is not readonly. define i32 @test2(ptr %x) uwtable ssp { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind ssp willreturn uwtable +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind ssp willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: @test2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[R:%.*]] = load atomic i32, ptr [[X:%.*]] seq_cst, align 4 Index: llvm/test/Transforms/FunctionAttrs/convergent.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/convergent.ll +++ llvm/test/Transforms/FunctionAttrs/convergent.ll @@ -2,7 +2,7 @@ ; RUN: opt -passes=function-attrs -S < %s | FileCheck %s define i32 @nonleaf() convergent { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@nonleaf ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @leaf() @@ -13,7 +13,7 @@ } define i32 @leaf() convergent { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@leaf ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: ret i32 0 @@ -85,7 +85,7 @@ } define i32 @recursive1() convergent { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@recursive1 ; CHECK-SAME: () #[[ATTR5:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @recursive2() #[[ATTR1]] @@ -96,7 +96,7 @@ } define i32 @recursive2() convergent { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@recursive2 ; CHECK-SAME: () #[[ATTR5]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @recursive1() #[[ATTR1]] Index: llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll +++ llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll @@ -5,7 +5,7 @@ ; function attributes when we derive readnone. define ptr @given_argmem_infer_readnone(ptr %p) #0 { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @given_argmem_infer_readnone( ; CHECK-NEXT: entry: ; CHECK-NEXT: ret ptr [[P:%.*]] @@ -15,7 +15,7 @@ } define ptr @given_inaccessible_infer_readnone(ptr %p) #1 { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @given_inaccessible_infer_readnone( ; CHECK-NEXT: entry: ; CHECK-NEXT: ret ptr [[P:%.*]] @@ -25,7 +25,7 @@ } define ptr @given_inaccessible_or_argmem_infer_readnone(ptr %p) #2 { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @given_inaccessible_or_argmem_infer_readnone( ; CHECK-NEXT: entry: ; CHECK-NEXT: ret ptr [[P:%.*]] Index: llvm/test/Transforms/FunctionAttrs/int_sideeffect.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/int_sideeffect.ll +++ llvm/test/Transforms/FunctionAttrs/int_sideeffect.ll @@ -7,7 +7,7 @@ ; is present. define void @test() { -; CHECK: Function Attrs: inaccessiblememonly mustprogress nofree nosync nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CHECK-LABEL: @test( ; CHECK-NEXT: call void @llvm.sideeffect() ; CHECK-NEXT: ret void @@ -17,7 +17,7 @@ } define void @loop() { -; CHECK: Function Attrs: inaccessiblememonly nofree noreturn nosync nounwind +; CHECK: Function Attrs: nofree noreturn nosync nounwind memory(inaccessiblemem: readwrite) ; CHECK-LABEL: @loop( ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: Index: llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll +++ llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll @@ -14,7 +14,7 @@ ; TEST 1 (positive case) define void @only_return() #0 { -; FNATTR: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; FNATTR: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable ; FNATTR-LABEL: define {{[^@]+}}@only_return ; FNATTR-SAME: () #[[ATTR3:[0-9]+]] { ; FNATTR-NEXT: ret void @@ -101,7 +101,7 @@ define void @mutual_recursion1() #0 { -; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; FNATTR-LABEL: define {{[^@]+}}@mutual_recursion1 ; FNATTR-SAME: () #[[ATTR4:[0-9]+]] { ; FNATTR-NEXT: call void @mutual_recursion2() @@ -112,7 +112,7 @@ } define void @mutual_recursion2() #0 { -; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; FNATTR-LABEL: define {{[^@]+}}@mutual_recursion2 ; FNATTR-SAME: () #[[ATTR4]] { ; FNATTR-NEXT: call void @mutual_recursion1() @@ -174,7 +174,7 @@ declare void @nofree_function() nofree readnone #0 define void @call_nofree_function() #0 { -; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; FNATTR-LABEL: define {{[^@]+}}@call_nofree_function ; FNATTR-SAME: () #[[ATTR4]] { ; FNATTR-NEXT: tail call void @nofree_function() @@ -225,7 +225,7 @@ declare float @llvm.floor.f32(float) define void @call_floor(float %a) #0 { -; FNATTR: Function Attrs: mustprogress nofree noinline nosync nounwind readnone willreturn uwtable +; FNATTR: Function Attrs: mustprogress nofree noinline nosync nounwind willreturn memory(none) uwtable ; FNATTR-LABEL: define {{[^@]+}}@call_floor ; FNATTR-SAME: (float [[A:%.*]]) #[[ATTR7:[0-9]+]] { ; FNATTR-NEXT: [[TMP1:%.*]] = tail call float @llvm.floor.f32(float [[A]]) @@ -239,7 +239,7 @@ ; Check propagation. define void @f1() #0 { -; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; FNATTR-LABEL: define {{[^@]+}}@f1 ; FNATTR-SAME: () #[[ATTR4]] { ; FNATTR-NEXT: tail call void @nofree_function() @@ -250,7 +250,7 @@ } define void @f2() #0 { -; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable ; FNATTR-LABEL: define {{[^@]+}}@f2 ; FNATTR-SAME: () #[[ATTR4]] { ; FNATTR-NEXT: tail call void @f1() Index: llvm/test/Transforms/FunctionAttrs/nofree.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/nofree.ll +++ llvm/test/Transforms/FunctionAttrs/nofree.ll @@ -34,7 +34,7 @@ declare void @free(ptr nocapture) local_unnamed_addr #2 define i32 @_Z4foo3Pi(ptr nocapture readonly %a) local_unnamed_addr #3 { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn uwtable +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) uwtable ; CHECK-LABEL: @_Z4foo3Pi( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A:%.*]], align 4 @@ -81,8 +81,8 @@ ; CHECK: Function Attrs: nounwind uwtable ; CHECK-LABEL: @_Z4foo6Pm( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[A:%.*]], align 8 -; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @realloc(ptr [[A]], i64 [[TMP1]]) #[[ATTR2]] +; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[A:%.*]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @realloc(ptr [[A]], i64 [[TMP0]]) #[[ATTR2]] ; CHECK-NEXT: ret ptr [[CALL]] ; entry: Index: llvm/test/Transforms/FunctionAttrs/norecurse.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/norecurse.ll +++ llvm/test/Transforms/FunctionAttrs/norecurse.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs),rpo-function-attrs' -S | FileCheck %s define i32 @leaf() { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@leaf ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret i32 1 @@ -11,7 +11,7 @@ } define i32 @self_rec() { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@self_rec ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @self_rec() @@ -22,7 +22,7 @@ } define i32 @indirect_rec() { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@indirect_rec ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec2() @@ -33,7 +33,7 @@ } define i32 @indirect_rec2() { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@indirect_rec2 ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec() @@ -44,7 +44,7 @@ } define i32 @extern() { -; CHECK: Function Attrs: nofree nosync readnone +; CHECK: Function Attrs: nofree nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@extern ; CHECK-SAME: () #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @k() @@ -57,7 +57,7 @@ declare i32 @k() readnone define void @intrinsic(ptr %dest, ptr %src, i32 %len) { -; CHECK: Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@intrinsic ; CHECK-SAME: (ptr nocapture writeonly [[DEST:%.*]], ptr nocapture readonly [[SRC:%.*]], i32 [[LEN:%.*]]) #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DEST]], ptr [[SRC]], i32 [[LEN]], i1 false) @@ -70,7 +70,7 @@ declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1) define internal i32 @called_by_norecurse() { -; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK: Function Attrs: nofree norecurse nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse ; CHECK-SAME: () #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @k() @@ -81,7 +81,7 @@ } define void @m() norecurse { -; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK: Function Attrs: nofree norecurse nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@m ; CHECK-SAME: () #[[ATTR6]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @called_by_norecurse() @@ -92,7 +92,7 @@ } define internal i32 @called_by_norecurse_indirectly() { -; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK: Function Attrs: nofree norecurse nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly ; CHECK-SAME: () #[[ATTR6]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @k() @@ -103,7 +103,7 @@ } define internal void @o() { -; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK: Function Attrs: nofree norecurse nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@o ; CHECK-SAME: () #[[ATTR6]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly() @@ -114,7 +114,7 @@ } define void @p() norecurse { -; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK: Function Attrs: nofree norecurse nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@p ; CHECK-SAME: () #[[ATTR6]] { ; CHECK-NEXT: call void @o() @@ -125,7 +125,7 @@ } define internal i32 @escapes_as_parameter(ptr %p) { -; CHECK: Function Attrs: nofree nosync readnone +; CHECK: Function Attrs: nofree nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@escapes_as_parameter ; CHECK-SAME: (ptr nocapture readnone [[P:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @k() @@ -136,7 +136,7 @@ } define internal void @q() { -; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK: Function Attrs: nofree norecurse nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@q ; CHECK-SAME: () #[[ATTR6]] { ; CHECK-NEXT: [[A:%.*]] = call i32 @escapes_as_parameter(ptr @escapes_as_parameter) @@ -147,7 +147,7 @@ } define void @r() norecurse { -; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK: Function Attrs: nofree norecurse nosync memory(none) ; CHECK-LABEL: define {{[^@]+}}@r ; CHECK-SAME: () #[[ATTR6]] { ; CHECK-NEXT: call void @q() Index: llvm/test/Transforms/FunctionAttrs/nosync.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/nosync.ll +++ llvm/test/Transforms/FunctionAttrs/nosync.ll @@ -6,7 +6,7 @@ ; Base case, empty function define void @test1() { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @test1( ; CHECK-NEXT: ret void ; @@ -15,7 +15,7 @@ ; Show the bottom up walk define void @test2() { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @test2( ; CHECK-NEXT: call void @test1() ; CHECK-NEXT: ret void @@ -38,7 +38,7 @@ } define i32 @test4(i32 %a, i32 %b) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @test4( ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: ret i32 [[A]] @@ -49,7 +49,7 @@ ; negative case - explicit sync define void @test5(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: @test5( ; CHECK-NEXT: store atomic i8 0, ptr [[P:%.*]] seq_cst, align 1 ; CHECK-NEXT: ret void @@ -60,7 +60,7 @@ ; negative case - explicit sync define i8 @test6(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: @test6( ; CHECK-NEXT: [[V:%.*]] = load atomic i8, ptr [[P:%.*]] seq_cst, align 1 ; CHECK-NEXT: ret i8 [[V]] @@ -71,7 +71,7 @@ ; negative case - explicit sync define void @test7(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: @test7( ; CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P:%.*]], i8 0 seq_cst, align 1 ; CHECK-NEXT: ret void @@ -104,7 +104,7 @@ ; atomic load with monotonic ordering define i32 @load_monotonic(ptr nocapture readonly %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: @load_monotonic( ; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, ptr [[TMP0:%.*]] monotonic, align 4 ; CHECK-NEXT: ret i32 [[TMP2]] @@ -115,7 +115,7 @@ ; atomic store with monotonic ordering. define void @store_monotonic(ptr nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: @store_monotonic( ; CHECK-NEXT: store atomic i32 10, ptr [[TMP0:%.*]] monotonic, align 4 ; CHECK-NEXT: ret void @@ -127,7 +127,7 @@ ; negative, should not deduce nosync ; atomic load with acquire ordering. define i32 @load_acquire(ptr nocapture readonly %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable ; CHECK-LABEL: @load_acquire( ; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, ptr [[TMP0:%.*]] acquire, align 4 ; CHECK-NEXT: ret i32 [[TMP2]] @@ -137,7 +137,7 @@ } define i32 @load_unordered(ptr nocapture readonly %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn uwtable +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) uwtable ; CHECK-LABEL: @load_unordered( ; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, ptr [[TMP0:%.*]] unordered, align 4 ; CHECK-NEXT: ret i32 [[TMP2]] @@ -148,7 +148,7 @@ ; atomic store with unordered ordering. define void @store_unordered(ptr nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly uwtable +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) uwtable ; CHECK-LABEL: @store_unordered( ; CHECK-NEXT: store atomic i32 10, ptr [[TMP0:%.*]] unordered, align 4 ; CHECK-NEXT: ret void @@ -161,7 +161,7 @@ ; negative, should not deduce nosync ; atomic load with release ordering define void @load_release(ptr nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind uwtable +; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable ; CHECK-LABEL: @load_release( ; CHECK-NEXT: store atomic volatile i32 10, ptr [[TMP0:%.*]] release, align 4 ; CHECK-NEXT: ret void @@ -172,7 +172,7 @@ ; negative volatile, relaxed atomic define void @load_volatile_release(ptr nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind uwtable +; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable ; CHECK-LABEL: @load_volatile_release( ; CHECK-NEXT: store atomic volatile i32 10, ptr [[TMP0:%.*]] release, align 4 ; CHECK-NEXT: ret void @@ -183,7 +183,7 @@ ; volatile store. define void @volatile_store(ptr %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind uwtable +; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable ; CHECK-LABEL: @volatile_store( ; CHECK-NEXT: store volatile i32 14, ptr [[TMP0:%.*]], align 4 ; CHECK-NEXT: ret void @@ -195,7 +195,7 @@ ; negative, should not deduce nosync ; volatile load. define i32 @volatile_load(ptr %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly mustprogress nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable ; CHECK-LABEL: @volatile_load( ; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, ptr [[TMP0:%.*]], align 4 ; CHECK-NEXT: ret i32 [[TMP2]] @@ -237,7 +237,7 @@ ; negative, checking volatile intrinsics. define i32 @memcpy_volatile(ptr %ptr1, ptr %ptr2) { -; CHECK: Function Attrs: argmemonly mustprogress nofree nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: @memcpy_volatile( ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[PTR1:%.*]], ptr [[PTR2:%.*]], i32 8, i1 true) ; CHECK-NEXT: ret i32 4 @@ -248,7 +248,7 @@ ; positive, non-volatile intrinsic. define i32 @memset_non_volatile(ptr %ptr1, i8 %val) { -; CHECK: Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: @memset_non_volatile( ; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr [[PTR1:%.*]], i8 [[VAL:%.*]], i32 8, i1 false) ; CHECK-NEXT: ret i32 4 @@ -271,7 +271,7 @@ ; negative. Convergent define void @convergent_readnone(){ -; CHECK: Function Attrs: nofree nosync readnone +; CHECK: Function Attrs: nofree nosync memory(none) ; CHECK-LABEL: @convergent_readnone( ; CHECK-NEXT: call void @readnone_test() ; CHECK-NEXT: ret void @@ -299,7 +299,7 @@ declare float @llvm.cos(float %val) readnone define float @cos_test(float %x) { -; CHECK: Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CHECK-LABEL: @cos_test( ; CHECK-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X:%.*]]) ; CHECK-NEXT: ret float [[C]] Index: llvm/test/Transforms/FunctionAttrs/nounwind.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/nounwind.ll +++ llvm/test/Transforms/FunctionAttrs/nounwind.ll @@ -3,7 +3,7 @@ ; TEST 1 define i32 @foo1() { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@foo1 ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret i32 1 @@ -13,7 +13,7 @@ ; TEST 2 define i32 @scc1_foo() { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@scc1_foo ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @scc1_bar() @@ -26,7 +26,7 @@ ; TEST 3 define i32 @scc1_bar() { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@scc1_bar ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @scc1_foo() Index: llvm/test/Transforms/FunctionAttrs/optnone.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/optnone.ll +++ llvm/test/Transforms/FunctionAttrs/optnone.ll @@ -20,6 +20,6 @@ ; CHECK: (ptr) #1 ; CHECK-LABEL: attributes #0 -; CHECK: = { mustprogress nofree norecurse nosync nounwind readnone willreturn } +; CHECK: = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } ; CHECK-LABEL: attributes #1 ; CHECK: = { noinline optnone } Index: llvm/test/Transforms/FunctionAttrs/readattrs.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/readattrs.ll +++ llvm/test/Transforms/FunctionAttrs/readattrs.ll @@ -18,7 +18,7 @@ } define ptr @test2(ptr %p) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) ; CHECK-LABEL: define {{[^@]+}}@test2 ; CHECK-SAME: (ptr readnone returned [[P:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: store i32 0, ptr @x, align 4 @@ -29,7 +29,7 @@ } define i1 @test3(ptr %p, ptr %q) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test3 ; CHECK-SAME: (ptr readnone [[P:%.*]], ptr readnone [[Q:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[A:%.*]] = icmp ult ptr [[P]], [[Q]] @@ -42,7 +42,7 @@ declare void @test4_1(ptr nocapture) readonly define void @test4_2(ptr %p) { -; CHECK: Function Attrs: nofree readonly +; CHECK: Function Attrs: nofree memory(read) ; CHECK-LABEL: define {{[^@]+}}@test4_2 ; CHECK-SAME: (ptr nocapture readonly [[P:%.*]]) #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: call void @test4_1(ptr [[P]]) @@ -54,7 +54,7 @@ ; Missed optz'n: we could make %q readnone, but don't break test6! define void @test5(ptr %p, ptr %q) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@test5 ; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: store ptr [[Q]], ptr [[P]], align 8 @@ -81,7 +81,7 @@ ; inalloca parameters are always considered written define void @test7_1(ptr inalloca(i32) %a) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@test7_1 ; CHECK-SAME: (ptr nocapture inalloca(i32) [[A:%.*]]) #[[ATTR5:[0-9]+]] { ; CHECK-NEXT: ret void @@ -91,7 +91,7 @@ ; preallocated parameters are always considered written define void @test7_2(ptr preallocated(i32) %a) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@test7_2 ; CHECK-SAME: (ptr nocapture preallocated(i32) [[A:%.*]]) #[[ATTR5]] { ; CHECK-NEXT: ret void @@ -100,7 +100,7 @@ } define ptr @test8_1(ptr %p) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test8_1 ; CHECK-SAME: (ptr readnone returned [[P:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: @@ -111,7 +111,7 @@ } define void @test8_2(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@test8_2 ; CHECK-SAME: (ptr writeonly [[P:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: entry: @@ -128,7 +128,7 @@ declare void @llvm.masked.scatter.v4i32.v4p0(<4 x i32>%val, <4 x ptr>, i32, <4 x i1>) define void @test9(<4 x ptr> %ptrs, <4 x i32>%val) { -; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write) ; CHECK-LABEL: define {{[^@]+}}@test9 ; CHECK-SAME: (<4 x ptr> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR7:[0-9]+]] { ; CHECK-NEXT: call void @llvm.masked.scatter.v4i32.v4p0(<4 x i32> [[VAL]], <4 x ptr> [[PTRS]], i32 4, <4 x i1> ) @@ -140,7 +140,7 @@ declare <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr>, i32, <4 x i1>, <4 x i32>) define <4 x i32> @test10(<4 x ptr> %ptrs) { -; CHECK: Function Attrs: mustprogress nofree nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(read) ; CHECK-LABEL: define {{[^@]+}}@test10 ; CHECK-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR9:[0-9]+]] { ; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> [[PTRS]], i32 4, <4 x i1> , <4 x i32> undef) @@ -152,7 +152,7 @@ declare <4 x i32> @test11_1(<4 x ptr>) argmemonly nounwind readonly define <4 x i32> @test11_2(<4 x ptr> %ptrs) { -; CHECK: Function Attrs: argmemonly nofree nounwind readonly +; CHECK: Function Attrs: nofree nounwind memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@test11_2 ; CHECK-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR11:[0-9]+]] { ; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x ptr> [[PTRS]]) @@ -164,7 +164,7 @@ declare <4 x i32> @test12_1(<4 x ptr>) argmemonly nounwind define <4 x i32> @test12_2(<4 x ptr> %ptrs) { -; CHECK: Function Attrs: argmemonly nounwind +; CHECK: Function Attrs: nounwind memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@test12_2 ; CHECK-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR12:[0-9]+]] { ; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x ptr> [[PTRS]]) @@ -175,7 +175,7 @@ } define i32 @volatile_load(ptr %p) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly mustprogress nofree norecurse nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@volatile_load ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR13:[0-9]+]] { ; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, ptr [[P]], align 4 @@ -246,7 +246,7 @@ } define void @fptr_test1c(ptr %p, ptr %f) { -; CHECK: Function Attrs: nofree readonly +; CHECK: Function Attrs: nofree memory(read) ; CHECK-LABEL: define {{[^@]+}}@fptr_test1c ; CHECK-SAME: (ptr readnone [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: call void [[F]](ptr readnone [[P]]) #[[ATTR2:[0-9]+]] @@ -278,7 +278,7 @@ } define void @fptr_test2c(ptr %p, ptr %f) { -; CHECK: Function Attrs: nofree readonly +; CHECK: Function Attrs: nofree memory(read) ; CHECK-LABEL: define {{[^@]+}}@fptr_test2c ; CHECK-SAME: (ptr readonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: call void [[F]](ptr readonly [[P]]) #[[ATTR2]] @@ -289,7 +289,7 @@ } define void @alloca_recphi() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone +; CHECK: Function Attrs: nofree norecurse nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@alloca_recphi ; CHECK-SAME: () #[[ATTR14:[0-9]+]] { ; CHECK-NEXT: entry: Index: llvm/test/Transforms/FunctionAttrs/stats.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/stats.ll +++ llvm/test/Transforms/FunctionAttrs/stats.ll @@ -16,13 +16,11 @@ ret void } -; CHECK: 1 function-attrs - Number of functions marked argmemonly +; CHECK: 2 function-attrs - Number of functions with improved memory attribute ; CHECK-NEXT: 1 function-attrs - Number of arguments marked nocapture ; CHECK-NEXT: 1 function-attrs - Number of functions marked as nofree ; CHECK-NEXT: 2 function-attrs - Number of functions marked as norecurse ; CHECK-NEXT: 2 function-attrs - Number of functions marked as nosync ; CHECK-NEXT: 2 function-attrs - Number of functions marked as nounwind -; CHECK-NEXT: 1 function-attrs - Number of functions marked readonly ; CHECK-NEXT: 1 function-attrs - Number of arguments marked readonly ; CHECK-NEXT: 2 function-attrs - Number of functions marked as willreturn -; CHECK-NEXT: 1 function-attrs - Number of functions marked writeonly Index: llvm/test/Transforms/FunctionAttrs/willreturn-callsites.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/willreturn-callsites.ll +++ llvm/test/Transforms/FunctionAttrs/willreturn-callsites.ll @@ -38,7 +38,7 @@ } define void @test_fn_mustprogress_readonly_calls(ptr %ptr) mustprogress { -; CHECK: Function Attrs: mustprogress nofree readonly willreturn +; CHECK: Function Attrs: mustprogress nofree willreturn memory(read) ; CHECK-LABEL: @test_fn_mustprogress_readonly_calls( ; CHECK-NOT: call void @decl_readonly() # ; CHECK-NOT: call void @decl_readnone() # Index: llvm/test/Transforms/FunctionAttrs/willreturn.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/willreturn.ll +++ llvm/test/Transforms/FunctionAttrs/willreturn.ll @@ -2,7 +2,7 @@ ; RUN: opt -function-attrs -S %s | FileCheck %s define void @mustprogress_readnone() mustprogress { -; CHECK: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none) ; CHECK-LABEL: @mustprogress_readnone( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[WHILE_BODY:%.*]] @@ -17,7 +17,7 @@ } define i32 @mustprogress_load(ptr %ptr) mustprogress { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse noreturn nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: @mustprogress_load( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[WHILE_BODY:%.*]] @@ -34,7 +34,7 @@ } define void @mustprogress_store(ptr %ptr) mustprogress { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse noreturn nosync nounwind writeonly +; CHECK: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind memory(argmem: write) ; CHECK-LABEL: @mustprogress_store( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[WHILE_BODY:%.*]] @@ -63,7 +63,7 @@ } define i32 @mustprogress_call_known_functions(ptr %ptr) mustprogress { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse noreturn nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: @mustprogress_call_known_functions( ; CHECK-NEXT: call void @mustprogress_readnone() ; CHECK-NEXT: [[R:%.*]] = call i32 @mustprogress_load(ptr [[PTR:%.*]]) @@ -77,7 +77,7 @@ declare i32 @__gxx_personality_v0(...) define i64 @mustprogress_mayunwind() mustprogress personality ptr @__gxx_personality_v0 { -; CHECK: Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CHECK-LABEL: @mustprogress_mayunwind( ; CHECK-NEXT: [[A:%.*]] = invoke i64 @fn_noread() ; CHECK-NEXT: to label [[A:%.*]] unwind label [[B:%.*]] @@ -141,7 +141,7 @@ ; Infinite loop without mustprogress, will not return. define void @willreturn_loop() { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none) ; CHECK-LABEL: @willreturn_loop( ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: @@ -156,7 +156,7 @@ ; Finite loop. Could be willreturn but not detected. ; FIXME define void @willreturn_finite_loop() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone +; CHECK: Function Attrs: nofree norecurse nosync nounwind memory(none) ; CHECK-LABEL: @willreturn_finite_loop( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] @@ -183,7 +183,7 @@ ; Infinite recursion without mustprogress, will not return. define void @willreturn_recursion() { -; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK: Function Attrs: nofree nosync nounwind memory(none) ; CHECK-LABEL: @willreturn_recursion( ; CHECK-NEXT: tail call void @willreturn_recursion() ; CHECK-NEXT: ret void @@ -194,7 +194,7 @@ ; Irreducible infinite loop, will not return. define void @willreturn_irreducible(i1 %c) { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none) ; CHECK-LABEL: @willreturn_irreducible( ; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: Index: llvm/test/Transforms/FunctionAttrs/writeonly.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/writeonly.ll +++ llvm/test/Transforms/FunctionAttrs/writeonly.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -passes=function-attrs -S | FileCheck %s define void @nouses-argworn-funrn(ptr writeonly %.aaa) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funrn ; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: nouses-argworn-funrn_entry: @@ -13,7 +13,7 @@ } define void @nouses-argworn-funro(ptr writeonly %.aaa, ptr %.bbb) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funro ; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]], ptr nocapture readonly [[DOTBBB:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: nouses-argworn-funro_entry: @@ -30,7 +30,7 @@ @d-ccc = internal global %_type_of_d-ccc <{ ptr null, i8 1, i8 13, i8 0, i8 -127 }>, align 8 define void @nouses-argworn-funwo(ptr writeonly %.aaa) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) ; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funwo ; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: nouses-argworn-funwo_entry: @@ -43,7 +43,7 @@ } define void @test_store(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@test_store ; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: store i8 0, ptr [[P]], align 1 @@ -55,7 +55,7 @@ @G = external global ptr define i8 @test_store_capture(ptr %p) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none) ; CHECK-LABEL: define {{[^@]+}}@test_store_capture ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: store ptr [[P]], ptr @G, align 8 @@ -70,7 +70,7 @@ } define void @test_addressing(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) ; CHECK-LABEL: define {{[^@]+}}@test_addressing ; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8 @@ -83,7 +83,7 @@ } define void @test_readwrite(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@test_readwrite ; CHECK-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR5:[0-9]+]] { ; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1 @@ -96,7 +96,7 @@ } define void @test_volatile(ptr %p) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind +; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@test_volatile ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: store volatile i8 0, ptr [[P]], align 1 @@ -107,7 +107,7 @@ } define void @test_atomicrmw(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) ; CHECK-LABEL: define {{[^@]+}}@test_atomicrmw ; CHECK-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR7:[0-9]+]] { ; CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1 @@ -134,7 +134,7 @@ ; writeonly w/o nocapture is not enough define void @direct2(ptr %p) { -; CHECK: Function Attrs: writeonly +; CHECK: Function Attrs: memory(write) ; CHECK-LABEL: define {{[^@]+}}@direct2 ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR8:[0-9]+]] { ; CHECK-NEXT: call void @direct2_callee(ptr [[P]]) @@ -146,9 +146,9 @@ } define void @direct2b(ptr %p) { -; CHECK: Function Attrs: writeonly +; CHECK: Function Attrs: memory(write) ; CHECK-LABEL: define {{[^@]+}}@direct2b -; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR8]] { +; CHECK-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR8]] { ; CHECK-NEXT: call void @direct2_callee(ptr nocapture [[P]]) ; CHECK-NEXT: ret void ; @@ -199,9 +199,9 @@ } define void @fptr_test3(ptr %p, ptr %f) { -; CHECK: Function Attrs: writeonly +; CHECK: Function Attrs: memory(write) ; CHECK-LABEL: define {{[^@]+}}@fptr_test3 -; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR8]] { +; CHECK-SAME: (ptr nocapture [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR8]] { ; CHECK-NEXT: call void [[F]](ptr nocapture [[P]]) #[[ATTR8]] ; CHECK-NEXT: ret void ; Index: llvm/test/Transforms/GlobalOpt/ctor-memset.ll =================================================================== --- llvm/test/Transforms/GlobalOpt/ctor-memset.ll +++ llvm/test/Transforms/GlobalOpt/ctor-memset.ll @@ -115,5 +115,5 @@ declare void @llvm.memset.p0.i64(ptr, i8, i64, i1) ;. -; CHECK: attributes #[[ATTR0:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } +; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } ;. Index: llvm/test/Transforms/GlobalOpt/pr54572.ll =================================================================== --- llvm/test/Transforms/GlobalOpt/pr54572.ll +++ llvm/test/Transforms/GlobalOpt/pr54572.ll @@ -19,5 +19,5 @@ ret void } ;. -; CHECK: attributes #[[ATTR0:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } +; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } ;. Index: llvm/test/Transforms/InferFunctionAttrs/annotate.ll =================================================================== --- llvm/test/Transforms/InferFunctionAttrs/annotate.ll +++ llvm/test/Transforms/InferFunctionAttrs/annotate.ll @@ -1081,25 +1081,25 @@ declare void @memset_pattern16(i8*, i8*, i64) ; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nofree nounwind willreturn } -; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]] = { mustprogress nofree nounwind willreturn writeonly } +; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]] = { mustprogress nofree nounwind willreturn memory(write) } ; CHECK-DAG: attributes [[NOFREE_NOUNWIND]] = { nofree nounwind } -; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE1_FAMILY_MALLOC]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,uninitialized,aligned") allocsize(1) "alloc-family"="malloc" } -; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCZEROED_ALLOCSIZE01_FAMILY_MALLOC]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" } -; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nofree nounwind readonly willreturn } -; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { argmemonly mustprogress nofree nounwind willreturn } -; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind readonly } -; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_FREE_FAMILY_MALLOC]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" } +; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE1_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized,aligned") allocsize(1) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" } +; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCZEROED_ALLOCSIZE01_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,zeroed") allocsize(0,1) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" } +; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(read) } +; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(argmem: readwrite) } +; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind memory(read) } +; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_FREE_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" } ; CHECK-DAG: attributes [[NOFREE_WILLRETURN]] = { mustprogress nofree willreturn } -; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE0_FAMILY_MALLOC]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" } -; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { argmemonly mustprogress nofree nounwind readonly willreturn } +; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE0_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" } +; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(argmem: read) } ; CHECK-DAG: attributes [[NOFREE]] = { nofree } -; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { argmemonly nofree nounwind } -; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE1_FAMILY_MALLOC]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("realloc") allocsize(1) "alloc-family"="malloc" } -; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN_FAMILY_MALLOC]] = { inaccessiblemem_or_argmemonly mustprogress nofree nounwind willreturn "alloc-family"="malloc" } +; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { nofree nounwind memory(argmem: readwrite) } +; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE1_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("realloc") allocsize(1) memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" } +; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" } -; CHECK-NVPTX-DAG: attributes [[NOFREE_NOUNWIND_READNONE]] = { nofree nosync nounwind readnone } +; CHECK-NVPTX-DAG: attributes [[NOFREE_NOUNWIND_READNONE]] = { nofree nosync nounwind memory(none) } -; CHECK-AIX-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCSIZE0_FAMILY_VEC_MALLOC]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) "alloc-family"="vec_malloc" } -; CHECK-AIX-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_FAMILY_VEC_MALLOC]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="vec_malloc" } -; CHECK-AIX-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCSIZE_FAMILY_VEC_MALLOC]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("realloc") allocsize(1) "alloc-family"="vec_malloc" } -; CHECK-AIX-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCSIZE01_FAMILY_VEC_MALLOC]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="vec_malloc" } +; CHECK-AIX-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCSIZE0_FAMILY_VEC_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="vec_malloc" } +; CHECK-AIX-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_FAMILY_VEC_MALLOC]] = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="vec_malloc" } +; CHECK-AIX-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCSIZE_FAMILY_VEC_MALLOC]] = { mustprogress nounwind willreturn allockind("realloc") allocsize(1) memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="vec_malloc" } +; CHECK-AIX-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCSIZE01_FAMILY_VEC_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,zeroed") allocsize(0,1) memory(inaccessiblemem: readwrite) "alloc-family"="vec_malloc" } Index: llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll =================================================================== --- llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll +++ llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll @@ -52,5 +52,5 @@ !28 = !DILocation(line: 9, column: 18, scope: !2) !29 = !DILocation(line: 10, column: 1, scope: !2) -; CHECK: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn } +; CHECK: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: write, inaccessiblemem: none) } ; CHECK-NOT: foo.coefficient1 Index: llvm/test/Transforms/InferFunctionAttrs/readonly_and_writeonly.ll =================================================================== --- llvm/test/Transforms/InferFunctionAttrs/readonly_and_writeonly.ll +++ llvm/test/Transforms/InferFunctionAttrs/readonly_and_writeonly.ll @@ -5,4 +5,4 @@ ; CHECK: declare double @acos(double) [[NOFREE_NOUNWIND_WILLRETURN_READNONE:#[0-9]+]] declare double @acos(double) readonly -; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN_READNONE]] = { mustprogress nofree nosync nounwind readnone willreturn } +; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN_READNONE]] = { mustprogress nofree nosync nounwind willreturn memory(none) } Index: llvm/test/Transforms/Inline/cgscc-update.ll =================================================================== --- llvm/test/Transforms/Inline/cgscc-update.ll +++ llvm/test/Transforms/Inline/cgscc-update.ll @@ -9,8 +9,8 @@ ; CHECK: declare void @unknown() declare void @unknown() -; Basic correctness check: this should get annotated as readnone. -; CHECK: Function Attrs: nounwind readnone +; Basic correctness check: this should get annotated as memory(none). +; CHECK: Function Attrs: nounwind memory(none) ; CHECK-NEXT: declare void @readnone() declare void @readnone() readnone nounwind @@ -26,8 +26,8 @@ ret void } -; This function should have had 'readnone' deduced for its SCC. -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone +; This function should have had 'memory(none)' deduced for its SCC. +; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) ; CHECK-NEXT: define void @test1_g() define void @test1_g() noinline { entry: @@ -35,8 +35,8 @@ ret void } -; This function should have had 'readnone' deduced for its SCC. -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone +; This function should have had 'memory(none)' deduced for its SCC. +; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) ; CHECK-NEXT: define void @test1_h() define void @test1_h() noinline { entry: @@ -58,8 +58,8 @@ ret void()* @test2_h } -; This function should have had 'readnone' deduced for its SCC. -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone +; This function should have had 'memory(none)' deduced for its SCC. +; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) ; CHECK-NEXT: define void @test2_g() define void @test2_g() noinline { entry: @@ -68,8 +68,8 @@ ret void } -; This function should have had 'readnone' deduced for its SCC. -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone +; This function should have had 'memory(none)' deduced for its SCC. +; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) ; CHECK-NEXT: define void @test2_h() define void @test2_h() noinline { entry: @@ -151,8 +151,8 @@ ; interesting call graph update for the new call edge. Eventually, we still ; form a new SCC and should use that can deduce precise function attrs. -; This function should have had 'readnone' deduced for its SCC. -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone +; This function should have had 'memory(none)' deduced for its SCC. +; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) ; CHECK-NEXT: define void @test4_f1() define void @test4_f1() noinline { entry: @@ -174,8 +174,8 @@ ret void } -; This function should have had 'readnone' deduced for its SCC. -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone +; This function should have had 'memory(none)' deduced for its SCC. +; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) ; CHECK-NEXT: define void @test4_h() define void @test4_h() noinline { entry: Index: llvm/test/Transforms/Inline/inline_invoke.ll =================================================================== --- llvm/test/Transforms/Inline/inline_invoke.ll +++ llvm/test/Transforms/Inline/inline_invoke.ll @@ -343,7 +343,7 @@ ; CHECK-NEXT: call void @_ZSt9terminatev() ; CHECK: attributes [[NUW]] = { nounwind } -; CHECK: attributes #1 = { nounwind readnone } +; CHECK: attributes #1 = { nounwind memory(none) } ; CHECK: attributes #2 = { ssp uwtable } -; CHECK: attributes #3 = { argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; CHECK: attributes #4 = { noreturn nounwind } Index: llvm/test/Transforms/InstCombine/AArch64/2012-04-23-Neon-Intrinsics.ll =================================================================== --- llvm/test/Transforms/InstCombine/AArch64/2012-04-23-Neon-Intrinsics.ll +++ llvm/test/Transforms/InstCombine/AArch64/2012-04-23-Neon-Intrinsics.ll @@ -65,6 +65,6 @@ declare <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16>, <4 x i16>) nounwind readnone declare <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16>, <4 x i16>) nounwind readnone -; CHECK: attributes #0 = { nounwind readnone ssp } -; CHECK: attributes #1 = { nocallback nofree nosync nounwind readnone willreturn } +; CHECK: attributes #0 = { nounwind ssp memory(none) } +; CHECK: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK: attributes [[NUW]] = { nounwind } Index: llvm/test/Transforms/InstCombine/stpncpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/stpncpy-1.ll +++ llvm/test/Transforms/InstCombine/stpncpy-1.ll @@ -463,6 +463,6 @@ ret void } ;. -; ANY: attributes #[[ATTR0:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } -; ANY: attributes #[[ATTR1:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } +; ANY: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } +; ANY: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } ;. Index: llvm/test/Transforms/LICM/scalar-promote.ll =================================================================== --- llvm/test/Transforms/LICM/scalar-promote.ll +++ llvm/test/Transforms/LICM/scalar-promote.ll @@ -600,7 +600,7 @@ } define i8 @test_hoistable_existing_load_sinkable_store_writeonly(ptr dereferenceable(8) %ptr, i8 %start) writeonly { -; CHECK: Function Attrs: writeonly +; CHECK: Function Attrs: memory(write) ; CHECK-LABEL: @test_hoistable_existing_load_sinkable_store_writeonly( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[PTR_PROMOTED:%.*]] = load i8, ptr [[PTR:%.*]], align 1 @@ -641,7 +641,7 @@ ; Test case for PR51248. define void @test_sink_store_only() writeonly { -; CHECK: Function Attrs: writeonly +; CHECK: Function Attrs: memory(write) ; CHECK-LABEL: @test_sink_store_only( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] @@ -678,7 +678,7 @@ } define void @test_sink_store_to_local_object_only_loop_must_execute() writeonly { -; CHECK: Function Attrs: writeonly +; CHECK: Function Attrs: memory(write) ; CHECK-LABEL: @test_sink_store_to_local_object_only_loop_must_execute( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 @@ -719,7 +719,7 @@ ; The store in the loop may not execute, so we need to introduce a load in the ; pre-header. Make sure the writeonly attribute is dropped. define void @test_sink_store_to_local_object_only_loop_may_not_execute(i8 %n) writeonly { -; CHECK: Function Attrs: writeonly +; CHECK: Function Attrs: memory(write) ; CHECK-LABEL: @test_sink_store_to_local_object_only_loop_may_not_execute( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 @@ -761,7 +761,7 @@ declare dereferenceable(8) noalias ptr @alloc_writeonly() writeonly define void @test_sink_store_to_noalias_call_object_only_loop_may_not_execute1(i8 %n) writeonly { -; CHECK: Function Attrs: writeonly +; CHECK: Function Attrs: memory(write) ; CHECK-LABEL: @test_sink_store_to_noalias_call_object_only_loop_may_not_execute1( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A:%.*]] = call noalias dereferenceable(8) ptr @alloc_writeonly() @@ -801,7 +801,7 @@ } define void @test_sink_store_only_no_phi_needed() writeonly { -; CHECK: Function Attrs: writeonly +; CHECK: Function Attrs: memory(write) ; CHECK-LABEL: @test_sink_store_only_no_phi_needed( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] Index: llvm/test/Transforms/LICM/strlen.ll =================================================================== --- llvm/test/Transforms/LICM/strlen.ll +++ llvm/test/Transforms/LICM/strlen.ll @@ -13,7 +13,7 @@ } ; CHECK: declare i64 @strlen(ptr nocapture) #0 -; CHECK: attributes #0 = { argmemonly mustprogress nofree nounwind readonly willreturn } +; CHECK: attributes #0 = { mustprogress nofree nounwind willreturn memory(argmem: read) } declare i64 @strlen(ptr) Index: llvm/test/Transforms/LowerMatrixIntrinsics/strided-store-double.ll =================================================================== --- llvm/test/Transforms/LowerMatrixIntrinsics/strided-store-double.ll +++ llvm/test/Transforms/LowerMatrixIntrinsics/strided-store-double.ll @@ -85,4 +85,4 @@ ; CHECK: declare void @llvm.matrix.column.major.store.v6f64.i64(<6 x double>, double* nocapture writeonly, i64, i1 immarg, i32 immarg, i32 immarg) #0 ; CHECK: declare void @llvm.matrix.column.major.store.v10f64.i64(<10 x double>, double* nocapture writeonly, i64, i1 immarg, i32 immarg, i32 immarg) #0 -; CHECK: attributes #0 = { argmemonly nocallback nofree nosync nounwind willreturn writeonly } +; CHECK: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: write) } Index: llvm/test/Transforms/ObjCARC/basic.ll =================================================================== --- llvm/test/Transforms/ObjCARC/basic.ll +++ llvm/test/Transforms/ObjCARC/basic.ll @@ -3073,5 +3073,5 @@ !5 = !{i32 2, !"Debug Info Version", i32 3} ; CHECK: attributes [[NUW]] = { nounwind } -; CHECK: attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CHECK: attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CHECK: ![[RELEASE]] = !{} Index: llvm/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll =================================================================== --- llvm/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll +++ llvm/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll @@ -105,7 +105,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) nounwind readnone ; CHECK: attributes #0 = { ssp uwtable } -; CHECK: attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CHECK: attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CHECK: attributes #2 = { nonlazybind } ; CHECK: attributes [[NUW]] = { nounwind } ; CHECK: attributes #4 = { noinline ssp uwtable } Index: llvm/test/Transforms/ObjCARC/nested.ll =================================================================== --- llvm/test/Transforms/ObjCARC/nested.ll +++ llvm/test/Transforms/ObjCARC/nested.ll @@ -821,5 +821,5 @@ ; CHECK: attributes [[NUW]] = { nounwind } -; CHECK: attributes #1 = { argmemonly nocallback nofree nounwind willreturn writeonly } +; CHECK: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: write) } ; CHECK: attributes #2 = { nonlazybind } Index: llvm/test/Transforms/ObjCARC/rle-s2l.ll =================================================================== --- llvm/test/Transforms/ObjCARC/rle-s2l.ll +++ llvm/test/Transforms/ObjCARC/rle-s2l.ll @@ -135,4 +135,4 @@ } ; CHECK: attributes #0 = { nounwind } -; CHECK: attributes [[RO]] = { readonly } +; CHECK: attributes [[RO]] = { memory(read) } Index: llvm/test/Transforms/OpenMP/add_attributes.ll =================================================================== --- llvm/test/Transforms/OpenMP/add_attributes.ll +++ llvm/test/Transforms/OpenMP/add_attributes.ll @@ -1211,67 +1211,67 @@ ; CHECK: ; Function Attrs: cold convergent noinline nounwind ; CHECK-NEXT: declare void @__kmpc_barrier_simple_spmd(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn writeonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: write) ; OPTIMISTIC-NEXT: declare dso_local void @omp_set_num_threads(i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn writeonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: write) ; OPTIMISTIC-NEXT: declare dso_local void @omp_set_dynamic(i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn writeonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: write) ; OPTIMISTIC-NEXT: declare dso_local void @omp_set_nested(i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn writeonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: write) ; OPTIMISTIC-NEXT: declare dso_local void @omp_set_max_active_levels(i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn writeonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: write) ; OPTIMISTIC-NEXT: declare dso_local void @omp_set_schedule(i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_num_threads() ; OPTIMISTIC-NOT: Function Attrs ; OPTIMISTIC: declare dso_local void @use_int(i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_dynamic() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_nested() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_max_threads() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_thread_num() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_num_procs() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_in_parallel() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_in_final() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_active_level() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_level() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_ancestor_thread_num(i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_team_size(i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_thread_limit() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_max_active_levels() -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare dso_local void @omp_get_schedule(i32* nocapture writeonly, i32* nocapture writeonly) ; OPTIMISTIC-NOT: Function Attrs @@ -1313,7 +1313,7 @@ ; OPTIMISTIC-NOT: Function Attrs ; OPTIMISTIC: declare dso_local void @omp_init_nest_lock_with_hint(%struct.omp_nest_lock_t*, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare dso_local double @omp_get_wtime() ; OPTIMISTIC-NOT: Function Attrs @@ -1340,7 +1340,7 @@ ; OPTIMISTIC-NOT: Function Attrs ; OPTIMISTIC: declare dso_local i32 @omp_get_team_num() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_cancellation() ; OPTIMISTIC-NOT: Function Attrs @@ -1370,25 +1370,25 @@ ; OPTIMISTIC-NOT: Function Attrs ; OPTIMISTIC: declare dso_local i32 @omp_get_device_num() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_proc_bind() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_num_places() ; OPTIMISTIC-NOT: Function Attrs ; OPTIMISTIC: declare dso_local i32 @omp_get_place_num_procs(i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare dso_local void @omp_get_place_proc_ids(i32, i32* nocapture writeonly) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_place_num() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_partition_num_places() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local void @omp_get_partition_place_nums(i32*) ; OPTIMISTIC-NOT: Function Attrs @@ -1433,10 +1433,10 @@ ; OPTIMISTIC-NOT: Function Attrs ; OPTIMISTIC: declare dso_local i32 @omp_pause_resource_all(i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare dso_local i32 @omp_get_supported_active_levels() -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind readonly willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: read) ; OPTIMISTIC-NEXT: declare i32 @__kmpc_global_thread_num(%struct.ident_t* nocapture nofree readonly) ; OPTIMISTIC: ; Function Attrs: nounwind @@ -1445,25 +1445,25 @@ ; OPTIMISTIC: ; Function Attrs: convergent nounwind ; OPTIMISTIC-NEXT: declare i32 @__kmpc_omp_taskwait(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare i32 @__kmpc_omp_taskyield(%struct.ident_t* nocapture nofree readonly, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_push_num_threads(%struct.ident_t* nocapture nofree readonly, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_push_proc_bind(%struct.ident_t* nocapture nofree readonly, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_serialized_parallel(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_end_serialized_parallel(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare i32 @__kmpc_master(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_end_master(%struct.ident_t* nocapture nofree readonly, i32) ; OPTIMISTIC: ; Function Attrs: convergent nounwind @@ -1499,43 +1499,43 @@ ; OPTIMISTIC: ; Function Attrs: convergent nounwind ; OPTIMISTIC-NEXT: declare void @__kmpc_end_ordered(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_for_static_init_4(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_for_static_init_4u(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_for_static_init_8(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64, i64) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_for_static_init_8u(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64, i64) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_for_static_fini(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_team_static_init_4(%struct.ident_t* nocapture nofree readonly, i32, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_team_static_init_4u(%struct.ident_t* nocapture nofree readonly, i32, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_team_static_init_8(%struct.ident_t* nocapture nofree readonly, i32, i32* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64, i64) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_team_static_init_8u(%struct.ident_t* nocapture nofree readonly, i32, i32* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64, i64) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dist_for_static_init_4(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dist_for_static_init_4u(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dist_for_static_init_8(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64, i64) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dist_for_static_init_8u(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64, i64) ; OPTIMISTIC: ; Function Attrs: convergent nounwind @@ -1556,52 +1556,52 @@ ; OPTIMISTIC: ; Function Attrs: convergent nounwind ; OPTIMISTIC-NEXT: declare void @__kmpc_taskgroup(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dist_dispatch_init_4(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i32, i32, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dist_dispatch_init_4u(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i32, i32, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dist_dispatch_init_8(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i64, i64, i64, i64) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dist_dispatch_init_8u(%struct.ident_t* nocapture nofree readonly, i32, i32, i32* nocapture nofree, i64, i64, i64, i64) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dispatch_init_4(%struct.ident_t* nocapture nofree readonly, i32, i32, i32, i32, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dispatch_init_4u(%struct.ident_t* nocapture nofree readonly, i32, i32, i32, i32, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dispatch_init_8(%struct.ident_t* nocapture nofree readonly, i32, i32, i64, i64, i64, i64) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dispatch_init_8u(%struct.ident_t* nocapture nofree readonly, i32, i32, i64, i64, i64, i64) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare i32 @__kmpc_dispatch_next_4(%struct.ident_t* nocapture nofree readonly, i32, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare i32 @__kmpc_dispatch_next_4u(%struct.ident_t* nocapture nofree readonly, i32, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree, i32* nocapture nofree) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare i32 @__kmpc_dispatch_next_8(%struct.ident_t* nocapture nofree readonly, i32, i32* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare i32 @__kmpc_dispatch_next_8u(%struct.ident_t* nocapture nofree readonly, i32, i32* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree, i64* nocapture nofree) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dispatch_fini_4(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dispatch_fini_4u(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dispatch_fini_8(%struct.ident_t* nocapture nofree readonly, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_dispatch_fini_8u(%struct.ident_t* nocapture nofree readonly, i32) ; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn @@ -1619,7 +1619,7 @@ ; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn ; OPTIMISTIC-NEXT: declare i32 @__kmpc_cancellationpoint(%struct.ident_t* nocapture nofree readonly, i32, i32) -; OPTIMISTIC: ; Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; OPTIMISTIC-NEXT: declare void @__kmpc_push_num_teams(%struct.ident_t* nocapture nofree readonly, i32, i32, i32) ; OPTIMISTIC: ; Function Attrs: nounwind @@ -1673,7 +1673,7 @@ ; OPTIMISTIC: ; Function Attrs: nosync nounwind willreturn ; OPTIMISTIC-NEXT: declare void @__kmpc_destroy_allocator(i32, i8*) -; OPTIMISTIC: ; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn writeonly +; OPTIMISTIC: ; Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: write) ; OPTIMISTIC-NEXT: declare void @__kmpc_push_target_tripcount_mapper(%struct.ident_t*, i64, i64) ; OPTIMISTIC: ; Function Attrs: convergent nounwind Index: llvm/test/Transforms/OpenMP/parallel_deletion.ll =================================================================== --- llvm/test/Transforms/OpenMP/parallel_deletion.ll +++ llvm/test/Transforms/OpenMP/parallel_deletion.ll @@ -72,7 +72,7 @@ ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: -; CHECK-NEXT: call void @readonly() #[[ATTR4:[0-9]+]] +; CHECK-NEXT: call void @readonly() ; CHECK-NEXT: ret void ; ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0 @@ -194,9 +194,9 @@ define internal void @.omp_outlined..0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..0 -; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: entry: -; CHECK-NEXT: call void @readonly() #[[ATTR4]] +; CHECK-NEXT: call void @readonly() ; CHECK-NEXT: ret void ; ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..0 @@ -338,7 +338,7 @@ ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR14:[0-9]+]] +; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR9:[0-9]+]] ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CHECK: if.then: @@ -466,7 +466,7 @@ ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5 ; CHECK-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @[[GLOB0]]) #[[ATTR14]] +; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @[[GLOB0]]) #[[ATTR9]] ; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 @@ -541,7 +541,7 @@ ; CHECK-NEXT: [[A1:%.*]] = alloca i32, align 4 ; CHECK-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 ; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A1]] to i8* -; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 [[TMP]]) #[[ATTR0]] +; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 [[TMP]]) #[[ATTR14:[0-9]+]] ; CHECK-NEXT: store i32 1, i32* [[A1]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i32** ; CHECK-NEXT: store i32* [[A1]], i32** [[TMP1]], align 8 Index: llvm/test/Transforms/OpenMP/remove_globalization.ll =================================================================== --- llvm/test/Transforms/OpenMP/remove_globalization.ll +++ llvm/test/Transforms/OpenMP/remove_globalization.ll @@ -80,7 +80,7 @@ ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) #[[ATTR0]], !dbg [[DBG8:![0-9]+]] -; CHECK-NEXT: call void @share(i8* nofree [[TMP0]]) #[[ATTR6:[0-9]+]], !dbg [[DBG8]] +; CHECK-NEXT: call void @share(i8* nofree [[TMP0]]) #[[ATTR1]], !dbg [[DBG8]] ; CHECK-NEXT: call void @__kmpc_free_shared(i8* [[TMP0]], i64 4) #[[ATTR0]] ; CHECK-NEXT: ret void ; @@ -88,7 +88,7 @@ ; CHECK-DISABLED-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-DISABLED-NEXT: entry: ; CHECK-DISABLED-NEXT: [[TMP0:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) #[[ATTR0]], !dbg [[DBG8:![0-9]+]] -; CHECK-DISABLED-NEXT: call void @share(i8* nofree [[TMP0]]) #[[ATTR6:[0-9]+]], !dbg [[DBG8]] +; CHECK-DISABLED-NEXT: call void @share(i8* nofree [[TMP0]]) #[[ATTR1]], !dbg [[DBG8]] ; CHECK-DISABLED-NEXT: call void @__kmpc_free_shared(i8* [[TMP0]], i64 4) #[[ATTR0]] ; CHECK-DISABLED-NEXT: ret void ; @@ -254,19 +254,17 @@ ;. ; CHECK: attributes #[[ATTR0]] = { nounwind } ; CHECK: attributes #[[ATTR1]] = { nosync nounwind } -; CHECK: attributes #[[ATTR2]] = { nounwind readnone } -; CHECK: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind writeonly } +; CHECK: attributes #[[ATTR2]] = { nounwind memory(none) } +; CHECK: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind memory(write) } ; CHECK: attributes #[[ATTR4:[0-9]+]] = { nosync nounwind allocsize(0) } ; CHECK: attributes #[[ATTR5:[0-9]+]] = { "llvm.assume"="omp_no_openmp" } -; CHECK: attributes #[[ATTR6]] = { nosync nounwind writeonly } ;. ; CHECK-DISABLED: attributes #[[ATTR0]] = { nounwind } ; CHECK-DISABLED: attributes #[[ATTR1]] = { nosync nounwind } -; CHECK-DISABLED: attributes #[[ATTR2]] = { nounwind readnone } -; CHECK-DISABLED: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind writeonly } +; CHECK-DISABLED: attributes #[[ATTR2]] = { nounwind memory(none) } +; CHECK-DISABLED: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind memory(write) } ; CHECK-DISABLED: attributes #[[ATTR4:[0-9]+]] = { nosync nounwind allocsize(0) } ; CHECK-DISABLED: attributes #[[ATTR5:[0-9]+]] = { "llvm.assume"="omp_no_openmp" } -; CHECK-DISABLED: attributes #[[ATTR6]] = { nosync nounwind writeonly } ;. ; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) ; CHECK: [[META1:![0-9]+]] = !DIFile(filename: "remove_globalization.c", directory: "/tmp/remove_globalization.c") Index: llvm/test/Transforms/OpenMP/replace_globalization.ll =================================================================== --- llvm/test/Transforms/OpenMP/replace_globalization.ll +++ llvm/test/Transforms/OpenMP/replace_globalization.ll @@ -147,8 +147,8 @@ ; CHECK-NEXT: [[C:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1]], i8 1, i1 false, i1 true) ; CHECK-NEXT: [[X:%.*]] = call align 4 i8* @__kmpc_alloc_shared(i64 4) #[[ATTR6:[0-9]+]] ; CHECK-NEXT: call void @unknown_no_openmp() -; CHECK-NEXT: call void @use.internalized(i8* nofree [[X]]) #[[ATTR7:[0-9]+]] -; CHECK-NEXT: call void @__kmpc_free_shared(i8* [[X]], i64 4) #[[ATTR8:[0-9]+]] +; CHECK-NEXT: call void @use.internalized(i8* nofree [[X]]) #[[ATTR6]] +; CHECK-NEXT: call void @__kmpc_free_shared(i8* [[X]], i64 4) #[[ATTR6]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true) ; CHECK-NEXT: ret void ; @@ -160,14 +160,14 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], -1 ; CHECK-NEXT: br i1 [[CMP]], label [[MASTER1:%.*]], label [[EXIT:%.*]] ; CHECK: master1: -; CHECK-NEXT: call void @use.internalized(i8* nofree addrspacecast (i8 addrspace(3)* getelementptr inbounds ([16 x i8], [16 x i8] addrspace(3)* @x_shared, i32 0, i32 0) to i8*)) #[[ATTR7]] +; CHECK-NEXT: call void @use.internalized(i8* nofree addrspacecast (i8 addrspace(3)* getelementptr inbounds ([16 x i8], [16 x i8] addrspace(3)* @x_shared, i32 0, i32 0) to i8*)) #[[ATTR6]] ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: call void @unknown_no_openmp() ; CHECK-NEXT: [[B0:%.*]] = icmp eq i32 [[C]], -1 ; CHECK-NEXT: br i1 [[B0]], label [[MASTER2:%.*]], label [[EXIT]] ; CHECK: master2: -; CHECK-NEXT: call void @use.internalized(i8* nofree addrspacecast (i8 addrspace(3)* getelementptr inbounds ([4 x i8], [4 x i8] addrspace(3)* @y_shared, i32 0, i32 0) to i8*)) #[[ATTR7]] +; CHECK-NEXT: call void @use.internalized(i8* nofree addrspacecast (i8 addrspace(3)* getelementptr inbounds ([4 x i8], [4 x i8] addrspace(3)* @y_shared, i32 0, i32 0) to i8*)) #[[ATTR6]] ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true) @@ -182,15 +182,15 @@ ; CHECK-NEXT: br i1 [[C0]], label [[MASTER3:%.*]], label [[EXIT:%.*]] ; CHECK: master3: ; CHECK-NEXT: [[Z:%.*]] = call align 4 i8* @__kmpc_alloc_shared(i64 24) #[[ATTR6]], !dbg [[DBG10:![0-9]+]] -; CHECK-NEXT: call void @use.internalized(i8* nofree [[Z]]) #[[ATTR7]] -; CHECK-NEXT: call void @__kmpc_free_shared(i8* [[Z]], i64 24) #[[ATTR8]] +; CHECK-NEXT: call void @use.internalized(i8* nofree [[Z]]) #[[ATTR6]] +; CHECK-NEXT: call void @__kmpc_free_shared(i8* [[Z]], i64 24) #[[ATTR6]] ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 2, i1 true) ; CHECK-NEXT: ret void ; ; -; CHECK: Function Attrs: nofree norecurse nounwind writeonly +; CHECK: Function Attrs: nofree norecurse nounwind memory(write) ; CHECK-LABEL: define {{[^@]+}}@use.internalized ; CHECK-SAME: (i8* nofree [[X:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: @@ -205,6 +205,7 @@ ; CHECK-NEXT: ret void ; ; +; CHECK: Function Attrs: nosync nounwind allocsize(0) memory(read) ; CHECK-LABEL: define {{[^@]+}}@__kmpc_alloc_shared ; CHECK-SAME: (i64 [[TMP0:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[L:%.*]] = load i32, i32* @offset, align 4 @@ -213,14 +214,12 @@ ; ;. ; CHECK: attributes #[[ATTR0]] = { "kernel" } -; CHECK: attributes #[[ATTR1]] = { nofree norecurse nounwind writeonly } -; CHECK: attributes #[[ATTR2]] = { nosync nounwind readonly allocsize(0) } +; CHECK: attributes #[[ATTR1]] = { nofree norecurse nounwind memory(write) } +; CHECK: attributes #[[ATTR2]] = { nosync nounwind allocsize(0) memory(read) } ; CHECK: attributes #[[ATTR3:[0-9]+]] = { nosync nounwind } -; CHECK: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CHECK: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CHECK: attributes #[[ATTR5:[0-9]+]] = { "llvm.assume"="omp_no_openmp" } -; CHECK: attributes #[[ATTR6]] = { nounwind readonly } -; CHECK: attributes #[[ATTR7]] = { nounwind writeonly } -; CHECK: attributes #[[ATTR8]] = { nounwind } +; CHECK: attributes #[[ATTR6]] = { nounwind } ;. ; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) ; CHECK: [[META1:![0-9]+]] = !DIFile(filename: "replace_globalization.c", directory: "/tmp/replace_globalization.c") Index: llvm/test/Transforms/OpenMP/spmdization.ll =================================================================== --- llvm/test/Transforms/OpenMP/spmdization.ll +++ llvm/test/Transforms/OpenMP/spmdization.ll @@ -702,9 +702,9 @@ ; AMDGPU-LABEL: define {{[^@]+}}@__omp_outlined__2 ; AMDGPU-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; AMDGPU-NEXT: entry: -; AMDGPU-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 4, addrspace(5) +; AMDGPU-NEXT: [[X_H2S:%.*]] = alloca i8, i64 4, align 4, addrspace(5) ; AMDGPU-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 -; AMDGPU-NEXT: [[MALLOC_CAST:%.*]] = addrspacecast i8 addrspace(5)* [[TMP0]] to i8* +; AMDGPU-NEXT: [[MALLOC_CAST:%.*]] = addrspacecast i8 addrspace(5)* [[X_H2S]] to i8* ; AMDGPU-NEXT: [[X_ON_STACK:%.*]] = bitcast i8* [[MALLOC_CAST]] to i32* ; AMDGPU-NEXT: call void @use(i32* nocapture [[X_ON_STACK]]) #[[ATTR7]] ; AMDGPU-NEXT: br label [[FOR_COND:%.*]] @@ -716,18 +716,18 @@ ; AMDGPU-NEXT: call void @spmd_amenable() #[[ATTR7]] ; AMDGPU-NEXT: ret void ; AMDGPU: for.body: -; AMDGPU-NEXT: [[TMP1:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA18]] -; AMDGPU-NEXT: [[TMP2:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -; AMDGPU-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP2]], i64 0) +; AMDGPU-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA18]] +; AMDGPU-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +; AMDGPU-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP1]], i64 0) ; AMDGPU-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 ; AMDGPU-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] ; ; NVPTX-LABEL: define {{[^@]+}}@__omp_outlined__2 ; NVPTX-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; NVPTX-NEXT: entry: -; NVPTX-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 4 +; NVPTX-NEXT: [[X_H2S:%.*]] = alloca i8, i64 4, align 4 ; NVPTX-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 -; NVPTX-NEXT: [[X_ON_STACK:%.*]] = bitcast i8* [[TMP0]] to i32* +; NVPTX-NEXT: [[X_ON_STACK:%.*]] = bitcast i8* [[X_H2S]] to i32* ; NVPTX-NEXT: call void @use(i32* nocapture [[X_ON_STACK]]) #[[ATTR7]] ; NVPTX-NEXT: br label [[FOR_COND:%.*]] ; NVPTX: for.cond: @@ -738,18 +738,18 @@ ; NVPTX-NEXT: call void @spmd_amenable() #[[ATTR7]] ; NVPTX-NEXT: ret void ; NVPTX: for.body: -; NVPTX-NEXT: [[TMP1:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA18]] -; NVPTX-NEXT: [[TMP2:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -; NVPTX-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP2]], i64 0) +; NVPTX-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA18]] +; NVPTX-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +; NVPTX-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP1]], i64 0) ; NVPTX-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 ; NVPTX-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] ; ; AMDGPU-DISABLED-LABEL: define {{[^@]+}}@__omp_outlined__2 ; AMDGPU-DISABLED-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; AMDGPU-DISABLED-NEXT: entry: -; AMDGPU-DISABLED-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 4, addrspace(5) +; AMDGPU-DISABLED-NEXT: [[X_H2S:%.*]] = alloca i8, i64 4, align 4, addrspace(5) ; AMDGPU-DISABLED-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 -; AMDGPU-DISABLED-NEXT: [[MALLOC_CAST:%.*]] = addrspacecast i8 addrspace(5)* [[TMP0]] to i8* +; AMDGPU-DISABLED-NEXT: [[MALLOC_CAST:%.*]] = addrspacecast i8 addrspace(5)* [[X_H2S]] to i8* ; AMDGPU-DISABLED-NEXT: [[X_ON_STACK:%.*]] = bitcast i8* [[MALLOC_CAST]] to i32* ; AMDGPU-DISABLED-NEXT: call void @use(i32* nocapture [[X_ON_STACK]]) #[[ATTR7]] ; AMDGPU-DISABLED-NEXT: br label [[FOR_COND:%.*]] @@ -761,18 +761,18 @@ ; AMDGPU-DISABLED-NEXT: call void @spmd_amenable() #[[ATTR7]] ; AMDGPU-DISABLED-NEXT: ret void ; AMDGPU-DISABLED: for.body: -; AMDGPU-DISABLED-NEXT: [[TMP1:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA18]] -; AMDGPU-DISABLED-NEXT: [[TMP2:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -; AMDGPU-DISABLED-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__3 to i8*), i8* @__omp_outlined__3_wrapper.ID, i8** [[TMP2]], i64 0) +; AMDGPU-DISABLED-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA18]] +; AMDGPU-DISABLED-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +; AMDGPU-DISABLED-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__3 to i8*), i8* @__omp_outlined__3_wrapper.ID, i8** [[TMP1]], i64 0) ; AMDGPU-DISABLED-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 ; AMDGPU-DISABLED-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] ; ; NVPTX-DISABLED-LABEL: define {{[^@]+}}@__omp_outlined__2 ; NVPTX-DISABLED-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; NVPTX-DISABLED-NEXT: entry: -; NVPTX-DISABLED-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 4 +; NVPTX-DISABLED-NEXT: [[X_H2S:%.*]] = alloca i8, i64 4, align 4 ; NVPTX-DISABLED-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 -; NVPTX-DISABLED-NEXT: [[X_ON_STACK:%.*]] = bitcast i8* [[TMP0]] to i32* +; NVPTX-DISABLED-NEXT: [[X_ON_STACK:%.*]] = bitcast i8* [[X_H2S]] to i32* ; NVPTX-DISABLED-NEXT: call void @use(i32* nocapture [[X_ON_STACK]]) #[[ATTR7]] ; NVPTX-DISABLED-NEXT: br label [[FOR_COND:%.*]] ; NVPTX-DISABLED: for.cond: @@ -783,9 +783,9 @@ ; NVPTX-DISABLED-NEXT: call void @spmd_amenable() #[[ATTR7]] ; NVPTX-DISABLED-NEXT: ret void ; NVPTX-DISABLED: for.body: -; NVPTX-DISABLED-NEXT: [[TMP1:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA18]] -; NVPTX-DISABLED-NEXT: [[TMP2:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -; NVPTX-DISABLED-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__3 to i8*), i8* @__omp_outlined__3_wrapper.ID, i8** [[TMP2]], i64 0) +; NVPTX-DISABLED-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA18]] +; NVPTX-DISABLED-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +; NVPTX-DISABLED-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__3 to i8*), i8* @__omp_outlined__3_wrapper.ID, i8** [[TMP1]], i64 0) ; NVPTX-DISABLED-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 ; NVPTX-DISABLED-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] ; @@ -2423,7 +2423,7 @@ ; AMDGPU: attributes #[[ATTR6:[0-9]+]] = { nofree nosync nounwind allocsize(0) } ; AMDGPU: attributes #[[ATTR7]] = { convergent "llvm.assume"="ompx_spmd_amenable" } ; AMDGPU: attributes #[[ATTR8]] = { convergent } -; AMDGPU: attributes #[[ATTR9:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; AMDGPU: attributes #[[ATTR9:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; AMDGPU: attributes #[[ATTR10:[0-9]+]] = { alwaysinline } ; AMDGPU: attributes #[[ATTR11:[0-9]+]] = { convergent nounwind } ;. @@ -2436,7 +2436,7 @@ ; NVPTX: attributes #[[ATTR6:[0-9]+]] = { nofree nosync nounwind allocsize(0) } ; NVPTX: attributes #[[ATTR7]] = { convergent "llvm.assume"="ompx_spmd_amenable" } ; NVPTX: attributes #[[ATTR8]] = { convergent } -; NVPTX: attributes #[[ATTR9:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; NVPTX: attributes #[[ATTR9:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; NVPTX: attributes #[[ATTR10:[0-9]+]] = { alwaysinline } ; NVPTX: attributes #[[ATTR11:[0-9]+]] = { convergent nounwind } ;. @@ -2449,7 +2449,7 @@ ; AMDGPU-DISABLED: attributes #[[ATTR6:[0-9]+]] = { nofree nosync nounwind allocsize(0) } ; AMDGPU-DISABLED: attributes #[[ATTR7]] = { convergent "llvm.assume"="ompx_spmd_amenable" } ; AMDGPU-DISABLED: attributes #[[ATTR8]] = { convergent } -; AMDGPU-DISABLED: attributes #[[ATTR9:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; AMDGPU-DISABLED: attributes #[[ATTR9:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; AMDGPU-DISABLED: attributes #[[ATTR10:[0-9]+]] = { alwaysinline } ; AMDGPU-DISABLED: attributes #[[ATTR11:[0-9]+]] = { convergent nounwind } ;. @@ -2462,7 +2462,7 @@ ; NVPTX-DISABLED: attributes #[[ATTR6:[0-9]+]] = { nofree nosync nounwind allocsize(0) } ; NVPTX-DISABLED: attributes #[[ATTR7]] = { convergent "llvm.assume"="ompx_spmd_amenable" } ; NVPTX-DISABLED: attributes #[[ATTR8]] = { convergent } -; NVPTX-DISABLED: attributes #[[ATTR9:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; NVPTX-DISABLED: attributes #[[ATTR9:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; NVPTX-DISABLED: attributes #[[ATTR10:[0-9]+]] = { alwaysinline } ; NVPTX-DISABLED: attributes #[[ATTR11:[0-9]+]] = { convergent nounwind } ;. Index: llvm/test/Transforms/OpenMP/spmdization_assumes.ll =================================================================== --- llvm/test/Transforms/OpenMP/spmdization_assumes.ll +++ llvm/test/Transforms/OpenMP/spmdization_assumes.ll @@ -146,7 +146,7 @@ !11 = !{!"Simple C/C++ TBAA"} ;. ; CHECK: attributes #[[ATTR0]] = { alwaysinline convergent norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -; CHECK: attributes #[[ATTR1]] = { alwaysinline mustprogress nofree norecurse nosync nounwind readnone willreturn "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +; CHECK: attributes #[[ATTR1]] = { alwaysinline mustprogress nofree norecurse nosync nounwind willreturn memory(none) "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } ; CHECK: attributes #[[ATTR2]] = { norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } ; CHECK: attributes #[[ATTR3]] = { nounwind } ; CHECK: attributes #[[ATTR4:[0-9]+]] = { alwaysinline } Index: llvm/test/Transforms/OpenMP/spmdization_guarding.ll =================================================================== --- llvm/test/Transforms/OpenMP/spmdization_guarding.ll +++ llvm/test/Transforms/OpenMP/spmdization_guarding.ll @@ -393,11 +393,11 @@ ; CHECK: attributes #[[ATTR0]] = { convergent norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } ; CHECK: attributes #[[ATTR1:[0-9]+]] = { alwaysinline } ; CHECK: attributes #[[ATTR2:[0-9]+]] = { convergent "frame-pointer"="all" "llvm.assume"="omp_no_openmp,ompx_spmd_amenable" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } -; CHECK: attributes #[[ATTR3:[0-9]+]] = { convergent nounwind readonly willreturn "frame-pointer"="all" "llvm.assume"="ompx_spmd_amenable" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } +; CHECK: attributes #[[ATTR3:[0-9]+]] = { convergent nounwind willreturn memory(read) "frame-pointer"="all" "llvm.assume"="ompx_spmd_amenable" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } ; CHECK: attributes #[[ATTR4:[0-9]+]] = { nosync nounwind allocsize(0) } ; CHECK: attributes #[[ATTR5:[0-9]+]] = { nosync nounwind } ; CHECK: attributes #[[ATTR6]] = { nounwind } -; CHECK: attributes #[[ATTR7:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #[[ATTR7:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } ; CHECK: attributes #[[ATTR8:[0-9]+]] = { convergent nounwind } ; CHECK: attributes #[[ATTR9]] = { nounwind willreturn } ; CHECK: attributes #[[ATTR10]] = { convergent nounwind "llvm.assume"="omp_no_openmp,ompx_spmd_amenable" } @@ -405,11 +405,11 @@ ; CHECK-DISABLED: attributes #[[ATTR0]] = { convergent norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } ; CHECK-DISABLED: attributes #[[ATTR1:[0-9]+]] = { alwaysinline } ; CHECK-DISABLED: attributes #[[ATTR2:[0-9]+]] = { convergent "frame-pointer"="all" "llvm.assume"="omp_no_openmp,ompx_spmd_amenable" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } -; CHECK-DISABLED: attributes #[[ATTR3:[0-9]+]] = { convergent nounwind readonly willreturn "frame-pointer"="all" "llvm.assume"="ompx_spmd_amenable" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } +; CHECK-DISABLED: attributes #[[ATTR3:[0-9]+]] = { convergent nounwind willreturn memory(read) "frame-pointer"="all" "llvm.assume"="ompx_spmd_amenable" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } ; CHECK-DISABLED: attributes #[[ATTR4:[0-9]+]] = { nosync nounwind allocsize(0) } ; CHECK-DISABLED: attributes #[[ATTR5:[0-9]+]] = { nosync nounwind } ; CHECK-DISABLED: attributes #[[ATTR6]] = { nounwind } -; CHECK-DISABLED: attributes #[[ATTR7:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } +; CHECK-DISABLED: attributes #[[ATTR7:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } ; CHECK-DISABLED: attributes #[[ATTR8:[0-9]+]] = { convergent nounwind } ; CHECK-DISABLED: attributes #[[ATTR9]] = { nounwind willreturn } ; CHECK-DISABLED: attributes #[[ATTR10]] = { convergent nounwind "llvm.assume"="omp_no_openmp,ompx_spmd_amenable" } Index: llvm/test/Transforms/OpenMP/spmdization_guarding_two_reaching_kernels.ll =================================================================== --- llvm/test/Transforms/OpenMP/spmdization_guarding_two_reaching_kernels.ll +++ llvm/test/Transforms/OpenMP/spmdization_guarding_two_reaching_kernels.ll @@ -152,7 +152,7 @@ ; CHECK-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 ; CHECK-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] ; CHECK: user_code.entry: -; CHECK-NEXT: call void @generic_helper() #[[ATTR6:[0-9]+]] +; CHECK-NEXT: call void @generic_helper() #[[ATTR5]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 2, i1 false) ; CHECK-NEXT: ret void ; CHECK: worker.exit: @@ -165,7 +165,7 @@ ; CHECK-DISABLE-SPMDIZATION-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1 ; CHECK-DISABLE-SPMDIZATION-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] ; CHECK-DISABLE-SPMDIZATION: user_code.entry: -; CHECK-DISABLE-SPMDIZATION-NEXT: call void @generic_helper() #[[ATTR6:[0-9]+]] +; CHECK-DISABLE-SPMDIZATION-NEXT: call void @generic_helper() #[[ATTR5]] ; CHECK-DISABLE-SPMDIZATION-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true) ; CHECK-DISABLE-SPMDIZATION-NEXT: ret void ; CHECK-DISABLE-SPMDIZATION: worker.exit: @@ -191,7 +191,7 @@ ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 -; CHECK-NEXT: call void @leaf() #[[ATTR6]] +; CHECK-NEXT: call void @leaf() #[[ATTR5]] ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB2]]) #[[ATTR2:[0-9]+]] ; CHECK-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** ; CHECK-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__ to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined___wrapper to i8*), i8** [[TMP1]], i64 0) @@ -201,7 +201,7 @@ ; CHECK-DISABLE-SPMDIZATION-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-DISABLE-SPMDIZATION-NEXT: entry: ; CHECK-DISABLE-SPMDIZATION-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 -; CHECK-DISABLE-SPMDIZATION-NEXT: call void @leaf() #[[ATTR6]] +; CHECK-DISABLE-SPMDIZATION-NEXT: call void @leaf() #[[ATTR5]] ; CHECK-DISABLE-SPMDIZATION-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB2]]) #[[ATTR2:[0-9]+]] ; CHECK-DISABLE-SPMDIZATION-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** ; CHECK-DISABLE-SPMDIZATION-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__ to i8*), i8* @__omp_outlined___wrapper.ID, i8** [[TMP1]], i64 0) @@ -223,7 +223,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: call void @unknown() #[[ATTR7:[0-9]+]] +; CHECK-NEXT: call void @unknown() #[[ATTR6:[0-9]+]] ; CHECK-NEXT: ret void ; ; CHECK-DISABLE-SPMDIZATION-LABEL: define {{[^@]+}}@__omp_outlined__ @@ -231,7 +231,7 @@ ; CHECK-DISABLE-SPMDIZATION-NEXT: entry: ; CHECK-DISABLE-SPMDIZATION-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-DISABLE-SPMDIZATION-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-DISABLE-SPMDIZATION-NEXT: call void @unknown() #[[ATTR7:[0-9]+]] +; CHECK-DISABLE-SPMDIZATION-NEXT: call void @unknown() #[[ATTR6:[0-9]+]] ; CHECK-DISABLE-SPMDIZATION-NEXT: ret void ; entry: @@ -325,13 +325,13 @@ ; CHECK-LABEL: define {{[^@]+}}@generic_helper ; CHECK-SAME: () #[[ATTR4]] { ; CHECK-NEXT: entry: -; CHECK-NEXT: call void @leaf() #[[ATTR6]] +; CHECK-NEXT: call void @leaf() #[[ATTR5]] ; CHECK-NEXT: ret void ; ; CHECK-DISABLE-SPMDIZATION-LABEL: define {{[^@]+}}@generic_helper ; CHECK-DISABLE-SPMDIZATION-SAME: () #[[ATTR4]] { ; CHECK-DISABLE-SPMDIZATION-NEXT: entry: -; CHECK-DISABLE-SPMDIZATION-NEXT: call void @leaf() #[[ATTR6]] +; CHECK-DISABLE-SPMDIZATION-NEXT: call void @leaf() #[[ATTR5]] ; CHECK-DISABLE-SPMDIZATION-NEXT: ret void ; entry: @@ -368,19 +368,17 @@ ; CHECK: attributes #[[ATTR1]] = { convergent noinline nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } ; CHECK: attributes #[[ATTR2]] = { nounwind } ; CHECK: attributes #[[ATTR3:[0-9]+]] = { alwaysinline } -; CHECK: attributes #[[ATTR4]] = { convergent noinline nounwind writeonly "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } +; CHECK: attributes #[[ATTR4]] = { convergent noinline nounwind memory(write) "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } ; CHECK: attributes #[[ATTR5]] = { convergent nounwind } -; CHECK: attributes #[[ATTR6]] = { convergent nounwind writeonly } -; CHECK: attributes #[[ATTR7]] = { convergent } +; CHECK: attributes #[[ATTR6]] = { convergent } ;. ; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR0]] = { convergent noinline norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } ; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR1]] = { convergent noinline nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } ; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR2]] = { nounwind } ; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR3:[0-9]+]] = { alwaysinline } -; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR4]] = { convergent noinline nounwind writeonly "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } +; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR4]] = { convergent noinline nounwind memory(write) "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" } ; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR5]] = { convergent nounwind } -; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR6]] = { convergent nounwind writeonly } -; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR7]] = { convergent } +; CHECK-DISABLE-SPMDIZATION: attributes #[[ATTR6]] = { convergent } ;. ; CHECK: [[META0:![0-9]+]] = !{i32 0, i32 43, i32 17011637, !"spmd", i32 12, i32 0} ; CHECK: [[META1:![0-9]+]] = !{i32 0, i32 43, i32 17011637, !"generic", i32 20, i32 1} Index: llvm/test/Transforms/RewriteStatepointsForGC/X86/intrinsic-attributes.ll =================================================================== --- llvm/test/Transforms/RewriteStatepointsForGC/X86/intrinsic-attributes.ll +++ llvm/test/Transforms/RewriteStatepointsForGC/X86/intrinsic-attributes.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -S -rewrite-statepoints-for-gc | FileCheck %s -; CHECK: Function Attrs: nounwind readnone +; CHECK: Function Attrs: nounwind memory(none) ; CHECK: declare i64 @llvm.x86.sse2.cvttsd2si64(<2 x double>) declare i64 @llvm.x86.sse2.cvttsd2si64(<2 x double>) Index: llvm/test/Transforms/RewriteStatepointsForGC/statepoint-attrs.ll =================================================================== --- llvm/test/Transforms/RewriteStatepointsForGC/statepoint-attrs.ll +++ llvm/test/Transforms/RewriteStatepointsForGC/statepoint-attrs.ll @@ -20,6 +20,6 @@ attributes #1 = { norecurse noimplicitfloat } ;. -; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone } +; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind memory(none) } ; CHECK: attributes #[[ATTR1]] = { noimplicitfloat norecurse } ;. Index: llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll =================================================================== --- llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll +++ llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals ; RUN: opt -passes=ipsccp -S %s | FileCheck %s ; Test cases to ensure argmemonly/inaccessiblemem_or_argmemonly attributes are @@ -10,8 +10,11 @@ ; Here the pointer argument %arg will be replaced by a constant. We need to ; drop argmemonly. +;. +; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 0 +;. define internal void @ptrarg.1(i32* %arg, i32 %val) argmemonly nounwind { -; CHECK: Function Attrs: nounwind +; CHECK: Function Attrs: nounwind memory(readwrite, inaccessiblemem: none) ; CHECK-LABEL: @ptrarg.1( ; CHECK-NEXT: store i32 10, i32* @g, align 4 ; CHECK-NEXT: ret void @@ -37,7 +40,7 @@ ; Here only the non-pointer argument %val is replaced, no need ; to drop the argmemonly attribute. define internal void @ptrarg.2(i32* %arg, i32 %val) argmemonly nounwind { -; CHECK: Function Attrs: argmemonly nounwind +; CHECK: Function Attrs: nounwind memory(argmem: readwrite) ; CHECK-LABEL: @ptrarg.2( ; CHECK-NEXT: store i32 10, i32* [[ARG:%.*]], align 4 ; CHECK-NEXT: ret void @@ -59,7 +62,7 @@ ; Here the pointer argument %arg will be replaced by a constant. We need to ; drop inaccessiblemem_or_argmemonly. define internal void @ptrarg.3(i32* %arg, i32 %val) inaccessiblemem_or_argmemonly nounwind { -; CHECK: Function Attrs: nounwind +; CHECK: Function Attrs: nounwind memory(readwrite) ; CHECK-LABEL: @ptrarg.3( ; CHECK-NEXT: store i32 10, i32* @g, align 4 ; CHECK-NEXT: ret void @@ -85,7 +88,7 @@ ; Here only the non-pointer argument %val is replaced, no need ; to drop the inaccessiblemem_or_argmemonly attribute. define internal void @ptrarg.4(i32* %arg, i32 %val) inaccessiblemem_or_argmemonly nounwind { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nounwind +; CHECK: Function Attrs: nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: @ptrarg.4( ; CHECK-NEXT: store i32 10, i32* [[ARG:%.*]], align 4 ; CHECK-NEXT: ret void @@ -107,7 +110,7 @@ ; Here the pointer argument %arg will be replaced by a constant. We need to ; drop inaccessiblemem_or_argmemonly. define internal void @ptrarg.5(i32* %arg, i32 %val) argmemonly inaccessiblemem_or_argmemonly nounwind { -; CHECK: Function Attrs: nounwind +; CHECK: Function Attrs: nounwind memory(readwrite, inaccessiblemem: none) ; CHECK-LABEL: @ptrarg.5( ; CHECK-NEXT: store i32 10, i32* @g, align 4 ; CHECK-NEXT: ret void @@ -143,10 +146,10 @@ define i32 @caller.6.cs.attributes(i32 %n) { ; CHECK-LABEL: @caller.6.cs.attributes( ; CHECK-NEXT: store i32 1, i32* @g, align 4 -; CHECK-NEXT: tail call void @ptrarg.5(i32* @g, i32 10) [[NOUNWIND:#[0-9]+]] -; CHECK-NEXT: tail call void @ptrarg.5(i32* @g, i32 10) [[NOUNWIND:#[0-9]+]] -; CHECK-NEXT: tail call void @ptrarg.5(i32* @g, i32 10) [[NOUNWIND:#[0-9]+]] -; CHECK-NEXT: tail call void @ptrarg.5(i32* @g, i32 10) [[NOUNWIND:#[0-9]+]] +; CHECK-NEXT: tail call void @ptrarg.5(i32* @g, i32 10) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: tail call void @ptrarg.5(i32* @g, i32 10) #[[ATTR2:[0-9]+]] +; CHECK-NEXT: tail call void @ptrarg.5(i32* @g, i32 10) #[[ATTR0]] +; CHECK-NEXT: tail call void @ptrarg.5(i32* @g, i32 10) #[[ATTR4:[0-9]+]] ; CHECK-NEXT: [[G_VAL:%.*]] = load i32, i32* @g, align 4 ; CHECK-NEXT: ret i32 [[G_VAL]] ; @@ -159,4 +162,10 @@ ret i32 %g.val } -; CHECK: [[NOUNWIND]] = { nounwind } +;. +; CHECK: attributes #[[ATTR0]] = { nounwind memory(readwrite, inaccessiblemem: none) } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(argmem: readwrite) } +; CHECK: attributes #[[ATTR2]] = { nounwind memory(readwrite) } +; CHECK: attributes #[[ATTR3:[0-9]+]] = { nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) } +; CHECK: attributes #[[ATTR4]] = { nounwind } +;. Index: llvm/test/Transforms/SCCP/remove-call-inst.ll =================================================================== --- llvm/test/Transforms/SCCP/remove-call-inst.ll +++ llvm/test/Transforms/SCCP/remove-call-inst.ll @@ -36,4 +36,4 @@ } ; CHECK: attributes #0 = { noreturn nounwind } -; CHECK: attributes #1 = { nounwind readnone willreturn } +; CHECK: attributes #1 = { nounwind willreturn memory(none) } Index: llvm/test/Transforms/SampleProfile/pseudo-probe-emit.ll =================================================================== --- llvm/test/Transforms/SampleProfile/pseudo-probe-emit.ll +++ llvm/test/Transforms/SampleProfile/pseudo-probe-emit.ll @@ -64,7 +64,7 @@ ret void } -; CHECK-IL: Function Attrs: inaccessiblememonly nocallback nofree nosync nounwind willreturn +; CHECK-IL: Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) ; CHECK-IL-NEXT: declare void @llvm.pseudoprobe(i64, i64, i32, i64) ; CHECK-IL: ![[#FOO:]] = distinct !DISubprogram(name: "foo" Index: llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad-debuginfo.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad-debuginfo.ll +++ llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad-debuginfo.ll @@ -68,7 +68,7 @@ declare dso_local i32 @__gxx_personality_v0(...) ;. ; CHECK: attributes #[[ATTR0:[0-9]+]] = { noreturn } -; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ;. ; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) ; CHECK: [[META1:![0-9]+]] = !DIFile(filename: "", directory: "/") Index: llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll +++ llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll @@ -2475,5 +2475,5 @@ ;. ; CHECK: attributes #[[ATTR0:[0-9]+]] = { noreturn } ; CHECK: attributes #[[ATTR1]] = { nomerge } -; CHECK: attributes #[[ATTR2]] = { readnone } +; CHECK: attributes #[[ATTR2]] = { memory(none) } ;. Index: llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll +++ llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll @@ -1133,7 +1133,7 @@ ;. ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind uwtable } ; CHECK: attributes #[[ATTR1]] = { nounwind } -; CHECK: attributes #[[ATTR2:[0-9]+]] = { noredzone nounwind readnone ssp } +; CHECK: attributes #[[ATTR2:[0-9]+]] = { noredzone nounwind ssp memory(none) } ;. ; CHECK: [[PROF0]] = !{!"branch_weights", i32 5, i32 11} ; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 3} Index: llvm/test/Verifier/fp-intrinsics.ll =================================================================== --- llvm/test/Verifier/fp-intrinsics.ll +++ llvm/test/Verifier/fp-intrinsics.ll @@ -12,7 +12,7 @@ ; attached to the FP intrinsic. ; CHECK1: declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata) #[[ATTR:[0-9]+]] ; CHECK1: declare double @llvm.experimental.constrained.sqrt.f64(double, metadata, metadata) #[[ATTR]] -; CHECK1: attributes #[[ATTR]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } +; CHECK1: attributes #[[ATTR]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } ; Note: FP exceptions aren't usually caught through normal unwind mechanisms, ; but we may want to revisit this for asynchronous exception handling. define double @f1(double %a, double %b) #0 { Index: llvm/test/Verifier/writeonly.ll =================================================================== --- llvm/test/Verifier/writeonly.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s - -declare void @a() readnone writeonly -; CHECK: Attributes {{.*}} are incompatible - -declare void @b() readonly writeonly -; CHECK: Attributes {{.*}} are incompatible - -declare void @c(i32* readnone writeonly %p) -; CHECK: Attributes {{.*}} are incompatible - -declare void @d(i32* readonly writeonly %p) -; CHECK: Attributes {{.*}} are incompatible Index: llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.funcattrs.expected =================================================================== --- llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.funcattrs.expected +++ llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_attrs.ll.funcattrs.expected @@ -6,7 +6,7 @@ %struct.ST = type { i32, double, %struct.RT } define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp { -; CHECK: Function Attrs: nofree norecurse nosync nounwind optsize readnone ssp willreturn uwtable +; CHECK: Function Attrs: nofree norecurse nosync nounwind optsize ssp willreturn memory(none) uwtable ; CHECK-LABEL: define {{[^@]+}}@foo ; CHECK-SAME: (%struct.ST* nofree readnone [[S:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: Index: llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.globals.expected =================================================================== --- llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.globals.expected +++ llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values.ll.funcsig.globals.expected @@ -249,8 +249,8 @@ !61 = !{!"branch_weights", i32 1, i32 1048575} ;. ; CHECK: attributes #[[ATTR0]] = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } -; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } -; CHECK: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; CHECK: attributes #[[ATTR3]] = { nounwind } ;. ; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) Index: llvm/test/tools/llvm-reduce/remove-attributes-from-intrinsics.ll =================================================================== --- llvm/test/tools/llvm-reduce/remove-attributes-from-intrinsics.ll +++ llvm/test/tools/llvm-reduce/remove-attributes-from-intrinsics.ll @@ -26,7 +26,7 @@ ; CHECK-ALL: declare i32 @llvm.uadd.sat.i32(i32, i32) #0 declare i32 @llvm.uadd.sat.i32(i32, i32) #0 -; CHECK-ALL: attributes #0 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; CHECK-ALL: attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } ; CHECK-INTERESTINGNESS: attributes #1 = { ; CHECK-INTERESTINGNESS-SAME: "arg4" Index: llvm/unittests/IR/InstructionsTest.cpp =================================================================== --- llvm/unittests/IR/InstructionsTest.cpp +++ llvm/unittests/IR/InstructionsTest.cpp @@ -731,11 +731,11 @@ // Test cloning an attribute. { AttrBuilder AB(C); - AB.addAttribute(Attribute::ReadOnly); + AB.addAttribute(Attribute::NoUnwind); Call->setAttributes( AttributeList::get(C, AttributeList::FunctionIndex, AB)); std::unique_ptr Clone(cast(Call->clone())); - EXPECT_TRUE(Clone->onlyReadsMemory()); + EXPECT_TRUE(Clone->doesNotThrow()); } } Index: llvm/utils/TableGen/IntrinsicEmitter.cpp =================================================================== --- llvm/utils/TableGen/IntrinsicEmitter.cpp +++ llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -776,49 +776,53 @@ case CodeGenIntrinsic::NoMem: if (Intrinsic.hasSideEffects) break; - OS << " Attribute::get(C, Attribute::ReadNone),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::none()),\n"; break; case CodeGenIntrinsic::ReadArgMem: - OS << " Attribute::get(C, Attribute::ReadOnly),\n"; - OS << " Attribute::get(C, Attribute::ArgMemOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::argMemOnly(ModRefInfo::Ref)),\n"; break; case CodeGenIntrinsic::ReadMem: - OS << " Attribute::get(C, Attribute::ReadOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::readOnly()),\n"; break; case CodeGenIntrinsic::ReadInaccessibleMem: - OS << " Attribute::get(C, Attribute::ReadOnly),\n"; - OS << " Attribute::get(C, Attribute::InaccessibleMemOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::inaccessibleMemOnly(ModRefInfo::Ref)),\n"; break; case CodeGenIntrinsic::ReadInaccessibleMemOrArgMem: - OS << " Attribute::get(C, Attribute::ReadOnly),\n"; - OS << " Attribute::get(C, " - << "Attribute::InaccessibleMemOrArgMemOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::inaccessibleOrArgMemOnly(ModRefInfo::Ref)),\n"; + break; break; case CodeGenIntrinsic::WriteArgMem: - OS << " Attribute::get(C, Attribute::WriteOnly),\n"; - OS << " Attribute::get(C, Attribute::ArgMemOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::argMemOnly(ModRefInfo::Mod)),\n"; break; case CodeGenIntrinsic::WriteMem: - OS << " Attribute::get(C, Attribute::WriteOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::writeOnly()),\n"; break; case CodeGenIntrinsic::WriteInaccessibleMem: - OS << " Attribute::get(C, Attribute::WriteOnly),\n"; - OS << " Attribute::get(C, Attribute::InaccessibleMemOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::inaccessibleMemOnly(ModRefInfo::Mod)),\n"; break; case CodeGenIntrinsic::WriteInaccessibleMemOrArgMem: - OS << " Attribute::get(C, Attribute::WriteOnly),\n"; - OS << " Attribute::get(C, " - << "Attribute::InaccessibleMemOrArgMemOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::inaccessibleOrArgMemOnly(ModRefInfo::Mod)),\n"; break; case CodeGenIntrinsic::ReadWriteArgMem: - OS << " Attribute::get(C, Attribute::ArgMemOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::argMemOnly(ModRefInfo::ModRef)),\n"; break; case CodeGenIntrinsic::ReadWriteInaccessibleMem: - OS << " Attribute::get(C, Attribute::InaccessibleMemOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef)),\n"; break; case CodeGenIntrinsic::ReadWriteInaccessibleMemOrArgMem: - OS << " Attribute::get(C, " - << "Attribute::InaccessibleMemOrArgMemOnly),\n"; + OS << " Attribute::getWithMemoryEffects(C, " + << "MemoryEffects::inaccessibleOrArgMemOnly(ModRefInfo::ModRef)),\n"; break; case CodeGenIntrinsic::ReadWriteMem: break; Index: llvm/utils/UpdateTestChecks/common.py =================================================================== --- llvm/utils/UpdateTestChecks/common.py +++ llvm/utils/UpdateTestChecks/common.py @@ -327,7 +327,7 @@ UNUSED_NOTE = 'NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:' OPT_FUNCTION_RE = re.compile( - r'^(\s*;\s*Function\sAttrs:\s(?P[\w\s]+?))?\s*define\s+(?:internal\s+)?[^@]*@(?P[\w.$-]+?)\s*' + r'^(\s*;\s*Function\sAttrs:\s(?P[\w\s():,]+?))?\s*define\s+(?:internal\s+)?[^@]*@(?P[\w.$-]+?)\s*' r'(?P\((\)|(.*?[\w.-]+?)\))[^{]*\{)\n(?P.*?)^\}$', flags=(re.M | re.S)) Index: mlir/test/Target/LLVMIR/llvmir.mlir =================================================================== --- mlir/test/Target/LLVMIR/llvmir.mlir +++ mlir/test/Target/LLVMIR/llvmir.mlir @@ -1948,5 +1948,5 @@ // Function attributes: readnone // CHECK: declare void @readnone_function() #[[ATTR:[0-9]+]] -// CHECK: attributes #[[ATTR]] = { readnone } +// CHECK: attributes #[[ATTR]] = { memory(none) } llvm.func @readnone_function() attributes {llvm.readnone}