Mercurial > hg > CbC > CbC_llvm
diff llvm/test/Transforms/FunctionAttrs/writeonly.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 diff
--- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll Wed Nov 09 17:47:54 2022 +0900 +++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll Fri Aug 18 09:04:13 2023 +0900 @@ -1,24 +1,38 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes -; RUN: opt < %s -passes=function-attrs -S | FileCheck %s +; 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 define void @nouses-argworn-funrn(ptr writeonly %.aaa) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funrn -; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: nouses-argworn-funrn_entry: -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; FNATTRS-LABEL: define {{[^@]+}}@nouses-argworn-funrn +; FNATTRS-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR0:[0-9]+]] { +; FNATTRS-NEXT: nouses-argworn-funrn_entry: +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@nouses-argworn-funrn +; ATTRIBUTOR-SAME: (ptr nocapture nofree readnone [[DOTAAA:%.*]]) #[[ATTR0:[0-9]+]] { +; ATTRIBUTOR-NEXT: nouses-argworn-funrn_entry: +; ATTRIBUTOR-NEXT: ret void ; nouses-argworn-funrn_entry: ret void } define void @nouses-argworn-funro(ptr writeonly %.aaa, ptr %.bbb) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn -; 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: -; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[DOTBBB]], align 4 -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) +; FNATTRS-LABEL: define {{[^@]+}}@nouses-argworn-funro +; FNATTRS-SAME: (ptr nocapture readnone [[DOTAAA:%.*]], ptr nocapture readonly [[DOTBBB:%.*]]) #[[ATTR1:[0-9]+]] { +; FNATTRS-NEXT: nouses-argworn-funro_entry: +; FNATTRS-NEXT: [[VAL:%.*]] = load i32, ptr [[DOTBBB]], align 4 +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@nouses-argworn-funro +; ATTRIBUTOR-SAME: (ptr nocapture nofree readnone [[DOTAAA:%.*]], ptr nocapture nofree nonnull readonly [[DOTBBB:%.*]]) #[[ATTR1:[0-9]+]] { +; ATTRIBUTOR-NEXT: nouses-argworn-funro_entry: +; ATTRIBUTOR-NEXT: [[VAL:%.*]] = load i32, ptr [[DOTBBB]], align 4 +; ATTRIBUTOR-NEXT: ret void ; nouses-argworn-funro_entry: %val = load i32 , ptr %.bbb @@ -30,12 +44,19 @@ @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-LABEL: define {{[^@]+}}@nouses-argworn-funwo -; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR2:[0-9]+]] { -; CHECK-NEXT: nouses-argworn-funwo_entry: -; CHECK-NEXT: store i8 0, ptr getelementptr inbounds ([[_TYPE_OF_D_CCC:%.*]], ptr @d-ccc, i32 0, i32 3), align 1 -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) +; FNATTRS-LABEL: define {{[^@]+}}@nouses-argworn-funwo +; FNATTRS-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR2:[0-9]+]] { +; FNATTRS-NEXT: nouses-argworn-funwo_entry: +; FNATTRS-NEXT: store i8 0, ptr getelementptr inbounds ([[_TYPE_OF_D_CCC:%.*]], ptr @d-ccc, i32 0, i32 3), align 1 +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@nouses-argworn-funwo +; ATTRIBUTOR-SAME: (ptr nocapture nofree readnone [[DOTAAA:%.*]]) #[[ATTR2:[0-9]+]] { +; ATTRIBUTOR-NEXT: nouses-argworn-funwo_entry: +; ATTRIBUTOR-NEXT: store i8 0, ptr getelementptr inbounds ([[_TYPE_OF_D_CCC:%.*]], ptr @d-ccc, i32 0, i32 3), align 1 +; ATTRIBUTOR-NEXT: ret void ; nouses-argworn-funwo_entry: store i8 0, ptr getelementptr inbounds (%_type_of_d-ccc, ptr @d-ccc, i32 0, i32 3) @@ -43,11 +64,17 @@ } define void @test_store(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@test_store -; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: store i8 0, ptr [[P]], align 1 -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) +; FNATTRS-LABEL: define {{[^@]+}}@test_store +; FNATTRS-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3:[0-9]+]] { +; FNATTRS-NEXT: store i8 0, ptr [[P]], align 1 +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_store +; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull writeonly [[P:%.*]]) #[[ATTR3:[0-9]+]] { +; ATTRIBUTOR-NEXT: store i8 0, ptr [[P]], align 1 +; ATTRIBUTOR-NEXT: ret void ; store i8 0, ptr %p ret void @@ -55,13 +82,21 @@ @G = external global ptr define i8 @test_store_capture(ptr %p) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@test_store_capture -; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR4:[0-9]+]] { -; CHECK-NEXT: store ptr [[P]], ptr @G, align 8 -; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr @G, align 8 -; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P2]], align 1 -; CHECK-NEXT: ret i8 [[V]] +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none) +; FNATTRS-LABEL: define {{[^@]+}}@test_store_capture +; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR4:[0-9]+]] { +; FNATTRS-NEXT: store ptr [[P]], ptr @G, align 8 +; FNATTRS-NEXT: [[P2:%.*]] = load ptr, ptr @G, align 8 +; FNATTRS-NEXT: [[V:%.*]] = load i8, ptr [[P2]], align 1 +; FNATTRS-NEXT: ret i8 [[V]] +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn +; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_store_capture +; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]]) #[[ATTR4:[0-9]+]] { +; ATTRIBUTOR-NEXT: store ptr [[P]], ptr @G, align 8 +; ATTRIBUTOR-NEXT: [[P2:%.*]] = load ptr, ptr @G, align 8 +; ATTRIBUTOR-NEXT: [[V:%.*]] = load i8, ptr [[P2]], align 1 +; ATTRIBUTOR-NEXT: ret i8 [[V]] ; store ptr %p, ptr @G %p2 = load ptr, ptr @G @@ -70,12 +105,19 @@ } define void @test_addressing(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@test_addressing -; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8 -; CHECK-NEXT: store i32 0, ptr [[GEP]], align 4 -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) +; FNATTRS-LABEL: define {{[^@]+}}@test_addressing +; FNATTRS-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3]] { +; FNATTRS-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8 +; FNATTRS-NEXT: store i32 0, ptr [[GEP]], align 4 +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_addressing +; ATTRIBUTOR-SAME: (ptr nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] { +; ATTRIBUTOR-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8 +; ATTRIBUTOR-NEXT: store i32 0, ptr [[GEP]], align 4 +; ATTRIBUTOR-NEXT: ret void ; %gep = getelementptr i8, ptr %p, i64 8 store i32 0, ptr %gep @@ -83,12 +125,19 @@ } define void @test_readwrite(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@test_readwrite -; CHECK-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR5:[0-9]+]] { -; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1 -; CHECK-NEXT: store i8 [[V]], ptr [[P]], align 1 -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) +; FNATTRS-LABEL: define {{[^@]+}}@test_readwrite +; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR5:[0-9]+]] { +; FNATTRS-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1 +; FNATTRS-NEXT: store i8 [[V]], ptr [[P]], align 1 +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_readwrite +; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull [[P:%.*]]) #[[ATTR5:[0-9]+]] { +; ATTRIBUTOR-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1 +; ATTRIBUTOR-NEXT: store i8 [[V]], ptr [[P]], align 1 +; ATTRIBUTOR-NEXT: ret void ; %v = load i8, ptr %p store i8 %v, ptr %p @@ -96,22 +145,34 @@ } define void @test_volatile(ptr %p) { -; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind -; CHECK-LABEL: define {{[^@]+}}@test_volatile -; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR6:[0-9]+]] { -; CHECK-NEXT: store volatile i8 0, ptr [[P]], align 1 -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) +; FNATTRS-LABEL: define {{[^@]+}}@test_volatile +; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR6:[0-9]+]] { +; FNATTRS-NEXT: store volatile i8 0, ptr [[P]], align 1 +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_volatile +; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]]) #[[ATTR6:[0-9]+]] { +; ATTRIBUTOR-NEXT: store volatile i8 0, ptr [[P]], align 1 +; ATTRIBUTOR-NEXT: ret void ; store volatile i8 0, ptr %p ret void } define void @test_atomicrmw(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn -; 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 -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; FNATTRS-LABEL: define {{[^@]+}}@test_atomicrmw +; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR7:[0-9]+]] { +; FNATTRS-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1 +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_atomicrmw +; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull [[P:%.*]]) #[[ATTR6]] { +; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1 +; ATTRIBUTOR-NEXT: ret void ; atomicrmw add ptr %p, i8 0 seq_cst ret void @@ -121,10 +182,10 @@ declare void @direct1_callee(ptr %p) define void @direct1(ptr %p) { -; CHECK-LABEL: define {{[^@]+}}@direct1 -; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: call void @direct1_callee(ptr [[P]]) -; CHECK-NEXT: ret void +; COMMON-LABEL: define {{[^@]+}}@direct1 +; COMMON-SAME: (ptr [[P:%.*]]) { +; COMMON-NEXT: call void @direct1_callee(ptr [[P]]) +; COMMON-NEXT: ret void ; call void @direct1_callee(ptr %p) ret void @@ -134,11 +195,17 @@ ; writeonly w/o nocapture is not enough define void @direct2(ptr %p) { -; CHECK: Function Attrs: writeonly -; CHECK-LABEL: define {{[^@]+}}@direct2 -; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR8:[0-9]+]] { -; CHECK-NEXT: call void @direct2_callee(ptr [[P]]) -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: memory(write) +; FNATTRS-LABEL: define {{[^@]+}}@direct2 +; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR8:[0-9]+]] { +; FNATTRS-NEXT: call void @direct2_callee(ptr [[P]]) +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: memory(write) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@direct2 +; ATTRIBUTOR-SAME: (ptr writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] { +; ATTRIBUTOR-NEXT: call void @direct2_callee(ptr [[P]]) #[[ATTR7]] +; ATTRIBUTOR-NEXT: ret void ; call void @direct2_callee(ptr %p) ; read back from global, read through pointer... @@ -146,11 +213,17 @@ } define void @direct2b(ptr %p) { -; CHECK: Function Attrs: writeonly -; CHECK-LABEL: define {{[^@]+}}@direct2b -; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: call void @direct2_callee(ptr nocapture [[P]]) -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: memory(write) +; FNATTRS-LABEL: define {{[^@]+}}@direct2b +; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR8]] { +; FNATTRS-NEXT: call void @direct2_callee(ptr nocapture [[P]]) +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: memory(write) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@direct2b +; ATTRIBUTOR-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR7]] { +; ATTRIBUTOR-NEXT: call void @direct2_callee(ptr nocapture writeonly [[P]]) #[[ATTR7]] +; ATTRIBUTOR-NEXT: ret void ; call void @direct2_callee(ptr nocapture %p) ret void @@ -159,61 +232,87 @@ declare void @direct3_callee(ptr nocapture writeonly %p) define void @direct3(ptr %p) { -; CHECK-LABEL: define {{[^@]+}}@direct3 -; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) { -; CHECK-NEXT: call void @direct3_callee(ptr [[P]]) -; CHECK-NEXT: ret void +; FNATTRS-LABEL: define {{[^@]+}}@direct3 +; FNATTRS-SAME: (ptr nocapture writeonly [[P:%.*]]) { +; FNATTRS-NEXT: call void @direct3_callee(ptr [[P]]) +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR-LABEL: define {{[^@]+}}@direct3 +; ATTRIBUTOR-SAME: (ptr nocapture writeonly [[P:%.*]]) { +; ATTRIBUTOR-NEXT: call void @direct3_callee(ptr nocapture writeonly [[P]]) +; ATTRIBUTOR-NEXT: ret void ; call void @direct3_callee(ptr %p) ret void } define void @direct3b(ptr %p) { -; CHECK-LABEL: define {{[^@]+}}@direct3b -; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read-and-capture"(ptr [[P]]) ] -; CHECK-NEXT: ret void +; COMMON-LABEL: define {{[^@]+}}@direct3b +; COMMON-SAME: (ptr [[P:%.*]]) { +; COMMON-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read-and-capture"(ptr [[P]]) ] +; COMMON-NEXT: ret void ; call void @direct3_callee(ptr %p) ["may-read-and-capture"(ptr %p)] ret void } define void @direct3c(ptr %p) { -; CHECK-LABEL: define {{[^@]+}}@direct3c -; CHECK-SAME: (ptr nocapture [[P:%.*]]) { -; CHECK-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read"() ] -; CHECK-NEXT: ret void +; FNATTRS-LABEL: define {{[^@]+}}@direct3c +; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) { +; FNATTRS-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read"() ] +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR-LABEL: define {{[^@]+}}@direct3c +; ATTRIBUTOR-SAME: (ptr nocapture [[P:%.*]]) { +; ATTRIBUTOR-NEXT: call void @direct3_callee(ptr nocapture [[P]]) [ "may-read"() ] +; ATTRIBUTOR-NEXT: ret void ; call void @direct3_callee(ptr %p) ["may-read"()] ret void } define void @fptr_test1(ptr %p, ptr %f) { -; CHECK-LABEL: define {{[^@]+}}@fptr_test1 -; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[F:%.*]]) { -; CHECK-NEXT: call void [[F]](ptr [[P]]) -; CHECK-NEXT: ret void +; FNATTRS-LABEL: define {{[^@]+}}@fptr_test1 +; FNATTRS-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[F:%.*]]) { +; FNATTRS-NEXT: call void [[F]](ptr [[P]]) +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test1 +; ATTRIBUTOR-SAME: (ptr [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) { +; ATTRIBUTOR-NEXT: call void [[F]](ptr [[P]]) +; ATTRIBUTOR-NEXT: ret void ; call void %f(ptr %p) ret void } define void @fptr_test2(ptr %p, ptr %f) { -; CHECK-LABEL: define {{[^@]+}}@fptr_test2 -; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) { -; CHECK-NEXT: call void [[F]](ptr nocapture writeonly [[P]]) -; CHECK-NEXT: ret void +; FNATTRS-LABEL: define {{[^@]+}}@fptr_test2 +; FNATTRS-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) { +; FNATTRS-NEXT: call void [[F]](ptr nocapture writeonly [[P]]) +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test2 +; ATTRIBUTOR-SAME: (ptr nocapture [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) { +; ATTRIBUTOR-NEXT: call void [[F]](ptr nocapture writeonly [[P]]) +; ATTRIBUTOR-NEXT: ret void ; call void %f(ptr nocapture writeonly %p) ret void } define void @fptr_test3(ptr %p, ptr %f) { -; CHECK: Function Attrs: writeonly -; CHECK-LABEL: define {{[^@]+}}@fptr_test3 -; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: call void [[F]](ptr nocapture [[P]]) #[[ATTR8]] -; CHECK-NEXT: ret void +; FNATTRS: Function Attrs: memory(write) +; FNATTRS-LABEL: define {{[^@]+}}@fptr_test3 +; FNATTRS-SAME: (ptr nocapture [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR8]] { +; FNATTRS-NEXT: call void [[F]](ptr nocapture [[P]]) #[[ATTR8]] +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: memory(write) +; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test3 +; ATTRIBUTOR-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture nofree nonnull writeonly [[F:%.*]]) #[[ATTR7]] { +; ATTRIBUTOR-NEXT: call void [[F]](ptr nocapture [[P]]) #[[ATTR7]] +; ATTRIBUTOR-NEXT: ret void ; call void %f(ptr nocapture %p) writeonly ret void