llvm.org GIT mirror llvm / b07f540
Add writeonly IR attribute Summary: This complements the earlier addition of IntrWriteMem and IntrWriteArgMem LLVM intrinsic properties, see D18291. Also start using the attribute for memset, memcpy, and memmove intrinsics, and remove their special-casing in BasicAliasAnalysis. Reviewers: reames, joker.eph Subscribers: joker.eph, llvm-commits Differential Revision: http://reviews.llvm.org/D18714 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274485 91177308-0d34-0410-b5e6-96231b3b80d8 Nicolai Haehnle 4 years ago
30 changed file(s) with 197 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
14731473 On an argument, this attribute indicates that the function does not write
14741474 through this pointer argument, even though it may write to the memory that
14751475 the pointer points to.
1476 ``writeonly``
1477 On a function, this attribute indicates that the function may write to but
1478 does not read from memory.
1479
1480 On an argument, this attribute indicates that the function may write to but
1481 does not read through this pointer argument (even though it may read from
1482 the memory that the pointer points to).
14761483 ``argmemonly``
14771484 This attribute indicates that the only memory accesses inside function are
14781485 loads and stores from objects pointed to by its pointer-typed arguments,
150150 /// This property corresponds to the IntrReadMem LLVM intrinsic flag.
151151 FMRB_OnlyReadsMemory = FMRL_Anywhere | MRI_Ref,
152152
153 // This function does not read from memory anywhere, but may write to any
154 // memory location.
155 //
156 // This property corresponds to the LLVM IR 'writeonly' attribute.
157 // This property corresponds to the IntrWriteMem LLVM intrinsic flag.
158 FMRB_DoesNotReadMemory = FMRL_Anywhere | MRI_Mod,
159
153160 /// This indicates that the function could not be classified into one of the
154161 /// behaviors above.
155162 FMRB_UnknownModRefBehavior = FMRL_Anywhere | MRI_ModRef
309316 /// from non-volatile memory (or not access memory at all).
310317 static bool onlyReadsMemory(FunctionModRefBehavior MRB) {
311318 return !(MRB & MRI_Mod);
319 }
320
321 /// Checks if functions with the specified behavior are known to only write
322 /// memory (or not access memory at all).
323 static bool doesNotReadMemory(FunctionModRefBehavior MRB) {
324 return !(MRB & MRI_Ref);
312325 }
313326
314327 /// Checks if functions with the specified behavior are known to read and
520520 ATTR_KIND_NO_RECURSE = 48,
521521 ATTR_KIND_INACCESSIBLEMEM_ONLY = 49,
522522 ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50,
523 ATTR_KIND_ALLOC_SIZE = 51
523 ATTR_KIND_ALLOC_SIZE = 51,
524 ATTR_KIND_WRITEONLY = 52
524525 };
525526
526527 enum ComdatSelectionKindCodes {
165165
166166 /// Function must be in a unwind table.
167167 def UWTable : EnumAttr<"uwtable">;
168
169 /// Function only writes to memory.
170 def WriteOnly : EnumAttr<"writeonly">;
168171
169172 /// Zero extended before/after call.
170173 def ZExt : EnumAttr<"zeroext">;
416416 CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
417417 }
418418
419 /// @brief Determine if the call does not access or only writes memory.
420 bool doesNotReadMemory() const {
421 CALLSITE_DELEGATE_GETTER(doesNotReadMemory());
422 }
423 void setDoesNotReadMemory() {
424 CALLSITE_DELEGATE_SETTER(setDoesNotReadMemory());
425 }
426
419427 /// @brief Determine if the call can access memmory only using pointers based
420428 /// on its arguments.
421429 bool onlyAccessesArgMemory() const {
297297 addFnAttr(Attribute::ReadOnly);
298298 }
299299
300 /// @brief Determine if the function does not access or only writes memory.
301 bool doesNotReadMemory() const {
302 return doesNotAccessMemory() || hasFnAttribute(Attribute::WriteOnly);
303 }
304 void setDoesNotReadMemory() {
305 addFnAttr(Attribute::WriteOnly);
306 }
307
300308 /// @brief Determine if the call can access memmory only using pointers based
301309 /// on its arguments.
302310 bool onlyAccessesArgMemory() const {
17381738 addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
17391739 }
17401740
1741 /// \brief Determine if the call does not access or only writes memory.
1742 bool doesNotReadMemory() const {
1743 return doesNotAccessMemory() || hasFnAttr(Attribute::WriteOnly);
1744 }
1745 void setDoesNotReadMemory() {
1746 addAttribute(AttributeSet::FunctionIndex, Attribute::WriteOnly);
1747 }
1748
17411749 /// @brief Determine if the call can access memmory only using pointers based
17421750 /// on its arguments.
17431751 bool onlyAccessesArgMemory() const {
36903698 addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
36913699 }
36923700
3701 /// \brief Determine if the call does not access or only writes memory.
3702 bool doesNotReadMemory() const {
3703 return doesNotAccessMemory() || hasFnAttr(Attribute::WriteOnly);
3704 }
3705 void setDoesNotReadMemory() {
3706 addAttribute(AttributeSet::FunctionIndex, Attribute::WriteOnly);
3707 }
3708
36933709 /// @brief Determine if the call access memmory only using it's pointer
36943710 /// arguments.
36953711 bool onlyAccessesArgMemory() const {
5656 // ReadOnly - The specified argument pointer is not written to through the
5757 // pointer by the intrinsic.
5858 class ReadOnly : IntrinsicProperty {
59 int ArgNo = argNo;
60 }
61
62 // WriteOnly - The intrinsic does not read memory through the specified
63 // argument pointer.
64 class WriteOnly : IntrinsicProperty {
5965 int ArgNo = argNo;
6066 }
6167
348354 [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
349355 llvm_i32_ty, llvm_i1_ty],
350356 [IntrArgMemOnly, NoCapture<0>, NoCapture<1>,
351 ReadOnly<1>]>;
357 WriteOnly<0>, ReadOnly<1>]>;
352358 def int_memmove : Intrinsic<[],
353359 [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
354360 llvm_i32_ty, llvm_i1_ty],
357363 def int_memset : Intrinsic<[],
358364 [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
359365 llvm_i32_ty, llvm_i1_ty],
360 [IntrArgMemOnly, NoCapture<0>]>;
366 [IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>;
361367
362368 let IntrProperties = [IntrNoMem] in {
363369 def int_fma : Intrinsic<[llvm_anyfloat_ty],
141141
142142 if (onlyReadsMemory(MRB))
143143 Result = ModRefInfo(Result & MRI_Ref);
144 else if (doesNotReadMemory(MRB))
145 Result = ModRefInfo(Result & MRI_Mod);
144146
145147 if (onlyAccessesArgPointees(MRB)) {
146148 bool DoesAlias = false;
206208 // from CS1 reading memory written by CS2.
207209 if (onlyReadsMemory(CS1B))
208210 Result = ModRefInfo(Result & MRI_Ref);
211 else if (doesNotReadMemory(CS1B))
212 Result = ModRefInfo(Result & MRI_Mod);
209213
210214 // If CS2 only access memory through arguments, accumulate the mod/ref
211215 // information from CS1's references to the memory referenced by
562562 // than that.
563563 if (CS.onlyReadsMemory())
564564 Min = FMRB_OnlyReadsMemory;
565 else if (CS.doesNotReadMemory())
566 Min = FMRB_DoesNotReadMemory;
565567
566568 if (CS.onlyAccessesArgMemory())
567569 Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
589591 // If the function declares it only reads memory, go with that.
590592 if (F->onlyReadsMemory())
591593 Min = FMRB_OnlyReadsMemory;
594 else if (F->doesNotReadMemory())
595 Min = FMRB_DoesNotReadMemory;
592596
593597 if (F->onlyAccessesArgMemory())
594598 Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
596600 return Min;
597601 }
598602
599 /// Returns true if this is a writeonly (i.e Mod only) parameter. Currently,
600 /// we don't have a writeonly attribute, so this only knows about builtin
601 /// intrinsics and target library functions. We could consider adding a
602 /// writeonly attribute in the future and moving all of these facts to either
603 /// Intrinsics.td or InferFunctionAttr.cpp
603 /// Returns true if this is a writeonly (i.e Mod only) parameter.
604604 static bool isWriteOnlyParam(ImmutableCallSite CS, unsigned ArgIdx,
605605 const TargetLibraryInfo &TLI) {
606 if (const IntrinsicInst *II = dyn_cast(CS.getInstruction()))
607 switch (II->getIntrinsicID()) {
608 default:
609 break;
610 case Intrinsic::memset:
611 case Intrinsic::memcpy:
612 case Intrinsic::memmove:
613 // We don't currently have a writeonly attribute. All other properties
614 // of these intrinsics are nicely described via attributes in
615 // Intrinsics.td and handled generically.
616 if (ArgIdx == 0)
617 return true;
618 }
606 if (CS.paramHasAttr(ArgIdx + 1, Attribute::WriteOnly))
607 return true;
619608
620609 // We can bound the aliasing properties of memset_pattern16 just as we can
621610 // for memcpy/memset. This is particularly important because the
622611 // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
623 // whenever possible. Note that all but the missing writeonly attribute are
624 // handled via InferFunctionAttr.
612 // whenever possible.
613 // FIXME Consider handling this in InferFunctionAttr.cpp together with other
614 // attributes.
625615 LibFunc::Func F;
626616 if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) &&
627617 F == LibFunc::memset_pattern16 && TLI.has(F))
638628 ModRefInfo BasicAAResult::getArgModRefInfo(ImmutableCallSite CS,
639629 unsigned ArgIdx) {
640630
641 // Emulate the missing writeonly attribute by checking for known builtin
642 // intrinsics and target library functions.
631 // Checking for known builtin intrinsics and target library functions.
643632 if (isWriteOnlyParam(CS, ArgIdx, TLI))
644633 return MRI_Mod;
645634
659659 KEYWORD(swifterror);
660660 KEYWORD(swiftself);
661661 KEYWORD(uwtable);
662 KEYWORD(writeonly);
662663 KEYWORD(zeroext);
663664
664665 KEYWORD(type);
10971097 case lltok::kw_sanitize_memory:
10981098 B.addAttribute(Attribute::SanitizeMemory); break;
10991099 case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
1100 case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break;
11001101
11011102 // Error handling.
11021103 case lltok::kw_inreg:
13931394 case lltok::kw_sret: B.addAttribute(Attribute::StructRet); break;
13941395 case lltok::kw_swifterror: B.addAttribute(Attribute::SwiftError); break;
13951396 case lltok::kw_swiftself: B.addAttribute(Attribute::SwiftSelf); break;
1397 case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break;
13961398 case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
13971399
13981400 case lltok::kw_alignstack:
204204 kw_swifterror,
205205 kw_swiftself,
206206 kw_uwtable,
207 kw_writeonly,
207208 kw_zeroext,
208209
209210 kw_type,
14631463 return Attribute::SwiftSelf;
14641464 case bitc::ATTR_KIND_UW_TABLE:
14651465 return Attribute::UWTable;
1466 case bitc::ATTR_KIND_WRITEONLY:
1467 return Attribute::WriteOnly;
14661468 case bitc::ATTR_KIND_Z_EXT:
14671469 return Attribute::ZExt;
14681470 }
666666 return bitc::ATTR_KIND_SWIFT_SELF;
667667 case Attribute::UWTable:
668668 return bitc::ATTR_KIND_UW_TABLE;
669 case Attribute::WriteOnly:
670 return bitc::ATTR_KIND_WRITEONLY;
669671 case Attribute::ZExt:
670672 return bitc::ATTR_KIND_Z_EXT;
671673 case Attribute::EndAttrKinds:
291291 return "readnone";
292292 if (hasAttribute(Attribute::ReadOnly))
293293 return "readonly";
294 if (hasAttribute(Attribute::WriteOnly))
295 return "writeonly";
294296 if (hasAttribute(Attribute::Returned))
295297 return "returned";
296298 if (hasAttribute(Attribute::ReturnsTwice))
515517 case Attribute::InaccessibleMemOrArgMemOnly: return 1ULL << 50;
516518 case Attribute::SwiftSelf: return 1ULL << 51;
517519 case Attribute::SwiftError: return 1ULL << 52;
520 case Attribute::WriteOnly: return 1ULL << 53;
518521 case Attribute::Dereferenceable:
519522 llvm_unreachable("dereferenceable attribute not supported in raw format");
520523 break;
13081308 return;
13091309 }
13101310 } else if (I->getKindAsEnum() == Attribute::ReadOnly ||
1311 I->getKindAsEnum() == Attribute::WriteOnly ||
13111312 I->getKindAsEnum() == Attribute::ReadNone) {
13121313 if (Idx == 0) {
13131314 CheckFailed("Attribute '" + I->getAsString() +
13811382 "'readnone and readonly' are incompatible!",
13821383 V);
13831384
1385 Assert(!(Attrs.hasAttribute(Idx, Attribute::ReadNone) &&
1386 Attrs.hasAttribute(Idx, Attribute::WriteOnly)),
1387 "Attributes "
1388 "'readnone and writeonly' are incompatible!",
1389 V);
1390
1391 Assert(!(Attrs.hasAttribute(Idx, Attribute::ReadOnly) &&
1392 Attrs.hasAttribute(Idx, Attribute::WriteOnly)),
1393 "Attributes "
1394 "'readonly and writeonly' are incompatible!",
1395 V);
1396
13841397 Assert(!(Attrs.hasAttribute(Idx, Attribute::NoInline) &&
13851398 Attrs.hasAttribute(Idx, Attribute::AlwaysInline)),
13861399 "Attributes "
14951508 !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) &&
14961509 Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly)),
14971510 "Attributes 'readnone and readonly' are incompatible!", V);
1511
1512 Assert(
1513 !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) &&
1514 Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::WriteOnly)),
1515 "Attributes 'readnone and writeonly' are incompatible!", V);
1516
1517 Assert(
1518 !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly) &&
1519 Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::WriteOnly)),
1520 "Attributes 'readonly and writeonly' are incompatible!", V);
14981521
14991522 Assert(
15001523 !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) &&
88 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
99
1010 declare void @a_readonly_func(i8 *) noinline nounwind readonly
11 declare void @a_writeonly_func(i8 *) noinline nounwind writeonly
1112
1213 define <8 x i16> @test1(i8* %p, <8 x i16> %y) {
1314 entry:
2122 ; CHECK-LABEL: Function: test1:
2223
2324 ; CHECK: NoAlias: i8* %p, i8* %q
24 ; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
25 ; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
25 ; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
26 ; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
2627 ; CHECK: NoModRef: Ptr: i8* %p <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
2728 ; CHECK: Both ModRef: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
28 ; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
29 ; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
30 ; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
31 ; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
32 ; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
33 ; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
34 ; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
35 ; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
29 ; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
30 ; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
31 ; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
32 ; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
33 ; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
34 ; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
35 ; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
36 ; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
3637 }
3738
3839 define void @test2(i8* %P, i8* %Q) nounwind ssp {
232233 ; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i32 8, i1 false)
233234 }
234235
235 attributes #0 = { nounwind readonly argmemonly }
236 attributes #1 = { nounwind argmemonly }
236 define void @test7(i8* %P) nounwind ssp {
237 call void @a_writeonly_func(i8* %P)
238 call void @a_readonly_func(i8* %P)
239 ret void
240
241 ; CHECK-LABEL: Function: test7:
242
243 ; CHECK: Just Mod: Ptr: i8* %P <-> call void @a_writeonly_func(i8* %P)
244 ; CHECK: Just Ref: Ptr: i8* %P <-> call void @a_readonly_func(i8* %P)
245 ; CHECK: Just Mod: call void @a_writeonly_func(i8* %P) <-> call void @a_readonly_func(i8* %P)
246 ; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @a_writeonly_func(i8* %P)
247 }
248
249 attributes #0 = { argmemonly nounwind readonly }
250 attributes #1 = { argmemonly nounwind }
237251 attributes #2 = { noinline nounwind readonly }
238 attributes #3 = { nounwind ssp }
239 attributes #4 = { nounwind }
240
252 attributes #3 = { noinline nounwind writeonly }
253 attributes #4 = { nounwind ssp }
254 attributes #5 = { nounwind }
255
0 ; RUN: not llvm-c-test --module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
11 ; RUN: not llvm-c-test --lazy-module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
22
3 CHECK: Error parsing bitcode: Unknown attribute kind (52)
3 CHECK: Error parsing bitcode: Unknown attribute kind (63)
44
55
66 ; RUN: not llvm-c-test --new-module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck --check-prefix=NEW %s
77 ; RUN: not llvm-c-test --lazy-new-module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck --check-prefix=NEW %s
88
9 NEW: Error with new bitcode parser: Unknown attribute kind (52)
9 NEW: Error with new bitcode parser: Unknown attribute kind (63)
1010
1111 ; RUN: llvm-c-test --test-diagnostic-handler < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck --check-prefix=DIAGNOSTIC %s
1212
203203 ; CHECK: define void @f34()
204204 {
205205 call void @nobuiltin() nobuiltin
206 ; CHECK: call void @nobuiltin() #32
206 ; CHECK: call void @nobuiltin() #33
207207 ret void;
208208 }
209209
325325 ; CHECK: define i8* @f55(i32, i32) #31
326326 define i8* @f55(i32, i32) allocsize(0, 1) {
327327 ret i8* null
328 }
329
330 ; CHECK: define void @f56() #32
331 define void @f56() writeonly
332 {
333 ret void
328334 }
329335
330336 ; CHECK: attributes #0 = { noreturn }
359365 ; CHECK: attributes #29 = { inaccessiblemem_or_argmemonly }
360366 ; CHECK: attributes #30 = { allocsize(0) }
361367 ; CHECK: attributes #31 = { allocsize(0,1) }
362 ; CHECK: attributes #32 = { nobuiltin }
368 ; CHECK: attributes #32 = { writeonly }
369 ; CHECK: attributes #33 = { nobuiltin }
12431243 ; CHECK: select <2 x i1> , <2 x i8> , <2 x i8>
12441244
12451245 call void @f.nobuiltin() builtin
1246 ; CHECK: call void @f.nobuiltin() #39
1246 ; CHECK: call void @f.nobuiltin() #40
12471247
12481248 call fastcc noalias i32* @f.noalias() noinline
12491249 ; CHECK: call fastcc noalias i32* @f.noalias() #12
15891589 ret void
15901590 }
15911591
1592 declare void @f.writeonly() writeonly
1593 ; CHECK: declare void @f.writeonly() #39
15921594
15931595 ; CHECK: attributes #0 = { alignstack=4 }
15941596 ; CHECK: attributes #1 = { alignstack=8 }
16291631 ; CHECK: attributes #36 = { argmemonly nounwind readonly }
16301632 ; CHECK: attributes #37 = { argmemonly nounwind }
16311633 ; CHECK: attributes #38 = { nounwind readonly }
1632 ; CHECK: attributes #39 = { builtin }
1634 ; CHECK: attributes #39 = { writeonly }
1635 ; CHECK: attributes #40 = { builtin }
16331636
16341637 ;; Metadata
16351638
0 ; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s
11
2 ; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (52)
2 ; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (63)
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 (52)
3 ; CHECK: llvm-lto{{.*}}: error loading file '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (63)
0 ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
1
2 declare void @a() readnone writeonly
3 ; CHECK: Attributes {{.*}} are incompatible
4
5 declare void @b() readonly writeonly
6 ; CHECK: Attributes {{.*}} are incompatible
7
8 declare void @c(i32* readnone writeonly %p)
9 ; CHECK: Attributes {{.*}} are incompatible
10
11 declare void @d(i32* readonly writeonly %p)
12 ; CHECK: Attributes {{.*}} are incompatible
111111 enum ArgAttribute {
112112 NoCapture,
113113 ReadOnly,
114 WriteOnly,
114115 ReadNone
115116 };
116117 std::vector > ArgumentAttributes;
594594 } else if (Property->isSubClassOf("ReadOnly")) {
595595 unsigned ArgNo = Property->getValueAsInt("ArgNo");
596596 ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly));
597 } else if (Property->isSubClassOf("WriteOnly")) {
598 unsigned ArgNo = Property->getValueAsInt("ArgNo");
599 ArgumentAttributes.push_back(std::make_pair(ArgNo, WriteOnly));
597600 } else if (Property->isSubClassOf("ReadNone")) {
598601 unsigned ArgNo = Property->getValueAsInt("ArgNo");
599602 ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
553553 OS << "Attribute::ReadOnly";
554554 addComma = true;
555555 break;
556 case CodeGenIntrinsic::WriteOnly:
557 if (addComma)
558 OS << ",";
559 OS << "Attribute::WriteOnly";
560 addComma = true;
561 break;
556562 case CodeGenIntrinsic::ReadNone:
557563 if (addComma)
558564 OS << ",";
616622 OS << "Attribute::ReadOnly";
617623 break;
618624 case CodeGenIntrinsic::WriteArgMem:
619 case CodeGenIntrinsic::ReadWriteArgMem:
620 if (addComma)
621 OS << ",";
625 if (addComma)
626 OS << ",";
627 OS << "Attribute::WriteOnly,";
622628 OS << "Attribute::ArgMemOnly";
623629 break;
624630 case CodeGenIntrinsic::WriteMem:
631 if (addComma)
632 OS << ",";
633 OS << "Attribute::WriteOnly";
634 break;
635 case CodeGenIntrinsic::ReadWriteArgMem:
636 if (addComma)
637 OS << ",";
638 OS << "Attribute::ArgMemOnly";
639 break;
625640 case CodeGenIntrinsic::ReadWriteMem:
626641 break;
627642 }