comparison 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
comparison
equal deleted inserted replaced
237:c80f45b162ad 252:1f2b6ac9f198
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes 1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
2 ; RUN: opt < %s -passes=function-attrs -S | FileCheck %s 2 ; RUN: opt -passes=function-attrs -S < %s | FileCheck --check-prefixes=COMMON,FNATTRS %s
3 ; RUN: opt -passes=attributor-light -S < %s | FileCheck --check-prefixes=COMMON,ATTRIBUTOR %s
3 4
4 define void @nouses-argworn-funrn(ptr writeonly %.aaa) { 5 define void @nouses-argworn-funrn(ptr writeonly %.aaa) {
5 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn 6 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
6 ; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funrn 7 ; FNATTRS-LABEL: define {{[^@]+}}@nouses-argworn-funrn
7 ; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR0:[0-9]+]] { 8 ; FNATTRS-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR0:[0-9]+]] {
8 ; CHECK-NEXT: nouses-argworn-funrn_entry: 9 ; FNATTRS-NEXT: nouses-argworn-funrn_entry:
9 ; CHECK-NEXT: ret void 10 ; FNATTRS-NEXT: ret void
11 ;
12 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
13 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@nouses-argworn-funrn
14 ; ATTRIBUTOR-SAME: (ptr nocapture nofree readnone [[DOTAAA:%.*]]) #[[ATTR0:[0-9]+]] {
15 ; ATTRIBUTOR-NEXT: nouses-argworn-funrn_entry:
16 ; ATTRIBUTOR-NEXT: ret void
10 ; 17 ;
11 nouses-argworn-funrn_entry: 18 nouses-argworn-funrn_entry:
12 ret void 19 ret void
13 } 20 }
14 21
15 define void @nouses-argworn-funro(ptr writeonly %.aaa, ptr %.bbb) { 22 define void @nouses-argworn-funro(ptr writeonly %.aaa, ptr %.bbb) {
16 ; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn 23 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
17 ; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funro 24 ; FNATTRS-LABEL: define {{[^@]+}}@nouses-argworn-funro
18 ; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]], ptr nocapture readonly [[DOTBBB:%.*]]) #[[ATTR1:[0-9]+]] { 25 ; FNATTRS-SAME: (ptr nocapture readnone [[DOTAAA:%.*]], ptr nocapture readonly [[DOTBBB:%.*]]) #[[ATTR1:[0-9]+]] {
19 ; CHECK-NEXT: nouses-argworn-funro_entry: 26 ; FNATTRS-NEXT: nouses-argworn-funro_entry:
20 ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[DOTBBB]], align 4 27 ; FNATTRS-NEXT: [[VAL:%.*]] = load i32, ptr [[DOTBBB]], align 4
21 ; CHECK-NEXT: ret void 28 ; FNATTRS-NEXT: ret void
29 ;
30 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
31 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@nouses-argworn-funro
32 ; ATTRIBUTOR-SAME: (ptr nocapture nofree readnone [[DOTAAA:%.*]], ptr nocapture nofree nonnull readonly [[DOTBBB:%.*]]) #[[ATTR1:[0-9]+]] {
33 ; ATTRIBUTOR-NEXT: nouses-argworn-funro_entry:
34 ; ATTRIBUTOR-NEXT: [[VAL:%.*]] = load i32, ptr [[DOTBBB]], align 4
35 ; ATTRIBUTOR-NEXT: ret void
22 ; 36 ;
23 nouses-argworn-funro_entry: 37 nouses-argworn-funro_entry:
24 %val = load i32 , ptr %.bbb 38 %val = load i32 , ptr %.bbb
25 ret void 39 ret void
26 } 40 }
28 %_type_of_d-ccc = type <{ ptr, i8, i8, i8, i8 }> 42 %_type_of_d-ccc = type <{ ptr, i8, i8, i8, i8 }>
29 43
30 @d-ccc = internal global %_type_of_d-ccc <{ ptr null, i8 1, i8 13, i8 0, i8 -127 }>, align 8 44 @d-ccc = internal global %_type_of_d-ccc <{ ptr null, i8 1, i8 13, i8 0, i8 -127 }>, align 8
31 45
32 define void @nouses-argworn-funwo(ptr writeonly %.aaa) { 46 define void @nouses-argworn-funwo(ptr writeonly %.aaa) {
33 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn writeonly 47 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
34 ; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funwo 48 ; FNATTRS-LABEL: define {{[^@]+}}@nouses-argworn-funwo
35 ; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR2:[0-9]+]] { 49 ; FNATTRS-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR2:[0-9]+]] {
36 ; CHECK-NEXT: nouses-argworn-funwo_entry: 50 ; FNATTRS-NEXT: nouses-argworn-funwo_entry:
37 ; CHECK-NEXT: store i8 0, ptr getelementptr inbounds ([[_TYPE_OF_D_CCC:%.*]], ptr @d-ccc, i32 0, i32 3), align 1 51 ; FNATTRS-NEXT: store i8 0, ptr getelementptr inbounds ([[_TYPE_OF_D_CCC:%.*]], ptr @d-ccc, i32 0, i32 3), align 1
38 ; CHECK-NEXT: ret void 52 ; FNATTRS-NEXT: ret void
53 ;
54 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
55 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@nouses-argworn-funwo
56 ; ATTRIBUTOR-SAME: (ptr nocapture nofree readnone [[DOTAAA:%.*]]) #[[ATTR2:[0-9]+]] {
57 ; ATTRIBUTOR-NEXT: nouses-argworn-funwo_entry:
58 ; ATTRIBUTOR-NEXT: store i8 0, ptr getelementptr inbounds ([[_TYPE_OF_D_CCC:%.*]], ptr @d-ccc, i32 0, i32 3), align 1
59 ; ATTRIBUTOR-NEXT: ret void
39 ; 60 ;
40 nouses-argworn-funwo_entry: 61 nouses-argworn-funwo_entry:
41 store i8 0, ptr getelementptr inbounds (%_type_of_d-ccc, ptr @d-ccc, i32 0, i32 3) 62 store i8 0, ptr getelementptr inbounds (%_type_of_d-ccc, ptr @d-ccc, i32 0, i32 3)
42 ret void 63 ret void
43 } 64 }
44 65
45 define void @test_store(ptr %p) { 66 define void @test_store(ptr %p) {
46 ; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly 67 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
47 ; CHECK-LABEL: define {{[^@]+}}@test_store 68 ; FNATTRS-LABEL: define {{[^@]+}}@test_store
48 ; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3:[0-9]+]] { 69 ; FNATTRS-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3:[0-9]+]] {
49 ; CHECK-NEXT: store i8 0, ptr [[P]], align 1 70 ; FNATTRS-NEXT: store i8 0, ptr [[P]], align 1
50 ; CHECK-NEXT: ret void 71 ; FNATTRS-NEXT: ret void
72 ;
73 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
74 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_store
75 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull writeonly [[P:%.*]]) #[[ATTR3:[0-9]+]] {
76 ; ATTRIBUTOR-NEXT: store i8 0, ptr [[P]], align 1
77 ; ATTRIBUTOR-NEXT: ret void
51 ; 78 ;
52 store i8 0, ptr %p 79 store i8 0, ptr %p
53 ret void 80 ret void
54 } 81 }
55 82
56 @G = external global ptr 83 @G = external global ptr
57 define i8 @test_store_capture(ptr %p) { 84 define i8 @test_store_capture(ptr %p) {
58 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 85 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none)
59 ; CHECK-LABEL: define {{[^@]+}}@test_store_capture 86 ; FNATTRS-LABEL: define {{[^@]+}}@test_store_capture
60 ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR4:[0-9]+]] { 87 ; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR4:[0-9]+]] {
61 ; CHECK-NEXT: store ptr [[P]], ptr @G, align 8 88 ; FNATTRS-NEXT: store ptr [[P]], ptr @G, align 8
62 ; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr @G, align 8 89 ; FNATTRS-NEXT: [[P2:%.*]] = load ptr, ptr @G, align 8
63 ; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P2]], align 1 90 ; FNATTRS-NEXT: [[V:%.*]] = load i8, ptr [[P2]], align 1
64 ; CHECK-NEXT: ret i8 [[V]] 91 ; FNATTRS-NEXT: ret i8 [[V]]
92 ;
93 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
94 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_store_capture
95 ; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]]) #[[ATTR4:[0-9]+]] {
96 ; ATTRIBUTOR-NEXT: store ptr [[P]], ptr @G, align 8
97 ; ATTRIBUTOR-NEXT: [[P2:%.*]] = load ptr, ptr @G, align 8
98 ; ATTRIBUTOR-NEXT: [[V:%.*]] = load i8, ptr [[P2]], align 1
99 ; ATTRIBUTOR-NEXT: ret i8 [[V]]
65 ; 100 ;
66 store ptr %p, ptr @G 101 store ptr %p, ptr @G
67 %p2 = load ptr, ptr @G 102 %p2 = load ptr, ptr @G
68 %v = load i8, ptr %p2 103 %v = load i8, ptr %p2
69 ret i8 %v 104 ret i8 %v
70 } 105 }
71 106
72 define void @test_addressing(ptr %p) { 107 define void @test_addressing(ptr %p) {
73 ; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly 108 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
74 ; CHECK-LABEL: define {{[^@]+}}@test_addressing 109 ; FNATTRS-LABEL: define {{[^@]+}}@test_addressing
75 ; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3]] { 110 ; FNATTRS-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3]] {
76 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8 111 ; FNATTRS-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8
77 ; CHECK-NEXT: store i32 0, ptr [[GEP]], align 4 112 ; FNATTRS-NEXT: store i32 0, ptr [[GEP]], align 4
78 ; CHECK-NEXT: ret void 113 ; FNATTRS-NEXT: ret void
114 ;
115 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
116 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_addressing
117 ; ATTRIBUTOR-SAME: (ptr nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] {
118 ; ATTRIBUTOR-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8
119 ; ATTRIBUTOR-NEXT: store i32 0, ptr [[GEP]], align 4
120 ; ATTRIBUTOR-NEXT: ret void
79 ; 121 ;
80 %gep = getelementptr i8, ptr %p, i64 8 122 %gep = getelementptr i8, ptr %p, i64 8
81 store i32 0, ptr %gep 123 store i32 0, ptr %gep
82 ret void 124 ret void
83 } 125 }
84 126
85 define void @test_readwrite(ptr %p) { 127 define void @test_readwrite(ptr %p) {
86 ; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn 128 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
87 ; CHECK-LABEL: define {{[^@]+}}@test_readwrite 129 ; FNATTRS-LABEL: define {{[^@]+}}@test_readwrite
88 ; CHECK-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR5:[0-9]+]] { 130 ; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR5:[0-9]+]] {
89 ; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1 131 ; FNATTRS-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1
90 ; CHECK-NEXT: store i8 [[V]], ptr [[P]], align 1 132 ; FNATTRS-NEXT: store i8 [[V]], ptr [[P]], align 1
91 ; CHECK-NEXT: ret void 133 ; FNATTRS-NEXT: ret void
134 ;
135 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
136 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_readwrite
137 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull [[P:%.*]]) #[[ATTR5:[0-9]+]] {
138 ; ATTRIBUTOR-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1
139 ; ATTRIBUTOR-NEXT: store i8 [[V]], ptr [[P]], align 1
140 ; ATTRIBUTOR-NEXT: ret void
92 ; 141 ;
93 %v = load i8, ptr %p 142 %v = load i8, ptr %p
94 store i8 %v, ptr %p 143 store i8 %v, ptr %p
95 ret void 144 ret void
96 } 145 }
97 146
98 define void @test_volatile(ptr %p) { 147 define void @test_volatile(ptr %p) {
99 ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind 148 ; FNATTRS: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite)
100 ; CHECK-LABEL: define {{[^@]+}}@test_volatile 149 ; FNATTRS-LABEL: define {{[^@]+}}@test_volatile
101 ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR6:[0-9]+]] { 150 ; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR6:[0-9]+]] {
102 ; CHECK-NEXT: store volatile i8 0, ptr [[P]], align 1 151 ; FNATTRS-NEXT: store volatile i8 0, ptr [[P]], align 1
103 ; CHECK-NEXT: ret void 152 ; FNATTRS-NEXT: ret void
153 ;
154 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
155 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_volatile
156 ; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]]) #[[ATTR6:[0-9]+]] {
157 ; ATTRIBUTOR-NEXT: store volatile i8 0, ptr [[P]], align 1
158 ; ATTRIBUTOR-NEXT: ret void
104 ; 159 ;
105 store volatile i8 0, ptr %p 160 store volatile i8 0, ptr %p
106 ret void 161 ret void
107 } 162 }
108 163
109 define void @test_atomicrmw(ptr %p) { 164 define void @test_atomicrmw(ptr %p) {
110 ; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn 165 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
111 ; CHECK-LABEL: define {{[^@]+}}@test_atomicrmw 166 ; FNATTRS-LABEL: define {{[^@]+}}@test_atomicrmw
112 ; CHECK-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR7:[0-9]+]] { 167 ; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR7:[0-9]+]] {
113 ; CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1 168 ; FNATTRS-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1
114 ; CHECK-NEXT: ret void 169 ; FNATTRS-NEXT: ret void
170 ;
171 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
172 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_atomicrmw
173 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull [[P:%.*]]) #[[ATTR6]] {
174 ; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1
175 ; ATTRIBUTOR-NEXT: ret void
115 ; 176 ;
116 atomicrmw add ptr %p, i8 0 seq_cst 177 atomicrmw add ptr %p, i8 0 seq_cst
117 ret void 178 ret void
118 } 179 }
119 180
120 181
121 declare void @direct1_callee(ptr %p) 182 declare void @direct1_callee(ptr %p)
122 183
123 define void @direct1(ptr %p) { 184 define void @direct1(ptr %p) {
124 ; CHECK-LABEL: define {{[^@]+}}@direct1 185 ; COMMON-LABEL: define {{[^@]+}}@direct1
125 ; CHECK-SAME: (ptr [[P:%.*]]) { 186 ; COMMON-SAME: (ptr [[P:%.*]]) {
126 ; CHECK-NEXT: call void @direct1_callee(ptr [[P]]) 187 ; COMMON-NEXT: call void @direct1_callee(ptr [[P]])
127 ; CHECK-NEXT: ret void 188 ; COMMON-NEXT: ret void
128 ; 189 ;
129 call void @direct1_callee(ptr %p) 190 call void @direct1_callee(ptr %p)
130 ret void 191 ret void
131 } 192 }
132 193
133 declare void @direct2_callee(ptr %p) writeonly 194 declare void @direct2_callee(ptr %p) writeonly
134 195
135 ; writeonly w/o nocapture is not enough 196 ; writeonly w/o nocapture is not enough
136 define void @direct2(ptr %p) { 197 define void @direct2(ptr %p) {
137 ; CHECK: Function Attrs: writeonly 198 ; FNATTRS: Function Attrs: memory(write)
138 ; CHECK-LABEL: define {{[^@]+}}@direct2 199 ; FNATTRS-LABEL: define {{[^@]+}}@direct2
139 ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR8:[0-9]+]] { 200 ; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR8:[0-9]+]] {
140 ; CHECK-NEXT: call void @direct2_callee(ptr [[P]]) 201 ; FNATTRS-NEXT: call void @direct2_callee(ptr [[P]])
141 ; CHECK-NEXT: ret void 202 ; FNATTRS-NEXT: ret void
203 ;
204 ; ATTRIBUTOR: Function Attrs: memory(write)
205 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@direct2
206 ; ATTRIBUTOR-SAME: (ptr writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] {
207 ; ATTRIBUTOR-NEXT: call void @direct2_callee(ptr [[P]]) #[[ATTR7]]
208 ; ATTRIBUTOR-NEXT: ret void
142 ; 209 ;
143 call void @direct2_callee(ptr %p) 210 call void @direct2_callee(ptr %p)
144 ; read back from global, read through pointer... 211 ; read back from global, read through pointer...
145 ret void 212 ret void
146 } 213 }
147 214
148 define void @direct2b(ptr %p) { 215 define void @direct2b(ptr %p) {
149 ; CHECK: Function Attrs: writeonly 216 ; FNATTRS: Function Attrs: memory(write)
150 ; CHECK-LABEL: define {{[^@]+}}@direct2b 217 ; FNATTRS-LABEL: define {{[^@]+}}@direct2b
151 ; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR8]] { 218 ; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR8]] {
152 ; CHECK-NEXT: call void @direct2_callee(ptr nocapture [[P]]) 219 ; FNATTRS-NEXT: call void @direct2_callee(ptr nocapture [[P]])
153 ; CHECK-NEXT: ret void 220 ; FNATTRS-NEXT: ret void
221 ;
222 ; ATTRIBUTOR: Function Attrs: memory(write)
223 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@direct2b
224 ; ATTRIBUTOR-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR7]] {
225 ; ATTRIBUTOR-NEXT: call void @direct2_callee(ptr nocapture writeonly [[P]]) #[[ATTR7]]
226 ; ATTRIBUTOR-NEXT: ret void
154 ; 227 ;
155 call void @direct2_callee(ptr nocapture %p) 228 call void @direct2_callee(ptr nocapture %p)
156 ret void 229 ret void
157 } 230 }
158 231
159 declare void @direct3_callee(ptr nocapture writeonly %p) 232 declare void @direct3_callee(ptr nocapture writeonly %p)
160 233
161 define void @direct3(ptr %p) { 234 define void @direct3(ptr %p) {
162 ; CHECK-LABEL: define {{[^@]+}}@direct3 235 ; FNATTRS-LABEL: define {{[^@]+}}@direct3
163 ; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) { 236 ; FNATTRS-SAME: (ptr nocapture writeonly [[P:%.*]]) {
164 ; CHECK-NEXT: call void @direct3_callee(ptr [[P]]) 237 ; FNATTRS-NEXT: call void @direct3_callee(ptr [[P]])
165 ; CHECK-NEXT: ret void 238 ; FNATTRS-NEXT: ret void
239 ;
240 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@direct3
241 ; ATTRIBUTOR-SAME: (ptr nocapture writeonly [[P:%.*]]) {
242 ; ATTRIBUTOR-NEXT: call void @direct3_callee(ptr nocapture writeonly [[P]])
243 ; ATTRIBUTOR-NEXT: ret void
166 ; 244 ;
167 call void @direct3_callee(ptr %p) 245 call void @direct3_callee(ptr %p)
168 ret void 246 ret void
169 } 247 }
170 248
171 define void @direct3b(ptr %p) { 249 define void @direct3b(ptr %p) {
172 ; CHECK-LABEL: define {{[^@]+}}@direct3b 250 ; COMMON-LABEL: define {{[^@]+}}@direct3b
173 ; CHECK-SAME: (ptr [[P:%.*]]) { 251 ; COMMON-SAME: (ptr [[P:%.*]]) {
174 ; CHECK-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read-and-capture"(ptr [[P]]) ] 252 ; COMMON-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read-and-capture"(ptr [[P]]) ]
175 ; CHECK-NEXT: ret void 253 ; COMMON-NEXT: ret void
176 ; 254 ;
177 call void @direct3_callee(ptr %p) ["may-read-and-capture"(ptr %p)] 255 call void @direct3_callee(ptr %p) ["may-read-and-capture"(ptr %p)]
178 ret void 256 ret void
179 } 257 }
180 258
181 define void @direct3c(ptr %p) { 259 define void @direct3c(ptr %p) {
182 ; CHECK-LABEL: define {{[^@]+}}@direct3c 260 ; FNATTRS-LABEL: define {{[^@]+}}@direct3c
183 ; CHECK-SAME: (ptr nocapture [[P:%.*]]) { 261 ; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) {
184 ; CHECK-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read"() ] 262 ; FNATTRS-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read"() ]
185 ; CHECK-NEXT: ret void 263 ; FNATTRS-NEXT: ret void
264 ;
265 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@direct3c
266 ; ATTRIBUTOR-SAME: (ptr nocapture [[P:%.*]]) {
267 ; ATTRIBUTOR-NEXT: call void @direct3_callee(ptr nocapture [[P]]) [ "may-read"() ]
268 ; ATTRIBUTOR-NEXT: ret void
186 ; 269 ;
187 call void @direct3_callee(ptr %p) ["may-read"()] 270 call void @direct3_callee(ptr %p) ["may-read"()]
188 ret void 271 ret void
189 } 272 }
190 273
191 define void @fptr_test1(ptr %p, ptr %f) { 274 define void @fptr_test1(ptr %p, ptr %f) {
192 ; CHECK-LABEL: define {{[^@]+}}@fptr_test1 275 ; FNATTRS-LABEL: define {{[^@]+}}@fptr_test1
193 ; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[F:%.*]]) { 276 ; FNATTRS-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[F:%.*]]) {
194 ; CHECK-NEXT: call void [[F]](ptr [[P]]) 277 ; FNATTRS-NEXT: call void [[F]](ptr [[P]])
195 ; CHECK-NEXT: ret void 278 ; FNATTRS-NEXT: ret void
279 ;
280 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test1
281 ; ATTRIBUTOR-SAME: (ptr [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
282 ; ATTRIBUTOR-NEXT: call void [[F]](ptr [[P]])
283 ; ATTRIBUTOR-NEXT: ret void
196 ; 284 ;
197 call void %f(ptr %p) 285 call void %f(ptr %p)
198 ret void 286 ret void
199 } 287 }
200 288
201 define void @fptr_test2(ptr %p, ptr %f) { 289 define void @fptr_test2(ptr %p, ptr %f) {
202 ; CHECK-LABEL: define {{[^@]+}}@fptr_test2 290 ; FNATTRS-LABEL: define {{[^@]+}}@fptr_test2
203 ; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) { 291 ; FNATTRS-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) {
204 ; CHECK-NEXT: call void [[F]](ptr nocapture writeonly [[P]]) 292 ; FNATTRS-NEXT: call void [[F]](ptr nocapture writeonly [[P]])
205 ; CHECK-NEXT: ret void 293 ; FNATTRS-NEXT: ret void
294 ;
295 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test2
296 ; ATTRIBUTOR-SAME: (ptr nocapture [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
297 ; ATTRIBUTOR-NEXT: call void [[F]](ptr nocapture writeonly [[P]])
298 ; ATTRIBUTOR-NEXT: ret void
206 ; 299 ;
207 call void %f(ptr nocapture writeonly %p) 300 call void %f(ptr nocapture writeonly %p)
208 ret void 301 ret void
209 } 302 }
210 303
211 define void @fptr_test3(ptr %p, ptr %f) { 304 define void @fptr_test3(ptr %p, ptr %f) {
212 ; CHECK: Function Attrs: writeonly 305 ; FNATTRS: Function Attrs: memory(write)
213 ; CHECK-LABEL: define {{[^@]+}}@fptr_test3 306 ; FNATTRS-LABEL: define {{[^@]+}}@fptr_test3
214 ; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR8]] { 307 ; FNATTRS-SAME: (ptr nocapture [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR8]] {
215 ; CHECK-NEXT: call void [[F]](ptr nocapture [[P]]) #[[ATTR8]] 308 ; FNATTRS-NEXT: call void [[F]](ptr nocapture [[P]]) #[[ATTR8]]
216 ; CHECK-NEXT: ret void 309 ; FNATTRS-NEXT: ret void
310 ;
311 ; ATTRIBUTOR: Function Attrs: memory(write)
312 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test3
313 ; ATTRIBUTOR-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture nofree nonnull writeonly [[F:%.*]]) #[[ATTR7]] {
314 ; ATTRIBUTOR-NEXT: call void [[F]](ptr nocapture [[P]]) #[[ATTR7]]
315 ; ATTRIBUTOR-NEXT: ret void
217 ; 316 ;
218 call void %f(ptr nocapture %p) writeonly 317 call void %f(ptr nocapture %p) writeonly
219 ret void 318 ret void
220 } 319 }