// 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...
// 'const', 'pure' and 'noalias' attributed functions are also nounwind.
if (TargetDecl->hasAttr<ConstAttr>()) {
- 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<PureAttr>()) {
- 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<NoAliasAttr>()) {
- FuncAttrs.addAttribute(llvm::Attribute::ArgMemOnly);
+ FuncAttrs.addMemoryAttr(llvm::MemoryEffects::argMemOnly());
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
}
if (TargetDecl->hasAttr<RestrictAttr>())
case ABIArgInfo::InAlloca:
case ABIArgInfo::Indirect: {
// inalloca and sret disable readnone and readonly
- FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
- .removeAttribute(llvm::Attribute::ReadNone);
+ AddPotentialArgAccess();
break;
}
Attrs.addAlignmentAttr(Align.getQuantity());
// byval disables readnone and readonly.
- FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
- .removeAttribute(llvm::Attribute::ReadNone);
-
+ AddPotentialArgAccess();
break;
}
case ABIArgInfo::IndirectAliased: {
case ABIArgInfo::InAlloca:
// inalloca disables readnone and readonly.
- FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
- .removeAttribute(llvm::Attribute::ReadNone);
+ AddPotentialArgAccess();
continue;
}
// 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<llvm::Function>(F.getCallee())->setLinkage(
llvm::Function::ExternalWeakLinkage);
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);
// 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;
}
// 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) }
// 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 {{.*}} }
// 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 {{.*}} }
// 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 }
// 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){{.*}} }
}
// 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) }
// 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){{.*}} }
// 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){{.*}} }
// 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){{.*}} }
int correct_linkage;
// CHECK: attributes [[NI]] = { noinline nounwind{{.*}} }
-// CHECK: attributes [[RN]] = { noinline nounwind optnone readnone{{.*}} }
+// CHECK: attributes [[RN]] = { noinline nounwind optnone willreturn memory(none){{.*}} }
// 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){{.*}} }
// 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) }
// 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 }
// 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) }
@end
// -- calls to objc_loadClassRef() are readnone
-// CHECK: attributes [[ATTRLIST]] = { nounwind nonlazybind readnone }
+// CHECK: attributes [[ATTRLIST]] = { nounwind nonlazybind memory(none) }
// 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"}
}
// CHECK: attributes [[ATTR_CONST]] =
-// CHECK-SAME: readnone
+// CHECK-SAME: memory(none)
// CHECK: attributes [[ATTR_PURE]] =
-// CHECK-SAME: readonly
+// CHECK-SAME: memory(read)
// 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]](
//.
// 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}
// 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) }
// 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) }
same address may be returned), for a free-like function the
pointer will always be invalidated.
+``readnone``
+ This attribute indicates that the function does not dereference that
+ pointer argument, even though it may read or write the memory that the
+ pointer points to if accessed through other pointers.
+
+ If a function reads from or writes to a readnone pointer argument, the
+ behavior is undefined.
+
+``readonly``
+ This attribute indicates that the function does not write through this
+ pointer argument, even though it may write to the memory that the pointer
+ points to.
+
+ If a function writes to a readonly pointer argument, the behavior is
+ undefined.
+
+``writeonly``
+ This attribute indicates that the function may write to, but does not read
+ through this pointer argument (even though it may read from the memory that
+ the pointer points to).
+
+ If a function reads from a writeonly pointer argument, the behavior is
+ undefined.
+
.. _gc:
Garbage Collector Strategy Names
the profile information. By marking a function ``hot``, users can work
around the cases where the training input does not have good coverage
on all the hot functions.
-``inaccessiblememonly``
- This attribute indicates that the function may only access memory that
- is not accessible by the module being compiled before return from the
- function. This is a weaker form of ``readnone``. If the function reads
- or writes other memory, the behavior is undefined.
-
- For clarity, note that such functions are allowed to return new memory
- which is ``noalias`` with respect to memory already accessible from
- the module. That is, a function can be both ``inaccessiblememonly`` and
- have a ``noalias`` return which introduces a new, potentially initialized,
- allocation.
-``inaccessiblemem_or_argmemonly``
- This attribute indicates that the function may only access memory that is
- either not accessible by the module being compiled, or is pointed to
- by its pointer arguments. This is a weaker form of ``argmemonly``. If the
- function reads or writes other memory, the behavior is undefined.
``inlinehint``
This attribute indicates that the source code contained a hint that
inlining this function is desirable (such as the "inline" keyword in
function that has a ``"probe-stack"`` attribute is inlined into a
function that has no ``"probe-stack"`` attribute at all, the resulting
function has the ``"probe-stack"`` attribute of the callee.
-``readnone``
- On a function, this attribute indicates that the function computes its
- result (or decides to unwind an exception) based strictly on its arguments,
- without dereferencing any pointer arguments or otherwise accessing
- any mutable state (e.g. memory, control registers, etc) visible outside the
- ``readnone`` function. It does not write through any pointer arguments
- (including ``byval`` arguments) and never changes any state visible to
- callers. This means while it cannot unwind exceptions by calling the ``C++``
- exception throwing methods (since they write to memory), there may be
- non-``C++`` mechanisms that throw exceptions without writing to LLVM visible
- memory.
-
- On an argument, this attribute indicates that the function does not
- dereference that pointer argument, even though it may read or write the
- memory that the pointer points to if accessed through other pointers.
-
- If a readnone function reads or writes memory visible outside the function,
- or has other side-effects, the behavior is undefined. If a
- function reads from or writes to a readnone pointer argument, the behavior
- is undefined.
-``readonly``
- On a function, this attribute indicates that the function does not write
- through any pointer arguments (including ``byval`` arguments) or otherwise
- modify any state (e.g. memory, control registers, etc) visible outside the
- ``readonly`` function. It may dereference pointer arguments and read
- state that may be set in the caller. A readonly function always
- returns the same value (or unwinds an exception identically) when
- called with the same set of arguments and global state. This means while it
- cannot unwind exceptions by calling the ``C++`` exception throwing methods
- (since they write to memory), there may be non-``C++`` mechanisms that throw
- exceptions without writing to LLVM visible memory.
-
- On an argument, this attribute indicates that the function does not write
- through this pointer argument, even though it may write to the memory that
- the pointer points to.
-
- If a readonly function writes memory visible outside the function, or has
- other side-effects, the behavior is undefined. If a function writes to a
- readonly pointer argument, the behavior is undefined.
``"stack-probe-size"``
This attribute controls the behavior of stack probes: either
the ``"probe-stack"`` attribute, or ABI-required stack probes, if any.
of the callee.
``"no-stack-arg-probe"``
This attribute disables ABI-required stack probes, if any.
-``writeonly``
- On a function, this attribute indicates that the function may write to but
- does not read from memory visible outside the ``writeonly`` function.
-
- On an argument, this attribute indicates that the function may write to but
- does not read through this pointer argument (even though it may read from
- the memory that the pointer points to).
-
- If a writeonly function reads memory visible outside the function or has
- other side-effects, the behavior is undefined. If a function reads
- from a writeonly pointer argument, the behavior is undefined.
-``argmemonly``
- This attribute indicates that the only memory accesses inside function are
- loads and stores from objects pointed to by its pointer-typed arguments,
- with arbitrary offsets. Or in other words, all memory operations in the
- function can refer to memory only using pointers based on its function
- arguments.
-
- Note that ``argmemonly`` can be used together with ``readonly`` attribute
- in order to specify that function reads only from its arguments.
-
- If an argmemonly function reads or writes memory other than the pointer
- arguments, or has other side-effects, the behavior is undefined.
``returns_twice``
This attribute indicates that this function can return twice. The C
``setjmp`` is an example of such a function. The compiler disables
Changes to the LLVM IR
----------------------
+* The ``readnone``, ``readonly``, ``writeonly``, ``argmemonly``,
+ ``inaccessiblememonly`` and ``inaccessiblemem_or_argmemonly`` function
+ attributes have been replaced by a single ``memory(...)`` attribute. The
+ old attributes may be mapped to the new one as follows:
+
+ * ``readnone`` -> ``memory(none)``
+ * ``readonly`` -> ``memory(read)``
+ * ``writeonly`` -> ``memory(write)``
+ * ``argmemonly`` -> ``memory(argmem: readwrite)``
+ * ``argmemonly readonly`` -> ``memory(argmem: read)``
+ * ``argmemonly writeonly`` -> ``memory(argmem: write)``
+ * ``inaccessiblememonly`` -> ``memory(inaccessiblemem: readwrite)``
+ * ``inaccessiblememonly readonly`` -> ``memory(inaccessiblemem: read)``
+ * ``inaccessiblememonly writeonly`` -> ``memory(inaccessiblemem: write)``
+ * ``inaccessiblemem_or_argmemonly`` ->
+ ``memory(argmem: readwrite, inaccessiblemem: readwrite)``
+ * ``inaccessiblemem_or_argmemonly readonly`` ->
+ ``memory(argmem: read, inaccessiblemem: read)``
+ * ``inaccessiblemem_or_argmemonly writeonly`` ->
+ ``memory(argmem: write, inaccessiblemem: write)``
+
* The constant expression variants of the following instructions has been
removed:
kw_argmem,
kw_inaccessiblemem,
+ // Legacy memory attributes:
+ kw_argmemonly,
+ kw_inaccessiblememonly,
+ kw_inaccessiblemem_or_argmemonly,
+
kw_type,
kw_opaque,
#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<Attribute>({__VA_ARGS__}))
#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
? 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
: 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,
/// 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]>;
/// 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]>;
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]>;
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]>;
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 {
/// 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); }
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 {
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 <typename AK> 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 <typename AttrKind> bool hasRetAttrImpl(AttrKind Kind) const {
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<Function>(Call->getCalledOperand())) {
MemoryEffects FuncME = AAQI.AAR.getMemoryEffects(F);
MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef);
}
- return getMemoryEffectsFromAttrs(F->getAttributes().getFnAttrs());
+ return F->getMemoryEffects();
}
ModRefInfo BasicAAResult::getArgModRefInfo(const CallBase *Call,
KEYWORD(readwrite);
KEYWORD(argmem);
KEYWORD(inaccessiblemem);
+ KEYWORD(argmemonly);
+ KEYWORD(inaccessiblememonly);
+ KEYWORD(inaccessiblemem_or_argmemonly);
KEYWORD(type);
KEYWORD(opaque);
}
}
+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
/// ::= <attr> | <attr> '=' <value>
bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
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))
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");
}
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;
}
//===----------------------------------------------------------------------===//
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;
/// 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;
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() {
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));
}
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:
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:
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;
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
}
}
+ if (ME != MemoryEffects::unknown())
+ B.addMemoryAttr(ME);
+
UpgradeAttributes(B);
MAttributeGroups[GrpID] = AttributeList::get(Context, Idx, B);
break;
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:
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:
#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"
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<Intrinsic::ID>(IntrID));
- bool DeclHasSideEffects = !Attrs.hasFnAttr(Attribute::ReadNone);
+ AttributeList Attrs = Intrinsic::getAttributes(
+ MF->getFunction().getContext(), static_cast<Intrinsic::ID>(IntrID));
+ bool DeclHasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory();
if (NoSideEffects && DeclHasSideEffects) {
report("G_INTRINSIC used with intrinsic that accesses memory", MI);
break;
#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"
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",
#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"
template <typename AK>
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<AK, Attribute::AttrKind>) {
+ // 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<ConstantExpr>(V))
if (CE->getOpcode() == BitCast)
getIntrinsicID() != Intrinsic::assume;
}
+MemoryEffects CallBase::getMemoryEffects() const {
+ MemoryEffects ME = getAttributes().getMemoryEffects();
+ if (auto *Fn = dyn_cast<Function>(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
//===----------------------------------------------------------------------===//
"' 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);
#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"
} 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);
}
#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"
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<SIMachineFunctionInfo>();
}
Info.flags |= MachineMemOperand::MODereferenceable;
- if (Attr.hasFnAttr(Attribute::ReadOnly)) {
+ if (ME.onlyReadsMemory()) {
unsigned DMaskLanes = 4;
if (RsrcIntr->IsImage) {
// 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();
#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"
// 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);
/// 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<Function>(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()
return clampStateAndIndicateChange(getState(), FnAA.getState());
}
+ /// See AbstractAttribute::manifest(...).
+ ChangeStatus manifest(Attributor &A) override {
+ // TODO: Deduplicate this with AAMemoryBehaviorFunction.
+ CallBase &CB = cast<CallBase>(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())
// 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<Attribute, 2> 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;
}
}
}
/// See AbstractAttribute::getDeducedAttributes(...).
void getDeducedAttributes(LLVMContext &Ctx,
SmallVectorImpl<Attribute> &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<Attribute, 4> DeducedAttrs;
+ SmallVector<Attribute, 1> 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<Attribute, 1> 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(...).
/// 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) {
#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");
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);
- }
}
}
// 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);
}
}
}
- ReadOnlyNoneAttrs.addAttribute(Attribute::ReadOnly)
- .addAttribute(Attribute::ReadNone);
+ // TODO: This could be more precise.
+ 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.
// 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()) {
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();
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);
// 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.
}
}
- // 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<CallBase>(U);
if (!CB || CB->getCalledFunction() != &F)
continue;
- CB->removeFnAttrs(AttributesToRemove);
+ CB->setAttributes(UpdateAttrs(CB->getAttributes()));
}
}
MadeChanges |= ReplacedPointerArg;
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;
// 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:
case Attribute::NoUndef:
case Attribute::NonNull:
case Attribute::Preallocated:
+ case Attribute::ReadNone:
+ case Attribute::ReadOnly:
case Attribute::Returned:
case Attribute::SExt:
case Attribute::StructRet:
case Attribute::ZExt:
case Attribute::ImmArg:
case Attribute::ByRef:
+ case Attribute::WriteOnly:
// These are not really attributes.
case Attribute::None:
case Attribute::EndAttrKinds:
}
-; 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 }
declare <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8*, i32) nounwind readonly
declare void @llvm.arm.neon.vst1.p0i8.v8i16(i8*, <8 x i16>, i32) nounwind
-; CHECK: attributes #0 = { argmemonly nocallback nofree nosync nounwind readonly willreturn }
-; CHECK: attributes #1 = { argmemonly nocallback nofree nosync nounwind willreturn }
+; CHECK: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) }
+; CHECK: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
; CHECK: attributes [[ATTR]] = { nounwind }
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 }
declare i32 @TestNone(i32)
-; CHECK: attributes [[READNONE]] = { readnone }
-; CHECK: attributes [[READONLY]] = { readonly }
+; CHECK: attributes [[READNONE]] = { memory(none) }
+; CHECK: attributes [[READONLY]] = { memory(read) }
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 = !{ }
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"}
declare <vscale x 4 x i32> @llvm.aarch64.sve.dup.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i1>, 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) }
; 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) }
; 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}
; 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 }
; 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 }
; 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 }
; 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 }
; 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
; 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 }
; 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
; 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 }
; 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
; 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 }
; 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
; 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 }
; 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
; 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 }
; 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
; 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 }
; 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
; 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 }
; 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 }
declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) nounwind readnone
; CHECK: attributes #0 = { nounwind }
-; CHECK: attributes #1 = { nocallback nofree nosync nounwind readnone willreturn }
+; CHECK: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) }
declare i32 @llvm.x86.sse41.ptestnzc(<4 x float>, <4 x float>) nounwind readnone
; CHECK: attributes #0 = { nounwind }
-; CHECK: attributes #1 = { nocallback nofree nosync nounwind readnone willreturn }
+; CHECK: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) }
;; 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" }
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*)
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" }
;.
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 }
; 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" }
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" }
; 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" }
; 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:
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) }
;.
; 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 }
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" }
;.
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 }
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 }
; 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*)
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
; 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
; RUN: opt -aa-pipeline=basic-aa -passes='default<O2>' -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()
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 ()*
; 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:
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 ()*
ret void
}
-; CHECK: attributes #0 = { nofree nosync readnone }
+; CHECK: attributes #0 = { nofree nosync memory(none) }
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*)
; 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:
; 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 {
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}}
; 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:
}
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:
; 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:
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 }
;.
; 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:
}
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]+]]
}
;.
-; 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 }
;.
; 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:
}
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:
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) }
;.
; 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:
}
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:
ret i32 0
}
;.
-; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
+; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) }
;.
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:
}
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:
; 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:
}
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:
}
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:
; 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:
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 }
;.
; 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:
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:
; 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:
; 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:
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:
; 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:
; 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:
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:
; 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:
; 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:
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:
; 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:
; 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:
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:
; 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:
; 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:
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:
; 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:
; 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:
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:
; 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:
; 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:
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:
; 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:
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 }
;.
; 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:
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:
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 }
;.
; 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
}
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
}
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]+]]
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 }
;.
; 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:
; 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:
; 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:
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 }
;.
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
}
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
}
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]+]]
}
;.
-; 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 }
;.
%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:
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:
; 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:
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 }
;.
%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:
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:
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:
; 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:
;.
-; 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 }
;.
;.
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:
}
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:
}
;.
-; 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 }
;.
; 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:
}
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:
}
;.
-; 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 }
;.
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
}
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]+]]
}
;.
-; 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 }
;.
; 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:
; 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:
}
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:
}
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:
}
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:
}
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:
}
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:
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 }
;.
;.
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:
}
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:
}
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
}
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
}
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:
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) }
;.
; 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:
}
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:
; 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:
; 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:
}
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:
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 }
;.
}
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:
}
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:
ret i32 %result
}
;.
-; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
+; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) }
;.
}
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:%.*]]
}
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
}
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
}
;.
-; 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 }
;.
}
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:%.*]]
}
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
}
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
}
;.
-; 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 }
;.
%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
}
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]+]]
; 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
}
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
; 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
}
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]]
; 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
}
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
; 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
; 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
}
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 }
;.
%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
}
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]+]]
!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: "")
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
}
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
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 }
;.
}
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:
; 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
}
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:
; 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
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) }
;.
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:
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:
; 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:
}
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:
}
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:
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 }
;.
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:
; 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:
}
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:
}
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:
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 }
;.
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:
}
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:
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) }
;.
; 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]])
}
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
; 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]])
}
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]]
; 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]+]]
}
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
}
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
;.
; 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 }
;.
; 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)
}
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]]
;.
; 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) }
;.
; 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
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) }
;.
; 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:
}
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:
}
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:
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) }
;.
}
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
ret void
}
;.
-; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
+; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) }
;.
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:
}
;.
-; CHECK: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone }
+; CHECK: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind memory(none) }
;.
; 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:
}
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:
ret i32 %tmp
}
;.
-; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
+; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) }
;.
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:
}
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:
}
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:
}
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:
}
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:
!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}
}
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
ret i8* null
}
;.
-; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
+; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) }
;.
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:
}
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:
}
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:
}
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:
!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}
; 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
}
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
}
;.
-; 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) }
;.
; 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:
}
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:
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 }
;.
;; 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:%.*]]
; 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
;; 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]]
}
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
; 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
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 }
;.
; 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]+]]
; 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]+]]
}
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:%.*]]
; 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:%.*]]
}
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]+]]
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 }
;.
%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:%.*]]
}
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
}
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]+]]
; 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]]
; 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]]
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 }
;.
; 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:
}
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:
}
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]]
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 }
;.
; 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:
!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}
; 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]]
; 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]]
; 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]]
; 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]]
; 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
}
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
; 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:%.*]]
; 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:%.*]]
; 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]+]]
; 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:%.*]]
; 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:%.*]]
}
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]]
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*
; 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*
; 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*
}
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*
; 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*
; 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*
; 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*
}
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*
; 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*
}
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:%.*]]
; 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:%.*]]
}
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:%.*]]
; 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:%.*]]
}
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:%.*]]
; 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:%.*]]
}
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:%.*]]
; 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:%.*]]
; 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
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*
; 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
}
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*
; 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
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
@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
; 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
}
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]]
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 }
;.
; 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
; 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
;.
; 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 }
;.
; 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:
}
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:
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 }
;.
;
define internal i8 @read_arg(i8* %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 {{[^@]+}}@read_arg
; CGSCC-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1022) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
; CGSCC-NEXT: entry:
}
define internal i8 @read_arg_index(i8* %p, i64 %index) {
-; TUNIT: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read)
; TUNIT-LABEL: define {{[^@]+}}@read_arg_index
; TUNIT-SAME: (i8* nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 2
; TUNIT-NEXT: ret i8 [[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 {{[^@]+}}@read_arg_index
; CGSCC-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1022) [[P:%.*]]) #[[ATTR0]] {
; CGSCC-NEXT: entry:
}
define i8 @call_simplifiable_1() {
-; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@call_simplifiable_1
; TUNIT-SAME: () #[[ATTR1:[0-9]+]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[I0:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 2
; TUNIT-NEXT: ret i8 2
;
-; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn
+; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@call_simplifiable_1
; CGSCC-SAME: () #[[ATTR1:[0-9]+]] {
; CGSCC-NEXT: entry:
}
define i8 @call_not_simplifiable_1() {
-; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@call_not_simplifiable_1
; TUNIT-SAME: () #[[ATTR1]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[R:%.*]] = call i8 @read_arg_index(i8* nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I0]]) #[[ATTR2:[0-9]+]]
; 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 {{[^@]+}}@call_not_simplifiable_1
; CGSCC-SAME: () #[[ATTR1]] {
; CGSCC-NEXT: entry:
}
;.
-; 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]] = { 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 }
;.
; 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 }
;.
; 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 }
;.
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 }
;.
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 }
;.
; }
;
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
; 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 }
;.
; 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*
; 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*
; 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
}
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
}
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
; 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]]
; 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
}
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
; 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:%.*]]
; 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
; 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:
; 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:
}
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:
; 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:
;
; 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:
; }
; 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
; 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()
; 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()
!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}
;.
; 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
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
}
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
}
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
; 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
; 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
; 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:
; 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:
; 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:
; 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
; 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
; 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
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
; 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
; 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
; 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
; 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
; 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
; 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
}
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
}
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
}
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
}
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*
}
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*
}
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*
}
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
;
; 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
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) }
;.
; 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
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
}
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
}
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
; 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
; 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
; 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:
; 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:
; 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:
; 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
; 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
; 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
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
; 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
; 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
; 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
; 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
; 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
; 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
}
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
}
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
}
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
}
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*
}
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*
}
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*
}
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
;
; 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
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) }
;.
; 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 }
;.
; 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 }
;.
; 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:
; 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]]
;
}
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:
; 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]]
;
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:
; 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:
}
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:
; 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]]
}
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
}
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]+]]
}
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
}
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
; 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
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 }
;.
; 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
;.
; 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 }
;.
; 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:%.*]]
}
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
}
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
; 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
; 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
}
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:
; 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:
; 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]]
}
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:
}
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:
}
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]+]]
; 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:
@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
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
@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:
; 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
; 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:
}
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:
; 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:
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 }
;.
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
}
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]]
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 }
;.
; 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 }
;.
; 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:
}
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:
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 }
;.
; 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:
ret i32 %retval
}
;.
-; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
+; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) }
;.
; 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:
}
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:
}
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:
}
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:
}
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:
}
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:
}
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:
}
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:
}
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:
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]])
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]])
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
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
}
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
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
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
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
}
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]+]]
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]]
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]]
}
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
; 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
}
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
; 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
}
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
}
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
; 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
}
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]]
}
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
; 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
}
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
}
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
}
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]]
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 }
;.
; 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]])
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:
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 }
;.
; 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:
}
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)
}
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
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]]
; 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 }
;.
}
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
; 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
; 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]+]]
; 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
}
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)
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
; 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)
@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
}
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
}
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
; 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
}
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)
; }
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
; }
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
}
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:
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) }
;.
; 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]]
; 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
}
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)
}
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
; 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
@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
; 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
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
; 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
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
}
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]]
;
; 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) ; <i32> [#uses=0]
; 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)
; 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
;
}
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:
}
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
;
}
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
;
}
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
;
}
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:
}
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
}
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
}
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
}
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:
; 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:
; 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
;
; 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
;
}
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
;
@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
;
}
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
}
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]]
}
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
}
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
}
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*
}
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*
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]]
}
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:
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 }
;.
;
; 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:
;
; 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:
; }
;
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:
; 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:
; 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
; 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
}
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*
;
; 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:
;
; 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:
; }
;
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:
;
; 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:
;
; 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
;
; 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:
;
; 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
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:
; 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:
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:
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:
}
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:
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)
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 }
;.
%"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:
}
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:
}
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:
}
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:
}
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:
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 }
;.
; 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
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
}
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
; 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
; 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
}
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]+]]
; 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
}
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
;
; 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
;
; 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 }
;.
; 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]]
}
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:%.*]]
}
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:%.*]]
; 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
}
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
; 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:%.*]]
; 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:%.*]]
}
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
}
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]]
}
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
}
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]]
; 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
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:
; 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:
}
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:
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:
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]]
;
}
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
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
}
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
; 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]]
; 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*)
}
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()
; 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]]
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*)
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*)
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 }
;.
; 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
}
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
}
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
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
}
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()
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]+]]
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()
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()
}
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()
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()
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()
}
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:
; 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:
}
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:
; 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
}
;.
-; 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 }
;.
; }
;
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:
; }
;
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:
; }
;
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:
;
; 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:
; }
;
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:
; 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:
; 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:
; 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:
; 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:
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) }
;.
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 }
;.
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 }
;.
; 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:
; }
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
; }
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
; }
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
; }
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
; 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
; }
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
; }
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
; 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]+]]
}
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]+]]
; 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]+]]
; 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)
; 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()
; 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
}
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 }
;.
; 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
; 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
; 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
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) }
;.
; 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]])
; 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]])
;.
; 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}
%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:
; 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:
}
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
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 }
;.
; 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
}
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
; 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
}
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]+]]
; 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]]
}
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]+]]
; 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]]
; 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
}
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
}
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]]
; 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]]
; 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]]
}
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]]
; 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]]
}
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]]
}
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]]
; 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]]
}
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
}
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
}
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
; 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
}
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]]
}
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]]
}
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:
; 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:%.*]] [
}
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]]
}
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:%.*]]
}
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:%.*]]
}
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:%.*]]
; 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]]
; 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]]
}
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:%.*]]
; 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]]
; 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
}
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]]
}
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]]
}
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]]
}
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
}
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
}
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
}
;.
-; 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}
; 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]+]]
}
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]+]]
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]+]]
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]]
; }
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:
}
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:
; 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:
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:%.*]]
; 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:%.*]]
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:
;
; 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:
; }
; }
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:
; 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:
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]
; }
; }
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:
; 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:
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:
; 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:
; 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:
}
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:
; 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:
}
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:
; 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:
}
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:
; 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:
; }
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]]
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]]
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]]
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]]
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]]
}
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
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
; 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]]
;
; 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]]
;
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]]
;
}
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
}
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
; 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
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
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
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
; 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
; 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]] ]
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
}
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
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
}
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
}
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]]
;
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
}
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
}
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)
}
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:%.*]] [
}
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
}
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)
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:%.*]] [
; 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:%.*]] [
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
}
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]]
;
}
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
; 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
}
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:
; 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:
!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}
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:
; 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:
}
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:
; 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:
; 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:
}
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:
; 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:
; 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:
}
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:
}
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:
; 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:
; 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:
}
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:
; 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]]
;
; 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 }
;.
}
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
}
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]]
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)
; 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
; 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
}
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:
}
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:
; 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 <i1 true, i1 false, i1 true, i1 false>) #[[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 <i1 true, i1 false, i1 true, i1 false>) #[[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 <i1 true, i1 false, i1 true, i1 false>) #[[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><i1 true, i1 false, i1 true, i1 false>)
; 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 <i1 true, i1 false, i1 true, i1 false>, <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 <i1 true, i1 false, i1 true, i1 false>, <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 <i1 true, i1 false, i1 true, i1 false>, <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 <i1 true, i1 false, i1 true, i1 false>, <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><i1 true, i1 false, i1 true, i1 false>, <4 x i32>undef)
; 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)
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)
}
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
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]])
}
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
}
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]])
}
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
}
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
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)
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)
@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
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 }
;.
; 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:
}
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:
}
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:
; 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:
}
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:
; 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:
; 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:
}
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:
}
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:
; 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:
; }
;
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:
; }
;
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:
; 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:
}
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:
; 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:
; 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:
}
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:
; 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:
; 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)
; 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:
; 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:
; }
;
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:
; }
;
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:
; 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:
; }
;
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:
; }
;
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:
; }
;
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:
; }
;
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:
; }
;
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:
; 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:
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:
}
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:
}
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:
@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*)
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()
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 }
;.
; -- 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
}
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
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:%.*]]
; 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
}
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
}
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
; -- 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
}
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
}
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:%.*]]
}
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
; 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]+]]
; -- 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
}
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:%.*]]
; 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:%.*]]
; 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
; -- 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
}
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:%.*]]
; 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:%.*]]
; 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
; 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
; 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
; 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:%.*]]
}
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
}
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
; 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]]
}
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:%.*]]
; 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
; 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]]
; 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
; 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
; 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
; 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:
}
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]]
; 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
}
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
}
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
; 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
}
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
; 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
; 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
}
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
; 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
}
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
; 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
; 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
}
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
; 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
; 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:%.*]] [
}
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:%.*]] [
}
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:%.*]] [
}
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
}
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]]
}
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
}
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]]
}
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
}
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:%.*]]
}
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]]
}
;.
-; 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 }
;.
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
}
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]+]]
}
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
; 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
}
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
; 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
}
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
; 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
}
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
; 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
}
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
; 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
}
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
; 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
; 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
}
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
; 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
; 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
}
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
; 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
; 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
}
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
; 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
; 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
}
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]]
}
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
; 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
}
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
; 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
}
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
; 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
}
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
; 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
}
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
; 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
}
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
; 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
; 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
}
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
; 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
; 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
}
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
; 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
; 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
}
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
; 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
; 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
}
;.
-; 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 }
;.
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:
!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)
; 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
; 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:
}
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:
; 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
; 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
}
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:
; 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
; 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:
}
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:
; 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
; 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
}
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:
;.
; 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 }
;.
; 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]]
; 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
; 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]+]]
; 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
; 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
; 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
}
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)
; 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)
; 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)
; 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 }
;.
%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:
; 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:
}
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:
; 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:
}
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:
}
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:
; 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]]
;
}
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]]
;
}
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:
}
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:
}
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:
; 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]]
;
}
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:
; 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]]
;
}
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:
; 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:
}
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:
; 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:
; 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:
; 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:
}
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
;
}
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]]
;
}
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:
}
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:
; 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:
!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}
; 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:
}
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:
}
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:
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) }
;.
; 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:
; 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:
; 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:
; }
;
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
; }
;
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
; }
;
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:
; }
;
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:
; 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]]
; }
;
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:
; 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:
; 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:
; 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:
; }
;
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:
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]]
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
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
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
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
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
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
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
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
}
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
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:
; 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:
; 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:
; 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:
; 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
; 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
; 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]]
; 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]]
}
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
; 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
!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}
; 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
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*)
; 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
}
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
}
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:%.*]]
; 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:%.*]]
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]]
}
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:%.*]]
}
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:%.*]]
}
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]]
}
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:%.*]]
}
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]]
}
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:%.*]]
}
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]]
}
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:%.*]]
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:%.*]]
}
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:%.*]]
; 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:%.*]]
; 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]]
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]]
}
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]]
; 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)
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
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
}
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
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]]
@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
; 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
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)
}
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:
; 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:
; 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]]
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]]
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]]
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]]
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]]
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]]
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
}
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]]
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]]
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]]
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:%.*]]
}
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]]
}
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:%.*]]
}
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]]
}
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
}
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
@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:
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]]
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
}
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:
; 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:
}
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:
; 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]]
;
; 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]]
;
; 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)
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
; 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
}
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
; 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
;.
; 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) }
;.
; 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
; 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
; 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:
; 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
; }
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
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:
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
; 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
}
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
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
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
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()
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
; }
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:%.*]]
; 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]]
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
; 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
; 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
}
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
}
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:%.*]]
; }
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:
; }
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:
; }
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:
; }
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:
; }
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:
; 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
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()
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()
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()
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 }
;.
; 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() {
; 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
; 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
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 }
; 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()
}
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()
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]]
}
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
;
}
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]]
; 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()
@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]]
@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
}
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
}
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
}
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
}
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
}
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
}
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
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()
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:%.*]])
}
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:%.*]])
}
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)
@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)
}
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)
}
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
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
}
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
}
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
}
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
; 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
; 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
; 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()
}
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
}
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]]
}
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]]
; 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:%.*]]
}
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:%.*]]
}
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:%.*]]
; 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
}
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:
; 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
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()
}
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()
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()
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]])
; 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()
}
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()
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
; 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:
; 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
}
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()
}
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()
}
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()
}
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()
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)
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()
}
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()
}
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()
}
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()
}
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()
}
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()
}
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)
}
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()
; 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
;
; 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
}
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]]
; 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
; 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]]
; 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
; 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]]
; 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
; 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]]
}
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]]
; 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
; 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
; 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
; 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
; 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]]
; 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
; 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
; 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
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]]
; 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
; 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()
; 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()
; 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 }
}
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
}
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]]
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]])
; 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
; 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
; 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
}
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:
}
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:
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> <i1 true, i1 false, i1 true, i1 false>)
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> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef)
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]])
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]])
}
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
}
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]+]]
}
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]]
}
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:
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
}
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() #
; 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:%.*]]
}
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:%.*]]
}
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:%.*]]
}
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:%.*]])
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:%.*]]
; 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:
; 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:%.*]]
; 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
; 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:
; 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:
}
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:
@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:
}
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
@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
}
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
}
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
}
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
}
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
; 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]])
}
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
;
}
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
;
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) }
;.
ret void
}
;.
-; CHECK: attributes #[[ATTR0:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn }
+; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
;.
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" }
!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
; 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) }
; 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
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:
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:
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:
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:
; 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:
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:
; 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 }
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 }
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) }
;.
}
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
; 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:%.*]]
}
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
; 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
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()
}
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:%.*]]
}
; 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)
; 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) }
!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]] = !{}
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 }
; 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 }
}
; CHECK: attributes #0 = { nounwind }
-; CHECK: attributes [[RO]] = { readonly }
+; CHECK: attributes [[RO]] = { memory(read) }
; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
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
; 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:
; 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
; 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
; 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
;
; 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
;
;.
; 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")
; 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
;
; 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)
; 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:
; 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
;
;.
; 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")
; 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:%.*]]
; 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:
; 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:%.*]]
; 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:
; 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]+]]
;
; 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 }
;.
; 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 }
;.
; 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 }
;.
; 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 }
;.
!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 }
; 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" }
; 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" }
; 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:
; 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:
; 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)
; 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)
; 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__
; 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:
; 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:
; 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}
; RUN: opt < %s -S -rewrite-statepoints-for-gc | FileCheck %s
-; CHECK: Function Attrs: nocallback nofree nosync nounwind readnone willreturn
+; CHECK: Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
; CHECK: declare i64 @llvm.x86.sse2.cvttsd2si64(<2 x double>)
declare i64 @llvm.x86.sse2.cvttsd2si64(<2 x double>)
attributes #1 = { norecurse noimplicitfloat }
;.
-; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone }
+; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind memory(none) }
; CHECK: attributes #[[ATTR1]] = { noimplicitfloat norecurse }
;.
-; 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
; 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(ptr %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, ptr @g, align 4
; CHECK-NEXT: ret void
; Here only the non-pointer argument %val is replaced, no need
; to drop the argmemonly attribute.
define internal void @ptrarg.2(ptr %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, ptr [[ARG:%.*]], align 4
; CHECK-NEXT: ret void
; Here the pointer argument %arg will be replaced by a constant. We need to
; drop inaccessiblemem_or_argmemonly.
define internal void @ptrarg.3(ptr %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, ptr @g, align 4
; CHECK-NEXT: ret void
; Here only the non-pointer argument %val is replaced, no need
; to drop the inaccessiblemem_or_argmemonly attribute.
define internal void @ptrarg.4(ptr %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, ptr [[ARG:%.*]], align 4
; CHECK-NEXT: ret void
; Here the pointer argument %arg will be replaced by a constant. We need to
; drop inaccessiblemem_or_argmemonly.
define internal void @ptrarg.5(ptr %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, ptr @g, align 4
; CHECK-NEXT: ret void
define i32 @caller.6.cs.attributes(i32 %n) {
; CHECK-LABEL: @caller.6.cs.attributes(
; CHECK-NEXT: store i32 1, ptr @g, align 4
-; CHECK-NEXT: tail call void @ptrarg.5(ptr @g, i32 10) [[NOUNWIND:#[0-9]+]]
-; CHECK-NEXT: tail call void @ptrarg.5(ptr @g, i32 10) [[NOUNWIND:#[0-9]+]]
-; CHECK-NEXT: tail call void @ptrarg.5(ptr @g, i32 10) [[NOUNWIND:#[0-9]+]]
-; CHECK-NEXT: tail call void @ptrarg.5(ptr @g, i32 10) [[NOUNWIND:#[0-9]+]]
+; CHECK-NEXT: tail call void @ptrarg.5(ptr @g, i32 10) #[[ATTR0:[0-9]+]]
+; CHECK-NEXT: tail call void @ptrarg.5(ptr @g, i32 10) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: tail call void @ptrarg.5(ptr @g, i32 10) #[[ATTR0]]
+; CHECK-NEXT: tail call void @ptrarg.5(ptr @g, i32 10) #[[ATTR4:[0-9]+]]
; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr @g, align 4
; CHECK-NEXT: ret i32 [[G_VAL]]
;
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 }
+;.
}
; CHECK: attributes #0 = { noreturn nounwind }
-; CHECK: attributes #1 = { nounwind readnone willreturn }
+; CHECK: attributes #1 = { nounwind willreturn memory(none) }
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"
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: "<stdin>", directory: "/")
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { noreturn }
; CHECK: attributes #[[ATTR1]] = { nomerge }
-; CHECK: attributes #[[ATTR2]] = { readnone }
+; CHECK: attributes #[[ATTR2]] = { memory(none) }
;.
;.
; 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}
; 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 {
+++ /dev/null
-; 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
%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:
!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)
; 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"
// 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<CallInst> Clone(cast<CallInst>(Call->clone()));
- EXPECT_TRUE(Clone->onlyReadsMemory());
+ EXPECT_TRUE(Clone->doesNotThrow());
}
}
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;
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<attrs>[\w\s]+?))?\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[\w.$-]+?)\s*'
+ r'^(\s*;\s*Function\sAttrs:\s(?P<attrs>[\w\s():,]+?))?\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[\w.$-]+?)\s*'
r'(?P<args_and_sig>\((\)|(.*?[\w.-]+?)\))[^{]*\{)\n(?P<body>.*?)^\}$',
flags=(re.M | re.S))
// 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}