Mercurial > hg > CbC > CbC_llvm
view llvm/test/Transforms/FunctionAttrs/argmemonly.ll @ 252:1f2b6ac9f198 llvm-original
LLVM16-1
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 18 Aug 2023 09:04:13 +0900 |
parents | c4bab56944e8 |
children |
line wrap: on
line source
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 2 ; RUN: opt -passes=function-attrs -S < %s | FileCheck --check-prefixes=COMMON,FNATTRS %s ; RUN: opt -passes=attributor-light -S < %s | FileCheck --check-prefixes=COMMON,ATTRIBUTOR %s @g = global i32 20 define void @test_no_read_or_write() { ; COMMON: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; COMMON-LABEL: define void @test_no_read_or_write ; COMMON-SAME: () #[[ATTR0:[0-9]+]] { ; COMMON-NEXT: entry: ; COMMON-NEXT: ret void ; entry: ret void } define i32 @test_only_read_arg(ptr %ptr) { ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; FNATTRS-LABEL: define i32 @test_only_read_arg ; FNATTRS-SAME: (ptr nocapture readonly [[PTR:%.*]]) #[[ATTR1:[0-9]+]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: [[L:%.*]] = load i32, ptr [[PTR]], align 4 ; FNATTRS-NEXT: ret i32 [[L]] ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; ATTRIBUTOR-LABEL: define i32 @test_only_read_arg ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readonly [[PTR:%.*]]) #[[ATTR1:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: [[L:%.*]] = load i32, ptr [[PTR]], align 4 ; ATTRIBUTOR-NEXT: ret i32 [[L]] ; entry: %l = load i32, ptr %ptr ret i32 %l } define i32 @test_only_read_arg_already_has_argmemonly(ptr %ptr) argmemonly { ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; FNATTRS-LABEL: define i32 @test_only_read_arg_already_has_argmemonly ; FNATTRS-SAME: (ptr nocapture readonly [[PTR:%.*]]) #[[ATTR1]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: [[L:%.*]] = load i32, ptr [[PTR]], align 4 ; FNATTRS-NEXT: ret i32 [[L]] ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; ATTRIBUTOR-LABEL: define i32 @test_only_read_arg_already_has_argmemonly ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readonly [[PTR:%.*]]) #[[ATTR1]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: [[L:%.*]] = load i32, ptr [[PTR]], align 4 ; ATTRIBUTOR-NEXT: ret i32 [[L]] ; entry: %l = load i32, ptr %ptr ret i32 %l } define i32 @test_read_global() { ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none) ; FNATTRS-LABEL: define i32 @test_read_global ; FNATTRS-SAME: () #[[ATTR2:[0-9]+]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: [[L:%.*]] = load i32, ptr @g, align 4 ; FNATTRS-NEXT: ret i32 [[L]] ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) ; ATTRIBUTOR-LABEL: define i32 @test_read_global ; ATTRIBUTOR-SAME: () #[[ATTR2:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: [[L:%.*]] = load i32, ptr @g, align 4 ; ATTRIBUTOR-NEXT: ret i32 [[L]] ; entry: %l = load i32, ptr @g ret i32 %l } define i32 @test_read_loaded_ptr(ptr %ptr) { ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none) ; FNATTRS-LABEL: define i32 @test_read_loaded_ptr ; FNATTRS-SAME: (ptr nocapture readonly [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: [[L:%.*]] = load ptr, ptr [[PTR]], align 8 ; FNATTRS-NEXT: [[L_2:%.*]] = load i32, ptr [[L]], align 4 ; FNATTRS-NEXT: ret i32 [[L_2]] ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) ; ATTRIBUTOR-LABEL: define i32 @test_read_loaded_ptr ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readonly [[PTR:%.*]]) #[[ATTR2]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: [[L:%.*]] = load ptr, ptr [[PTR]], align 8 ; ATTRIBUTOR-NEXT: [[L_2:%.*]] = load i32, ptr [[L]], align 4 ; ATTRIBUTOR-NEXT: ret i32 [[L_2]] ; entry: %l = load ptr, ptr %ptr %l.2 = load i32, ptr %l ret i32 %l.2 } define void @test_only_write_arg(ptr %ptr) { ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) ; FNATTRS-LABEL: define void @test_only_write_arg ; FNATTRS-SAME: (ptr nocapture writeonly [[PTR:%.*]]) #[[ATTR4:[0-9]+]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: store i32 0, ptr [[PTR]], align 4 ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) ; ATTRIBUTOR-LABEL: define void @test_only_write_arg ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: store i32 0, ptr [[PTR]], align 4 ; ATTRIBUTOR-NEXT: ret void ; entry: store i32 0, ptr %ptr ret void } define void @test_write_global() { ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) ; FNATTRS-LABEL: define void @test_write_global ; FNATTRS-SAME: () #[[ATTR5:[0-9]+]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: store i32 0, ptr @g, align 4 ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) ; ATTRIBUTOR-LABEL: define void @test_write_global ; ATTRIBUTOR-SAME: () #[[ATTR4:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: store i32 0, ptr @g, align 4 ; ATTRIBUTOR-NEXT: ret void ; entry: store i32 0, ptr @g ret void } declare void @fn_may_access_memory() define void @test_call_may_access_memory() { ; COMMON-LABEL: define void @test_call_may_access_memory() { ; COMMON-NEXT: entry: ; COMMON-NEXT: call void @fn_may_access_memory() ; COMMON-NEXT: ret void ; entry: call void @fn_may_access_memory() ret void } declare i32 @fn_readnone() readnone define void @test_call_readnone(ptr %ptr) { ; FNATTRS: Function Attrs: memory(argmem: write) ; FNATTRS-LABEL: define void @test_call_readnone ; FNATTRS-SAME: (ptr nocapture writeonly [[PTR:%.*]]) #[[ATTR7:[0-9]+]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: [[C:%.*]] = call i32 @fn_readnone() ; FNATTRS-NEXT: store i32 [[C]], ptr [[PTR]], align 4 ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nosync memory(argmem: write) ; ATTRIBUTOR-LABEL: define void @test_call_readnone ; ATTRIBUTOR-SAME: (ptr nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR6:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: [[C:%.*]] = call i32 @fn_readnone() #[[ATTR18:[0-9]+]] ; ATTRIBUTOR-NEXT: store i32 [[C]], ptr [[PTR]], align 4 ; ATTRIBUTOR-NEXT: ret void ; entry: %c = call i32 @fn_readnone() store i32 %c, ptr %ptr ret void } declare i32 @fn_argmemonly(ptr) argmemonly define i32 @test_call_argmemonly(ptr %ptr) { ; FNATTRS: Function Attrs: memory(argmem: readwrite) ; FNATTRS-LABEL: define i32 @test_call_argmemonly ; FNATTRS-SAME: (ptr [[PTR:%.*]]) #[[ATTR8:[0-9]+]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: [[C:%.*]] = call i32 @fn_argmemonly(ptr [[PTR]]) ; FNATTRS-NEXT: ret i32 [[C]] ; ; ATTRIBUTOR: Function Attrs: memory(argmem: readwrite) ; ATTRIBUTOR-LABEL: define i32 @test_call_argmemonly ; ATTRIBUTOR-SAME: (ptr [[PTR:%.*]]) #[[ATTR7:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: [[C:%.*]] = call i32 @fn_argmemonly(ptr [[PTR]]) ; ATTRIBUTOR-NEXT: ret i32 [[C]] ; entry: %c = call i32 @fn_argmemonly(ptr %ptr) ret i32 %c } define i32 @test_call_fn_where_argmemonly_can_be_inferred(ptr %ptr) { ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; FNATTRS-LABEL: define i32 @test_call_fn_where_argmemonly_can_be_inferred ; FNATTRS-SAME: (ptr nocapture readonly [[PTR:%.*]]) #[[ATTR1]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: [[C:%.*]] = call i32 @test_only_read_arg(ptr [[PTR]]) ; FNATTRS-NEXT: ret i32 [[C]] ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; ATTRIBUTOR-LABEL: define i32 @test_call_fn_where_argmemonly_can_be_inferred ; ATTRIBUTOR-SAME: (ptr nocapture nofree readonly [[PTR:%.*]]) #[[ATTR1]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: [[C:%.*]] = call i32 @test_only_read_arg(ptr nocapture nofree readonly [[PTR]]) #[[ATTR19:[0-9]+]] ; ATTRIBUTOR-NEXT: ret i32 [[C]] ; entry: %c = call i32 @test_only_read_arg(ptr %ptr) ret i32 %c } define void @test_memcpy_argonly(ptr %dst, ptr %src) { ; FNATTRS: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) ; FNATTRS-LABEL: define void @test_memcpy_argonly ; FNATTRS-SAME: (ptr nocapture writeonly [[DST:%.*]], ptr nocapture readonly [[SRC:%.*]]) #[[ATTR9:[0-9]+]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 32, i1 false) ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; ATTRIBUTOR-LABEL: define void @test_memcpy_argonly ; ATTRIBUTOR-SAME: (ptr nocapture nofree writeonly [[DST:%.*]], ptr nocapture nofree readonly [[SRC:%.*]]) #[[ATTR8:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly [[DST]], ptr nocapture readonly [[SRC]], i64 32, i1 false) #[[ATTR20:[0-9]+]] ; ATTRIBUTOR-NEXT: ret void ; entry: call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 32, i1 false) ret void } declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1) @arr = global [32 x i8] zeroinitializer define void @test_memcpy_src_global(ptr %dst) { ; FNATTRS: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) ; FNATTRS-LABEL: define void @test_memcpy_src_global ; FNATTRS-SAME: (ptr nocapture writeonly [[DST:%.*]]) #[[ATTR11:[0-9]+]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr @arr, i64 32, i1 false) ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn ; ATTRIBUTOR-LABEL: define void @test_memcpy_src_global ; ATTRIBUTOR-SAME: (ptr nocapture nofree writeonly [[DST:%.*]]) #[[ATTR10:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly [[DST]], ptr readonly @arr, i64 32, i1 false) #[[ATTR20]] ; ATTRIBUTOR-NEXT: ret void ; entry: call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr @arr, i64 32, i1 false) ret void } define void @test_memcpy_dst_global(ptr %src) { ; FNATTRS: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) ; FNATTRS-LABEL: define void @test_memcpy_dst_global ; FNATTRS-SAME: (ptr nocapture readonly [[SRC:%.*]]) #[[ATTR11]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr @arr, ptr [[SRC]], i64 32, i1 false) ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn ; ATTRIBUTOR-LABEL: define void @test_memcpy_dst_global ; ATTRIBUTOR-SAME: (ptr nocapture nofree readonly [[SRC:%.*]]) #[[ATTR10]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr writeonly @arr, ptr nocapture readonly [[SRC]], i64 32, i1 false) #[[ATTR20]] ; ATTRIBUTOR-NEXT: ret void ; entry: call void @llvm.memcpy.p0.p0.i64(ptr @arr, ptr %src, i64 32, i1 false) ret void } define i32 @test_read_arg_access_alloca(ptr %ptr) { ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) ; FNATTRS-LABEL: define i32 @test_read_arg_access_alloca ; FNATTRS-SAME: (ptr nocapture readonly [[PTR:%.*]]) #[[ATTR1]] { ; FNATTRS-NEXT: entry: ; FNATTRS-NEXT: [[A:%.*]] = alloca i32, align 4 ; FNATTRS-NEXT: [[L:%.*]] = load i32, ptr [[PTR]], align 4 ; FNATTRS-NEXT: store i32 [[L]], ptr [[A]], align 4 ; FNATTRS-NEXT: [[L_2:%.*]] = load i32, ptr [[A]], align 4 ; FNATTRS-NEXT: ret i32 [[L_2]] ; ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; ATTRIBUTOR-LABEL: define i32 @test_read_arg_access_alloca ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readonly [[PTR:%.*]]) #[[ATTR8]] { ; ATTRIBUTOR-NEXT: entry: ; ATTRIBUTOR-NEXT: [[A:%.*]] = alloca i32, align 4 ; ATTRIBUTOR-NEXT: [[L:%.*]] = load i32, ptr [[PTR]], align 4 ; ATTRIBUTOR-NEXT: store i32 [[L]], ptr [[A]], align 4 ; ATTRIBUTOR-NEXT: [[L_2:%.*]] = load i32, ptr [[A]], align 4 ; ATTRIBUTOR-NEXT: ret i32 [[L_2]] ; entry: %a = alloca i32 %l = load i32, ptr %ptr store i32 %l, ptr %a %l.2 = load i32, ptr %a ret i32 %l.2 } declare void @fn_inaccessiblememonly() inaccessiblememonly define void @test_inaccessiblememonly() { ; FNATTRS: Function Attrs: memory(inaccessiblemem: readwrite) ; FNATTRS-LABEL: define void @test_inaccessiblememonly ; FNATTRS-SAME: () #[[ATTR12:[0-9]+]] { ; FNATTRS-NEXT: call void @fn_inaccessiblememonly() ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: memory(inaccessiblemem: readwrite) ; ATTRIBUTOR-LABEL: define void @test_inaccessiblememonly ; ATTRIBUTOR-SAME: () #[[ATTR11:[0-9]+]] { ; ATTRIBUTOR-NEXT: call void @fn_inaccessiblememonly() ; ATTRIBUTOR-NEXT: ret void ; call void @fn_inaccessiblememonly() ret void } define void @test_inaccessiblememonly_readonly() { ; FNATTRS: Function Attrs: nofree memory(inaccessiblemem: read) ; FNATTRS-LABEL: define void @test_inaccessiblememonly_readonly ; FNATTRS-SAME: () #[[ATTR13:[0-9]+]] { ; FNATTRS-NEXT: call void @fn_inaccessiblememonly() #[[ATTR18:[0-9]+]] ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nosync memory(inaccessiblemem: read) ; ATTRIBUTOR-LABEL: define void @test_inaccessiblememonly_readonly ; ATTRIBUTOR-SAME: () #[[ATTR12:[0-9]+]] { ; ATTRIBUTOR-NEXT: call void @fn_inaccessiblememonly() #[[ATTR21:[0-9]+]] ; ATTRIBUTOR-NEXT: ret void ; call void @fn_inaccessiblememonly() readonly ret void } define void @test_inaccessibleorargmemonly_readonly(ptr %arg) { ; FNATTRS: Function Attrs: nofree memory(argmem: read, inaccessiblemem: read) ; FNATTRS-LABEL: define void @test_inaccessibleorargmemonly_readonly ; FNATTRS-SAME: (ptr nocapture readonly [[ARG:%.*]]) #[[ATTR14:[0-9]+]] { ; FNATTRS-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG]], align 4 ; FNATTRS-NEXT: call void @fn_inaccessiblememonly() #[[ATTR18]] ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nosync memory(argmem: read, inaccessiblemem: read) ; ATTRIBUTOR-LABEL: define void @test_inaccessibleorargmemonly_readonly ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readonly [[ARG:%.*]]) #[[ATTR13:[0-9]+]] { ; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG]], align 4 ; ATTRIBUTOR-NEXT: call void @fn_inaccessiblememonly() #[[ATTR21]] ; ATTRIBUTOR-NEXT: ret void ; load i32, ptr %arg call void @fn_inaccessiblememonly() readonly ret void } define void @test_inaccessibleorargmemonly_readwrite(ptr %arg) { ; FNATTRS: Function Attrs: memory(argmem: write, inaccessiblemem: read) ; FNATTRS-LABEL: define void @test_inaccessibleorargmemonly_readwrite ; FNATTRS-SAME: (ptr nocapture writeonly [[ARG:%.*]]) #[[ATTR15:[0-9]+]] { ; FNATTRS-NEXT: store i32 0, ptr [[ARG]], align 4 ; FNATTRS-NEXT: call void @fn_inaccessiblememonly() #[[ATTR18]] ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nosync memory(argmem: readwrite, inaccessiblemem: readwrite) ; ATTRIBUTOR-LABEL: define void @test_inaccessibleorargmemonly_readwrite ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull writeonly [[ARG:%.*]]) #[[ATTR14:[0-9]+]] { ; ATTRIBUTOR-NEXT: store i32 0, ptr [[ARG]], align 4 ; ATTRIBUTOR-NEXT: call void @fn_inaccessiblememonly() #[[ATTR21]] ; ATTRIBUTOR-NEXT: ret void ; store i32 0, ptr %arg call void @fn_inaccessiblememonly() readonly ret void } define void @test_recursive_argmem_read(ptr %p) { ; FNATTRS: Function Attrs: nofree nosync nounwind memory(argmem: read) ; FNATTRS-LABEL: define void @test_recursive_argmem_read ; FNATTRS-SAME: (ptr nocapture readonly [[P:%.*]]) #[[ATTR16:[0-9]+]] { ; FNATTRS-NEXT: [[PVAL:%.*]] = load ptr, ptr [[P]], align 8 ; FNATTRS-NEXT: call void @test_recursive_argmem_read(ptr [[PVAL]]) ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(read) ; ATTRIBUTOR-LABEL: define void @test_recursive_argmem_read ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readonly [[P:%.*]]) #[[ATTR15:[0-9]+]] { ; ATTRIBUTOR-NEXT: [[PVAL:%.*]] = load ptr, ptr [[P]], align 8 ; ATTRIBUTOR-NEXT: call void @test_recursive_argmem_read(ptr nocapture nofree readonly [[PVAL]]) #[[ATTR15]] ; ATTRIBUTOR-NEXT: ret void ; %pval = load ptr, ptr %p call void @test_recursive_argmem_read(ptr %pval) ret void } define void @test_recursive_argmem_readwrite(ptr %p) { ; FNATTRS: Function Attrs: nofree nosync nounwind memory(argmem: readwrite) ; FNATTRS-LABEL: define void @test_recursive_argmem_readwrite ; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR17:[0-9]+]] { ; FNATTRS-NEXT: [[PVAL:%.*]] = load ptr, ptr [[P]], align 8 ; FNATTRS-NEXT: store i32 0, ptr [[P]], align 4 ; FNATTRS-NEXT: call void @test_recursive_argmem_readwrite(ptr [[PVAL]]) ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind ; ATTRIBUTOR-LABEL: define void @test_recursive_argmem_readwrite ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull [[P:%.*]]) #[[ATTR16:[0-9]+]] { ; ATTRIBUTOR-NEXT: [[PVAL:%.*]] = load ptr, ptr [[P]], align 8 ; ATTRIBUTOR-NEXT: store i32 0, ptr [[P]], align 4 ; ATTRIBUTOR-NEXT: call void @test_recursive_argmem_readwrite(ptr nocapture nofree [[PVAL]]) #[[ATTR16]] ; ATTRIBUTOR-NEXT: ret void ; %pval = load ptr, ptr %p store i32 0, ptr %p call void @test_recursive_argmem_readwrite(ptr %pval) ret void } define void @test_recursive_argmem_read_alloca(ptr %p) { ; FNATTRS: Function Attrs: nofree nosync nounwind memory(argmem: read) ; FNATTRS-LABEL: define void @test_recursive_argmem_read_alloca ; FNATTRS-SAME: (ptr nocapture readonly [[P:%.*]]) #[[ATTR16]] { ; FNATTRS-NEXT: [[A:%.*]] = alloca ptr, align 8 ; FNATTRS-NEXT: [[TMP1:%.*]] = load i32, ptr [[P]], align 4 ; FNATTRS-NEXT: call void @test_recursive_argmem_read_alloca(ptr [[A]]) ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(argmem: read) ; ATTRIBUTOR-LABEL: define void @test_recursive_argmem_read_alloca ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readonly [[P:%.*]]) #[[ATTR17:[0-9]+]] { ; ATTRIBUTOR-NEXT: [[A:%.*]] = alloca ptr, align 8 ; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = load i32, ptr [[P]], align 4 ; ATTRIBUTOR-NEXT: call void @test_recursive_argmem_read_alloca(ptr nocapture nofree nonnull readonly [[A]]) #[[ATTR15]] ; ATTRIBUTOR-NEXT: ret void ; %a = alloca ptr load i32, ptr %p call void @test_recursive_argmem_read_alloca(ptr %a) ret void } define void @test_scc_argmem_read_1(ptr %p) { ; FNATTRS: Function Attrs: nofree nosync nounwind memory(argmem: read) ; FNATTRS-LABEL: define void @test_scc_argmem_read_1 ; FNATTRS-SAME: (ptr nocapture readonly [[P:%.*]]) #[[ATTR16]] { ; FNATTRS-NEXT: [[PVAL:%.*]] = load ptr, ptr [[P]], align 8 ; FNATTRS-NEXT: call void @test_scc_argmem_read_2(ptr [[PVAL]]) ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(read) ; ATTRIBUTOR-LABEL: define void @test_scc_argmem_read_1 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readonly [[P:%.*]]) #[[ATTR15]] { ; ATTRIBUTOR-NEXT: [[PVAL:%.*]] = load ptr, ptr [[P]], align 8 ; ATTRIBUTOR-NEXT: call void @test_scc_argmem_read_2(ptr nocapture nofree readonly [[PVAL]]) #[[ATTR15]] ; ATTRIBUTOR-NEXT: ret void ; %pval = load ptr, ptr %p call void @test_scc_argmem_read_2(ptr %pval) ret void } define void @test_scc_argmem_read_2(ptr %p) { ; FNATTRS: Function Attrs: nofree nosync nounwind memory(argmem: read) ; FNATTRS-LABEL: define void @test_scc_argmem_read_2 ; FNATTRS-SAME: (ptr nocapture readonly [[P:%.*]]) #[[ATTR16]] { ; FNATTRS-NEXT: call void @test_scc_argmem_read_1(ptr [[P]]) ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(read) ; ATTRIBUTOR-LABEL: define void @test_scc_argmem_read_2 ; ATTRIBUTOR-SAME: (ptr nocapture nofree readonly [[P:%.*]]) #[[ATTR15]] { ; ATTRIBUTOR-NEXT: call void @test_scc_argmem_read_1(ptr nocapture nofree readonly [[P]]) #[[ATTR15]] ; ATTRIBUTOR-NEXT: ret void ; call void @test_scc_argmem_read_1(ptr %p) ret void }