llvm.org GIT mirror llvm / ee7970e
Add InaccessibleMemOnly and inaccessibleMemOrArgMemOnly attributes Summary: This patch introduces two new function attributes InaccessibleMemOnly: This attribute indicates that the function may only access memory that is not accessible by the program/IR being compiled. This is a weaker form of ReadNone. inaccessibleMemOrArgMemOnly: This attribute indicates that the function may only access memory that is either not accessible by the program/IR being compiled, or is pointed to by its pointer arguments. This is a weaker form of ArgMemOnly Test cases have been updated. This revision uses this (https://github.com/llvm-mirror/llvm/commit/d001932f3a8aa1ebd1555162fdce365f011bc292) as reference. Reviewers: jmolloy, hfinkel Subscribers: reames, joker.eph, llvm-commits Differential Revision: http://reviews.llvm.org/D15499 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255778 91177308-0d34-0410-b5e6-96231b3b80d8 Vaivaswatha Nagaraj 4 years ago
19 changed file(s) with 105 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
12421242 thread execution pattern under certain parallel execution models.
12431243 Transformations that are execution model agnostic may not make the execution
12441244 of a convergent operation control dependent on any additional values.
1245 ``inaccessiblememonly``
1246 This attribute indicates that the function may only access memory that
1247 is not accessible by the module being compiled. This is a weaker form
1248 of ``readnone``.
1249 ``inaccessiblemem_or_argmemonly``
1250 This attribute indicates that the function may only access memory that is
1251 either not accessible by the module being compiled, or is pointed to
1252 by its pointer arguments. This is a weaker form of ``argmemonly``
12451253 ``inlinehint``
12461254 This attribute indicates that the source code contained a hint that
12471255 inlining this function is desirable (such as the "inline" keyword in
482482 ATTR_KIND_ARGMEMONLY = 45,
483483 ATTR_KIND_SWIFT_SELF = 46,
484484 ATTR_KIND_SWIFT_ERROR = 47,
485 ATTR_KIND_NO_RECURSE = 48
485 ATTR_KIND_NO_RECURSE = 48,
486 ATTR_KIND_INACCESSIBLEMEM_ONLY = 49,
487 ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50
486488 };
487489
488490 enum ComdatSelectionKindCodes {
3939
4040 /// Pointer is either null or dereferenceable.
4141 def DereferenceableOrNull : EnumAttr<"dereferenceable_or_null">;
42
43 /// Function may only access memory that is inaccessible from IR.
44 def InaccessibleMemOnly : EnumAttr<"inaccessiblememonly">;
45
46 /// Function may only access memory that is either inaccessible from the IR,
47 /// or pointed to by its pointer arguments.
48 def InaccessibleMemOrArgMemOnly : EnumAttr<"inaccessiblemem_or_argmemonly">;
4249
4350 /// Pass structure in an alloca.
4451 def InAlloca : EnumAttr<"inalloca">;
292292 }
293293 void setOnlyAccessesArgMemory() { addFnAttr(Attribute::ArgMemOnly); }
294294
295 /// @brief Determine if the function may only access memory that is
296 /// inaccessible from the IR.
297 bool onlyAccessesInaccessibleMemory() const {
298 return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
299 Attribute::InaccessibleMemOnly);
300 }
301 void setOnlyAccessesInaccessibleMemory() {
302 addFnAttr(Attribute::InaccessibleMemOnly);
303 }
304
305 /// @brief Determine if the function may only access memory that is
306 // either inaccessible from the IR or pointed to by its arguments.
307 bool onlyAccessesInaccessibleMemOrArgMem() const {
308 return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
309 Attribute::InaccessibleMemOrArgMemOnly);
310 }
311 void setOnlyAccessesInaccessibleMemOrArgMem() {
312 addFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
313 }
314
295315 /// @brief Determine if the function cannot return.
296316 bool doesNotReturn() const {
297317 return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
608608 KEYWORD(convergent);
609609 KEYWORD(dereferenceable);
610610 KEYWORD(dereferenceable_or_null);
611 KEYWORD(inaccessiblememonly);
612 KEYWORD(inaccessiblemem_or_argmemonly);
611613 KEYWORD(inlinehint);
612614 KEYWORD(inreg);
613615 KEYWORD(jumptable);
994994 case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
995995 case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
996996 case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break;
997 case lltok::kw_inaccessiblememonly:
998 B.addAttribute(Attribute::InaccessibleMemOnly); break;
999 case lltok::kw_inaccessiblemem_or_argmemonly:
1000 B.addAttribute(Attribute::InaccessibleMemOrArgMemOnly); break;
9971001 case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
9981002 case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
9991003 case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
114114 kw_convergent,
115115 kw_dereferenceable,
116116 kw_dereferenceable_or_null,
117 kw_inaccessiblememonly,
118 kw_inaccessiblemem_or_argmemonly,
117119 kw_inlinehint,
118120 kw_inreg,
119121 kw_jumptable,
12291229 return Attribute::Cold;
12301230 case bitc::ATTR_KIND_CONVERGENT:
12311231 return Attribute::Convergent;
1232 case bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY:
1233 return Attribute::InaccessibleMemOnly;
1234 case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY:
1235 return Attribute::InaccessibleMemOrArgMemOnly;
12321236 case bitc::ATTR_KIND_INLINE_HINT:
12331237 return Attribute::InlineHint;
12341238 case bitc::ATTR_KIND_IN_REG:
177177 return bitc::ATTR_KIND_IN_ALLOCA;
178178 case Attribute::Cold:
179179 return bitc::ATTR_KIND_COLD;
180 case Attribute::InaccessibleMemOnly:
181 return bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY;
182 case Attribute::InaccessibleMemOrArgMemOnly:
183 return bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY;
180184 case Attribute::InlineHint:
181185 return bitc::ATTR_KIND_INLINE_HINT;
182186 case Attribute::InReg:
197197 return "byval";
198198 if (hasAttribute(Attribute::Convergent))
199199 return "convergent";
200 if (hasAttribute(Attribute::InaccessibleMemOnly))
201 return "inaccessiblememonly";
202 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
203 return "inaccessiblemem_or_argmemonly";
200204 if (hasAttribute(Attribute::InAlloca))
201205 return "inalloca";
202206 if (hasAttribute(Attribute::InlineHint))
444448 case Attribute::Convergent: return 1ULL << 46;
445449 case Attribute::SafeStack: return 1ULL << 47;
446450 case Attribute::NoRecurse: return 1ULL << 48;
451 case Attribute::InaccessibleMemOnly: return 1ULL << 49;
452 case Attribute::InaccessibleMemOrArgMemOnly: return 1ULL << 50;
447453 case Attribute::Dereferenceable:
448454 llvm_unreachable("dereferenceable attribute not supported in raw format");
449455 break;
12501250 I->getKindAsEnum() == Attribute::JumpTable ||
12511251 I->getKindAsEnum() == Attribute::Convergent ||
12521252 I->getKindAsEnum() == Attribute::ArgMemOnly ||
1253 I->getKindAsEnum() == Attribute::NoRecurse) {
1253 I->getKindAsEnum() == Attribute::NoRecurse ||
1254 I->getKindAsEnum() == Attribute::InaccessibleMemOnly ||
1255 I->getKindAsEnum() == Attribute::InaccessibleMemOrArgMemOnly) {
12541256 if (!isFunction) {
12551257 CheckFailed("Attribute '" + I->getAsString() +
12561258 "' only applies to functions!", V);
14191421 !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) &&
14201422 Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly)),
14211423 "Attributes 'readnone and readonly' are incompatible!", V);
1424
1425 Assert(
1426 !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) &&
1427 Attrs.hasAttribute(AttributeSet::FunctionIndex,
1428 Attribute::InaccessibleMemOrArgMemOnly)),
1429 "Attributes 'readnone and inaccessiblemem_or_argmemonly' are incompatible!", V);
1430
1431 Assert(
1432 !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) &&
1433 Attrs.hasAttribute(AttributeSet::FunctionIndex,
1434 Attribute::InaccessibleMemOnly)),
1435 "Attributes 'readnone and inaccessiblememonly' are incompatible!", V);
14221436
14231437 Assert(
14241438 !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::NoInline) &&
0 ; RUN: not llvm-c-test --module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
11
2 CHECK: Error parsing bitcode: Unknown attribute kind (50)
2 CHECK: Error parsing bitcode: Unknown attribute kind (52)
203203 ; CHECK: define void @f34()
204204 {
205205 call void @nobuiltin() nobuiltin
206 ; CHECK: call void @nobuiltin() #28
206 ; CHECK: call void @nobuiltin() #30
207207 ret void;
208208 }
209209
273273
274274 ; CHECK: define void @f47() #27
275275 define void @f47() norecurse {
276 ret void
277 }
278
279 ; CHECK: define void @f48() #28
280 define void @f48() inaccessiblememonly {
281 ret void
282 }
283
284 ; CHECK: define void @f49() #29
285 define void @f49() inaccessiblemem_or_argmemonly {
276286 ret void
277287 }
278288
304314 ; CHECK: attributes #25 = { convergent }
305315 ; CHECK: attributes #26 = { argmemonly }
306316 ; CHECK: attributes #27 = { norecurse }
307 ; CHECK: attributes #28 = { nobuiltin }
317 ; CHECK: attributes #28 = { inaccessiblememonly }
318 ; CHECK: attributes #29 = { inaccessiblemem_or_argmemonly }
319 ; CHECK: attributes #30 = { nobuiltin }
502502 ; CHECK:declare void @f.kvpair() #31
503503 declare void @f.norecurse() norecurse
504504 ; CHECK: declare void @f.norecurse() #32
505 declare void @f.inaccessiblememonly() inaccessiblememonly
506 ; CHECK: declare void @f.inaccessiblememonly() #33
507 declare void @f.inaccessiblemem_or_argmemonly() inaccessiblemem_or_argmemonly
508 ; CHECK: declare void @f.inaccessiblemem_or_argmemonly() #34
505509
506510 ; Functions -- section
507511 declare void @f.section() section "80"
560564
561565 ; Functions -- Personality constant
562566 declare void @llvm.donothing() nounwind readnone
563 ; CHECK: declare void @llvm.donothing() #33
567 ; CHECK: declare void @llvm.donothing() #35
564568 define void @f.no_personality() personality i8 3 {
565569 ; CHECK: define void @f.no_personality() personality i8 3
566570 invoke void @llvm.donothing() to label %normal unwind label %exception
11351139 ; CHECK: select <2 x i1> , <2 x i8> , <2 x i8>
11361140
11371141 call void @f.nobuiltin() builtin
1138 ; CHECK: call void @f.nobuiltin() #37
1142 ; CHECK: call void @f.nobuiltin() #39
11391143
11401144 call fastcc noalias i32* @f.noalias() noinline
11411145 ; CHECK: call fastcc noalias i32* @f.noalias() #12
15151519 ; CHECK: attributes #30 = { uwtable }
15161520 ; CHECK: attributes #31 = { "cpu"="cortex-a8" }
15171521 ; CHECK: attributes #32 = { norecurse }
1518 ; CHECK: attributes #33 = { nounwind readnone }
1519 ; CHECK: attributes #34 = { argmemonly nounwind readonly }
1520 ; CHECK: attributes #35 = { argmemonly nounwind }
1521 ; CHECK: attributes #36 = { nounwind readonly }
1522 ; CHECK: attributes #37 = { builtin }
1522 ; CHECK: attributes #33 = { inaccessiblememonly }
1523 ; CHECK: attributes #34 = { inaccessiblemem_or_argmemonly }
1524 ; CHECK: attributes #35 = { nounwind readnone }
1525 ; CHECK: attributes #36 = { argmemonly nounwind readonly }
1526 ; CHECK: attributes #37 = { argmemonly nounwind }
1527 ; CHECK: attributes #38 = { nounwind readonly }
1528 ; CHECK: attributes #39 = { builtin }
15231529
15241530 ;; Metadata
15251531
0 ; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s
11
2 ; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (50)
2 ; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (52)
33
44 ; invalid.ll.bc has an invalid attribute number.
55 ; The test checks that LLVM reports the error and doesn't access freed memory
Binary diff not shown
0 ; RUN: not llvm-lto %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
11
22
3 ; CHECK: llvm-lto{{.*}}: error loading file '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (50)
3 ; CHECK: llvm-lto{{.*}}: error loading file '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (52)