[llvm] r274485 - Add writeonly IR attribute

Nicolai Hähnle via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 4 01:56:49 PDT 2016


On 04.07.2016 10:15, David Majnemer wrote:
> Hi,
>
> Did this get an LGTM?  I can't seem to find one in
> http://reviews.llvm.org/D18714
>
> Please revert this revision if it has not received an LGTM.

Mehdi's last comment was that he's fine with it, and after I wrote to 
both Philip and Mehdi in private after multiple pings, Philip said not 
to wait on him. CC'ing him so he can chime in in case anything has changed.

Nicolai

>
> On Mon, Jul 4, 2016 at 1:01 AM, Nicolai Haehnle via llvm-commits
> <llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>> wrote:
>
>     Author: nha
>     Date: Mon Jul  4 03:01:29 2016
>     New Revision: 274485
>
>     URL: http://llvm.org/viewvc/llvm-project?rev=274485&view=rev
>     Log:
>     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
>
>     Added:
>          llvm/trunk/test/Verifier/writeonly.ll
>     Modified:
>          llvm/trunk/docs/LangRef.rst
>          llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
>          llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
>          llvm/trunk/include/llvm/IR/Attributes.td
>          llvm/trunk/include/llvm/IR/CallSite.h
>          llvm/trunk/include/llvm/IR/Function.h
>          llvm/trunk/include/llvm/IR/Instructions.h
>          llvm/trunk/include/llvm/IR/Intrinsics.td
>          llvm/trunk/lib/Analysis/AliasAnalysis.cpp
>          llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
>          llvm/trunk/lib/AsmParser/LLLexer.cpp
>          llvm/trunk/lib/AsmParser/LLParser.cpp
>          llvm/trunk/lib/AsmParser/LLToken.h
>          llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>          llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>          llvm/trunk/lib/IR/Attributes.cpp
>          llvm/trunk/lib/IR/Verifier.cpp
>          llvm/trunk/test/Analysis/BasicAA/cs-cs.ll
>          llvm/trunk/test/Bindings/llvm-c/Inputs/invalid.ll.bc
>          llvm/trunk/test/Bindings/llvm-c/invalid-bitcode.test
>          llvm/trunk/test/Bitcode/attributes.ll
>          llvm/trunk/test/Bitcode/compatibility.ll
>          llvm/trunk/test/Bitcode/invalid.ll
>          llvm/trunk/test/Bitcode/invalid.ll.bc
>          llvm/trunk/test/LTO/X86/Inputs/invalid.ll.bc
>          llvm/trunk/test/LTO/X86/invalid.ll
>          llvm/trunk/utils/TableGen/CodeGenIntrinsics.h
>          llvm/trunk/utils/TableGen/CodeGenTarget.cpp
>          llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
>
>     Modified: llvm/trunk/docs/LangRef.rst
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/docs/LangRef.rst (original)
>     +++ llvm/trunk/docs/LangRef.rst Mon Jul  4 03:01:29 2016
>     @@ -1474,6 +1474,13 @@ example:
>           On an argument, this attribute indicates that the function
>     does not write
>           through this pointer argument, even though it may write to the
>     memory that
>           the pointer points to.
>     +``writeonly``
>     +    On a function, this attribute indicates that the function may
>     write to but
>     +    does not read from memory.
>     +
>     +    On an argument, this attribute indicates that the function may
>     write to but
>     +    does not read through this pointer argument (even though it may
>     read from
>     +    the memory that the pointer points to).
>       ``argmemonly``
>           This attribute indicates that the only memory accesses inside
>     function are
>           loads and stores from objects pointed to by its pointer-typed
>     arguments,
>
>     Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original)
>     +++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Mon Jul  4
>     03:01:29 2016
>     @@ -151,6 +151,13 @@ enum FunctionModRefBehavior {
>         /// This property corresponds to the IntrReadMem LLVM intrinsic
>     flag.
>         FMRB_OnlyReadsMemory = FMRL_Anywhere | MRI_Ref,
>
>     +  // This function does not read from memory anywhere, but may
>     write to any
>     +  // memory location.
>     +  //
>     +  // This property corresponds to the LLVM IR 'writeonly' attribute.
>     +  // This property corresponds to the IntrWriteMem LLVM intrinsic flag.
>     +  FMRB_DoesNotReadMemory = FMRL_Anywhere | MRI_Mod,
>     +
>         /// This indicates that the function could not be classified
>     into one of the
>         /// behaviors above.
>         FMRB_UnknownModRefBehavior = FMRL_Anywhere | MRI_ModRef
>     @@ -312,6 +319,12 @@ public:
>           return !(MRB & MRI_Mod);
>         }
>
>     +  /// Checks if functions with the specified behavior are known to
>     only write
>     +  /// memory (or not access memory at all).
>     +  static bool doesNotReadMemory(FunctionModRefBehavior MRB) {
>     +    return !(MRB & MRI_Ref);
>     +  }
>     +
>         /// Checks if functions with the specified behavior are known to
>     read and
>         /// write at most from objects pointed to by their pointer-typed
>     arguments
>         /// (with arbitrary offsets).
>
>     Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
>     +++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Mon Jul  4
>     03:01:29 2016
>     @@ -521,7 +521,8 @@ enum AttributeKindCodes {
>         ATTR_KIND_NO_RECURSE = 48,
>         ATTR_KIND_INACCESSIBLEMEM_ONLY = 49,
>         ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50,
>     -  ATTR_KIND_ALLOC_SIZE = 51
>     +  ATTR_KIND_ALLOC_SIZE = 51,
>     +  ATTR_KIND_WRITEONLY = 52
>       };
>
>       enum ComdatSelectionKindCodes {
>
>     Modified: llvm/trunk/include/llvm/IR/Attributes.td
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Attributes.td?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/include/llvm/IR/Attributes.td (original)
>     +++ llvm/trunk/include/llvm/IR/Attributes.td Mon Jul  4 03:01:29 2016
>     @@ -167,6 +167,9 @@ def SwiftSelf : EnumAttr<"swiftself">;
>       /// Function must be in a unwind table.
>       def UWTable : EnumAttr<"uwtable">;
>
>     +/// Function only writes to memory.
>     +def WriteOnly : EnumAttr<"writeonly">;
>     +
>       /// Zero extended before/after call.
>       def ZExt : EnumAttr<"zeroext">;
>
>
>     Modified: llvm/trunk/include/llvm/IR/CallSite.h
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/CallSite.h?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/include/llvm/IR/CallSite.h (original)
>     +++ llvm/trunk/include/llvm/IR/CallSite.h Mon Jul  4 03:01:29 2016
>     @@ -417,6 +417,14 @@ public:
>           CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
>         }
>
>     +  /// @brief Determine if the call does not access or only writes
>     memory.
>     +  bool doesNotReadMemory() const {
>     +    CALLSITE_DELEGATE_GETTER(doesNotReadMemory());
>     +  }
>     +  void setDoesNotReadMemory() {
>     +    CALLSITE_DELEGATE_SETTER(setDoesNotReadMemory());
>     +  }
>     +
>         /// @brief Determine if the call can access memmory only using
>     pointers based
>         /// on its arguments.
>         bool onlyAccessesArgMemory() const {
>
>     Modified: llvm/trunk/include/llvm/IR/Function.h
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Function.h?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/include/llvm/IR/Function.h (original)
>     +++ llvm/trunk/include/llvm/IR/Function.h Mon Jul  4 03:01:29 2016
>     @@ -298,6 +298,14 @@ public:
>           addFnAttr(Attribute::ReadOnly);
>         }
>
>     +  /// @brief Determine if the function does not access or only
>     writes memory.
>     +  bool doesNotReadMemory() const {
>     +    return doesNotAccessMemory() ||
>     hasFnAttribute(Attribute::WriteOnly);
>     +  }
>     +  void setDoesNotReadMemory() {
>     +    addFnAttr(Attribute::WriteOnly);
>     +  }
>     +
>         /// @brief Determine if the call can access memmory only using
>     pointers based
>         /// on its arguments.
>         bool onlyAccessesArgMemory() const {
>
>     Modified: llvm/trunk/include/llvm/IR/Instructions.h
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instructions.h?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/include/llvm/IR/Instructions.h (original)
>     +++ llvm/trunk/include/llvm/IR/Instructions.h Mon Jul  4 03:01:29 2016
>     @@ -1739,6 +1739,14 @@ public:
>           addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
>         }
>
>     +  /// \brief Determine if the call does not access or only writes
>     memory.
>     +  bool doesNotReadMemory() const {
>     +    return doesNotAccessMemory() || hasFnAttr(Attribute::WriteOnly);
>     +  }
>     +  void setDoesNotReadMemory() {
>     +    addAttribute(AttributeSet::FunctionIndex, Attribute::WriteOnly);
>     +  }
>     +
>         /// @brief Determine if the call can access memmory only using
>     pointers based
>         /// on its arguments.
>         bool onlyAccessesArgMemory() const {
>     @@ -3691,6 +3699,14 @@ public:
>           addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
>         }
>
>     +  /// \brief Determine if the call does not access or only writes
>     memory.
>     +  bool doesNotReadMemory() const {
>     +    return doesNotAccessMemory() || hasFnAttr(Attribute::WriteOnly);
>     +  }
>     +  void setDoesNotReadMemory() {
>     +    addAttribute(AttributeSet::FunctionIndex, Attribute::WriteOnly);
>     +  }
>     +
>         /// @brief Determine if the call access memmory only using it's
>     pointer
>         /// arguments.
>         bool onlyAccessesArgMemory() const {
>
>     Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
>     +++ llvm/trunk/include/llvm/IR/Intrinsics.td Mon Jul  4 03:01:29 2016
>     @@ -60,6 +60,12 @@ class ReadOnly<int argNo> : IntrinsicPro
>         int ArgNo = argNo;
>       }
>
>     +// WriteOnly - The intrinsic does not read memory through the specified
>     +// argument pointer.
>     +class WriteOnly<int argNo> : IntrinsicProperty {
>     +  int ArgNo = argNo;
>     +}
>     +
>       // ReadNone - The specified argument pointer is not dereferenced
>     by the
>       // intrinsic.
>       class ReadNone<int argNo> : IntrinsicProperty {
>     @@ -349,7 +355,7 @@ def int_memcpy  : Intrinsic<[],
>                                    [llvm_anyptr_ty, llvm_anyptr_ty,
>     llvm_anyint_ty,
>                                     llvm_i32_ty, llvm_i1_ty],
>                                   [IntrArgMemOnly, NoCapture<0>,
>     NoCapture<1>,
>     -                             ReadOnly<1>]>;
>     +                             WriteOnly<0>, ReadOnly<1>]>;
>       def int_memmove : Intrinsic<[],
>                                   [llvm_anyptr_ty, llvm_anyptr_ty,
>     llvm_anyint_ty,
>                                    llvm_i32_ty, llvm_i1_ty],
>     @@ -358,7 +364,7 @@ def int_memmove : Intrinsic<[],
>       def int_memset  : Intrinsic<[],
>                                   [llvm_anyptr_ty, llvm_i8_ty,
>     llvm_anyint_ty,
>                                    llvm_i32_ty, llvm_i1_ty],
>     -                            [IntrArgMemOnly, NoCapture<0>]>;
>     +                            [IntrArgMemOnly, NoCapture<0>,
>     WriteOnly<0>]>;
>
>       let IntrProperties = [IntrNoMem] in {
>         def int_fma  : Intrinsic<[llvm_anyfloat_ty],
>
>     Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysis.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/lib/Analysis/AliasAnalysis.cpp (original)
>     +++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp Mon Jul  4 03:01:29 2016
>     @@ -142,6 +142,8 @@ ModRefInfo AAResults::getModRefInfo(Immu
>
>         if (onlyReadsMemory(MRB))
>           Result = ModRefInfo(Result & MRI_Ref);
>     +  else if (doesNotReadMemory(MRB))
>     +    Result = ModRefInfo(Result & MRI_Mod);
>
>         if (onlyAccessesArgPointees(MRB)) {
>           bool DoesAlias = false;
>     @@ -207,6 +209,8 @@ ModRefInfo AAResults::getModRefInfo(Immu
>         // from CS1 reading memory written by CS2.
>         if (onlyReadsMemory(CS1B))
>           Result = ModRefInfo(Result & MRI_Ref);
>     +  else if (doesNotReadMemory(CS1B))
>     +    Result = ModRefInfo(Result & MRI_Mod);
>
>         // If CS2 only access memory through arguments, accumulate the
>     mod/ref
>         // information from CS1's references to the memory referenced by
>
>     Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original)
>     +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Mon Jul  4
>     03:01:29 2016
>     @@ -563,6 +563,8 @@ FunctionModRefBehavior BasicAAResult::ge
>         // than that.
>         if (CS.onlyReadsMemory())
>           Min = FMRB_OnlyReadsMemory;
>     +  else if (CS.doesNotReadMemory())
>     +    Min = FMRB_DoesNotReadMemory;
>
>         if (CS.onlyAccessesArgMemory())
>           Min = FunctionModRefBehavior(Min &
>     FMRB_OnlyAccessesArgumentPointees);
>     @@ -590,6 +592,8 @@ FunctionModRefBehavior BasicAAResult::ge
>         // If the function declares it only reads memory, go with that.
>         if (F->onlyReadsMemory())
>           Min = FMRB_OnlyReadsMemory;
>     +  else if (F->doesNotReadMemory())
>     +    Min = FMRB_DoesNotReadMemory;
>
>         if (F->onlyAccessesArgMemory())
>           Min = FunctionModRefBehavior(Min &
>     FMRB_OnlyAccessesArgumentPointees);
>     @@ -597,32 +601,18 @@ FunctionModRefBehavior BasicAAResult::ge
>         return Min;
>       }
>
>     -/// Returns true if this is a writeonly (i.e Mod only) parameter.
>     Currently,
>     -/// we don't have a writeonly attribute, so this only knows about
>     builtin
>     -/// intrinsics and target library functions.  We could consider
>     adding a
>     -/// writeonly attribute in the future and moving all of these facts
>     to either
>     -/// Intrinsics.td or InferFunctionAttr.cpp
>     +/// Returns true if this is a writeonly (i.e Mod only) parameter.
>       static bool isWriteOnlyParam(ImmutableCallSite CS, unsigned ArgIdx,
>                                    const TargetLibraryInfo &TLI) {
>     -  if (const IntrinsicInst *II =
>     dyn_cast<IntrinsicInst>(CS.getInstruction()))
>     -    switch (II->getIntrinsicID()) {
>     -    default:
>     -      break;
>     -    case Intrinsic::memset:
>     -    case Intrinsic::memcpy:
>     -    case Intrinsic::memmove:
>     -      // We don't currently have a writeonly attribute.  All other
>     properties
>     -      // of these intrinsics are nicely described via attributes in
>     -      // Intrinsics.td and handled generically.
>     -      if (ArgIdx == 0)
>     -        return true;
>     -    }
>     +  if (CS.paramHasAttr(ArgIdx + 1, Attribute::WriteOnly))
>     +    return true;
>
>         // We can bound the aliasing properties of memset_pattern16 just
>     as we can
>         // for memcpy/memset.  This is particularly important because the
>         // LoopIdiomRecognizer likes to turn loops into calls to
>     memset_pattern16
>     -  // whenever possible.  Note that all but the missing writeonly
>     attribute are
>     -  // handled via InferFunctionAttr.
>     +  // whenever possible.
>     +  // FIXME Consider handling this in InferFunctionAttr.cpp together
>     with other
>     +  // attributes.
>         LibFunc::Func F;
>         if (CS.getCalledFunction() &&
>     TLI.getLibFunc(*CS.getCalledFunction(), F) &&
>             F == LibFunc::memset_pattern16 && TLI.has(F))
>     @@ -639,8 +629,7 @@ static bool isWriteOnlyParam(ImmutableCa
>       ModRefInfo BasicAAResult::getArgModRefInfo(ImmutableCallSite CS,
>                                                  unsigned ArgIdx) {
>
>     -  // Emulate the missing writeonly attribute by checking for known
>     builtin
>     -  // intrinsics and target library functions.
>     +  // Checking for known builtin intrinsics and target library
>     functions.
>         if (isWriteOnlyParam(CS, ArgIdx, TLI))
>           return MRI_Mod;
>
>
>     Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
>     +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Mon Jul  4 03:01:29 2016
>     @@ -660,6 +660,7 @@ lltok::Kind LLLexer::LexIdentifier() {
>         KEYWORD(swifterror);
>         KEYWORD(swiftself);
>         KEYWORD(uwtable);
>     +  KEYWORD(writeonly);
>         KEYWORD(zeroext);
>
>         KEYWORD(type);
>
>     Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
>     +++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Jul  4 03:01:29 2016
>     @@ -1098,6 +1098,7 @@ bool LLParser::ParseFnAttributeValuePair
>           case lltok::kw_sanitize_memory:
>             B.addAttribute(Attribute::SanitizeMemory); break;
>           case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
>     +    case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly);
>     break;
>
>           // Error handling.
>           case lltok::kw_inreg:
>     @@ -1394,6 +1395,7 @@ bool LLParser::ParseOptionalParamAttrs(A
>           case lltok::kw_sret:
>     B.addAttribute(Attribute::StructRet); break;
>           case lltok::kw_swifterror:
>     B.addAttribute(Attribute::SwiftError); break;
>           case lltok::kw_swiftself:
>       B.addAttribute(Attribute::SwiftSelf); break;
>     +    case lltok::kw_writeonly:
>       B.addAttribute(Attribute::WriteOnly); break;
>           case lltok::kw_zeroext:
>       B.addAttribute(Attribute::ZExt); break;
>
>           case lltok::kw_alignstack:
>
>     Modified: llvm/trunk/lib/AsmParser/LLToken.h
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/lib/AsmParser/LLToken.h (original)
>     +++ llvm/trunk/lib/AsmParser/LLToken.h Mon Jul  4 03:01:29 2016
>     @@ -205,6 +205,7 @@ enum Kind {
>         kw_swifterror,
>         kw_swiftself,
>         kw_uwtable,
>     +  kw_writeonly,
>         kw_zeroext,
>
>         kw_type,
>
>     Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
>     +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Jul  4
>     03:01:29 2016
>     @@ -1464,6 +1464,8 @@ static Attribute::AttrKind getAttrFromCo
>           return Attribute::SwiftSelf;
>         case bitc::ATTR_KIND_UW_TABLE:
>           return Attribute::UWTable;
>     +  case bitc::ATTR_KIND_WRITEONLY:
>     +    return Attribute::WriteOnly;
>         case bitc::ATTR_KIND_Z_EXT:
>           return Attribute::ZExt;
>         }
>
>     Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
>     +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Jul  4
>     03:01:29 2016
>     @@ -667,6 +667,8 @@ static uint64_t getAttrKindEncoding(Attr
>           return bitc::ATTR_KIND_SWIFT_SELF;
>         case Attribute::UWTable:
>           return bitc::ATTR_KIND_UW_TABLE;
>     +  case Attribute::WriteOnly:
>     +    return bitc::ATTR_KIND_WRITEONLY;
>         case Attribute::ZExt:
>           return bitc::ATTR_KIND_Z_EXT;
>         case Attribute::EndAttrKinds:
>
>     Modified: llvm/trunk/lib/IR/Attributes.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/lib/IR/Attributes.cpp (original)
>     +++ llvm/trunk/lib/IR/Attributes.cpp Mon Jul  4 03:01:29 2016
>     @@ -292,6 +292,8 @@ std::string Attribute::getAsString(bool
>           return "readnone";
>         if (hasAttribute(Attribute::ReadOnly))
>           return "readonly";
>     +  if (hasAttribute(Attribute::WriteOnly))
>     +    return "writeonly";
>         if (hasAttribute(Attribute::Returned))
>           return "returned";
>         if (hasAttribute(Attribute::ReturnsTwice))
>     @@ -516,6 +518,7 @@ uint64_t AttributeImpl::getAttrMask(Attr
>         case Attribute::InaccessibleMemOrArgMemOnly: return 1ULL << 50;
>         case Attribute::SwiftSelf:       return 1ULL << 51;
>         case Attribute::SwiftError:      return 1ULL << 52;
>     +  case Attribute::WriteOnly:       return 1ULL << 53;
>         case Attribute::Dereferenceable:
>           llvm_unreachable("dereferenceable attribute not supported in
>     raw format");
>           break;
>
>     Modified: llvm/trunk/lib/IR/Verifier.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/lib/IR/Verifier.cpp (original)
>     +++ llvm/trunk/lib/IR/Verifier.cpp Mon Jul  4 03:01:29 2016
>     @@ -1309,6 +1309,7 @@ void Verifier::verifyAttributeTypes(Attr
>               return;
>             }
>           } else if (I->getKindAsEnum() == Attribute::ReadOnly ||
>     +               I->getKindAsEnum() == Attribute::WriteOnly ||
>                      I->getKindAsEnum() == Attribute::ReadNone) {
>             if (Idx == 0) {
>               CheckFailed("Attribute '" + I->getAsString() +
>     @@ -1382,6 +1383,18 @@ void Verifier::verifyParameterAttrs(Attr
>                "'readnone and readonly' are incompatible!",
>                V);
>
>     +  Assert(!(Attrs.hasAttribute(Idx, Attribute::ReadNone) &&
>     +           Attrs.hasAttribute(Idx, Attribute::WriteOnly)),
>     +         "Attributes "
>     +         "'readnone and writeonly' are incompatible!",
>     +         V);
>     +
>     +  Assert(!(Attrs.hasAttribute(Idx, Attribute::ReadOnly) &&
>     +           Attrs.hasAttribute(Idx, Attribute::WriteOnly)),
>     +         "Attributes "
>     +         "'readonly and writeonly' are incompatible!",
>     +         V);
>     +
>         Assert(!(Attrs.hasAttribute(Idx, Attribute::NoInline) &&
>                  Attrs.hasAttribute(Idx, Attribute::AlwaysInline)),
>                "Attributes "
>     @@ -1499,6 +1512,16 @@ void Verifier::verifyFunctionAttrs(Funct
>
>         Assert(
>             !(Attrs.hasAttribute(AttributeSet::FunctionIndex,
>     Attribute::ReadNone) &&
>     +        Attrs.hasAttribute(AttributeSet::FunctionIndex,
>     Attribute::WriteOnly)),
>     +      "Attributes 'readnone and writeonly' are incompatible!", V);
>     +
>     +  Assert(
>     +      !(Attrs.hasAttribute(AttributeSet::FunctionIndex,
>     Attribute::ReadOnly) &&
>     +        Attrs.hasAttribute(AttributeSet::FunctionIndex,
>     Attribute::WriteOnly)),
>     +      "Attributes 'readonly and writeonly' are incompatible!", V);
>     +
>     +  Assert(
>     +      !(Attrs.hasAttribute(AttributeSet::FunctionIndex,
>     Attribute::ReadNone) &&
>               Attrs.hasAttribute(AttributeSet::FunctionIndex,
>                                  Attribute::InaccessibleMemOrArgMemOnly)),
>             "Attributes 'readnone and inaccessiblemem_or_argmemonly' are
>     incompatible!", V);
>
>     Modified: llvm/trunk/test/Analysis/BasicAA/cs-cs.ll
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/cs-cs.ll?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/test/Analysis/BasicAA/cs-cs.ll (original)
>     +++ llvm/trunk/test/Analysis/BasicAA/cs-cs.ll Mon Jul  4 03:01:29 2016
>     @@ -9,6 +9,7 @@ declare void @llvm.memset.p0i8.i64(i8* n
>       declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8*
>     nocapture, i64, i32, i1) nounwind
>
>       declare void @a_readonly_func(i8 *) noinline nounwind readonly
>     +declare void @a_writeonly_func(i8 *) noinline nounwind writeonly
>
>       define <8 x i16> @test1(i8* %p, <8 x i16> %y) {
>       entry:
>     @@ -22,18 +23,18 @@ entry:
>       ; CHECK-LABEL: Function: test1:
>
>       ; CHECK: NoAlias:      i8* %p, i8* %q
>     -; CHECK: Just Ref:  Ptr: i8* %p        <->  %a = call <8 x i16>
>     @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
>     -; CHECK: NoModRef:  Ptr: i8* %q        <->  %a = call <8 x i16>
>     @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
>     +; CHECK: Just Ref:  Ptr: i8* %p        <->  %a = call <8 x i16>
>     @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
>     +; CHECK: NoModRef:  Ptr: i8* %q        <->  %a = call <8 x i16>
>     @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
>       ; CHECK: NoModRef:  Ptr: i8* %p        <->  call void
>     @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
>       ; CHECK: Both ModRef:  Ptr: i8* %q     <->  call void
>     @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
>     -; CHECK: Just Ref:  Ptr: i8* %p        <->  %b = call <8 x i16>
>     @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
>     -; CHECK: NoModRef:  Ptr: i8* %q        <->  %b = call <8 x i16>
>     @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
>     -; 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)
>     -; 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
>     -; 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
>     -; 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
>     -; 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
>     -; 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)
>     +; CHECK: Just Ref:  Ptr: i8* %p        <->  %b = call <8 x i16>
>     @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
>     +; CHECK: NoModRef:  Ptr: i8* %q        <->  %b = call <8 x i16>
>     @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
>     +; 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)
>     +; 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
>     +; 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
>     +; 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
>     +; 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
>     +; 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)
>       }
>
>       define void @test2(i8* %P, i8* %Q) nounwind ssp {
>     @@ -233,9 +234,23 @@ define void @test6(i8* %P) nounwind ssp
>       ; 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)
>       }
>
>     -attributes #0 = { nounwind readonly argmemonly }
>     -attributes #1 = { nounwind argmemonly }
>     +define void @test7(i8* %P) nounwind ssp {
>     +  call void @a_writeonly_func(i8* %P)
>     +  call void @a_readonly_func(i8* %P)
>     +  ret void
>     +
>     +; CHECK-LABEL: Function: test7:
>     +
>     +; CHECK: Just Mod:  Ptr: i8* %P        <->  call void
>     @a_writeonly_func(i8* %P)
>     +; CHECK: Just Ref:  Ptr: i8* %P        <->  call void
>     @a_readonly_func(i8* %P)
>     +; CHECK: Just Mod:   call void @a_writeonly_func(i8* %P) <->   call
>     void @a_readonly_func(i8* %P)
>     +; CHECK: Just Ref:   call void @a_readonly_func(i8* %P) <->   call
>     void @a_writeonly_func(i8* %P)
>     +}
>     +
>     +attributes #0 = { argmemonly nounwind readonly }
>     +attributes #1 = { argmemonly nounwind }
>       attributes #2 = { noinline nounwind readonly }
>     -attributes #3 = { nounwind ssp }
>     -attributes #4 = { nounwind }
>     +attributes #3 = { noinline nounwind writeonly }
>     +attributes #4 = { nounwind ssp }
>     +attributes #5 = { nounwind }
>
>
>     Modified: llvm/trunk/test/Bindings/llvm-c/Inputs/invalid.ll.bc
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/llvm-c/Inputs/invalid.ll.bc?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     Binary files llvm/trunk/test/Bindings/llvm-c/Inputs/invalid.ll.bc
>     (original) and llvm/trunk/test/Bindings/llvm-c/Inputs/invalid.ll.bc
>     Mon Jul  4 03:01:29 2016 differ
>
>     Modified: llvm/trunk/test/Bindings/llvm-c/invalid-bitcode.test
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/llvm-c/invalid-bitcode.test?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/test/Bindings/llvm-c/invalid-bitcode.test (original)
>     +++ llvm/trunk/test/Bindings/llvm-c/invalid-bitcode.test Mon Jul  4
>     03:01:29 2016
>     @@ -1,13 +1,13 @@
>       ; RUN: not llvm-c-test --module-dump < %S/Inputs/invalid.ll.bc
>     2>&1 | FileCheck %s
>       ; RUN: not llvm-c-test --lazy-module-dump <
>     %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
>
>     -CHECK: Error parsing bitcode: Unknown attribute kind (52)
>     +CHECK: Error parsing bitcode: Unknown attribute kind (63)
>
>
>       ; RUN: not llvm-c-test --new-module-dump < %S/Inputs/invalid.ll.bc
>     2>&1 | FileCheck --check-prefix=NEW %s
>       ; RUN: not llvm-c-test --lazy-new-module-dump <
>     %S/Inputs/invalid.ll.bc 2>&1 | FileCheck --check-prefix=NEW %s
>
>     -NEW: Error with new bitcode parser: Unknown attribute kind (52)
>     +NEW: Error with new bitcode parser: Unknown attribute kind (63)
>
>       ; RUN: llvm-c-test --test-diagnostic-handler <
>     %S/Inputs/invalid.ll.bc 2>&1 | FileCheck --check-prefix=DIAGNOSTIC %s
>
>
>     Modified: llvm/trunk/test/Bitcode/attributes.ll
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/attributes.ll?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/test/Bitcode/attributes.ll (original)
>     +++ llvm/trunk/test/Bitcode/attributes.ll Mon Jul  4 03:01:29 2016
>     @@ -204,7 +204,7 @@ define void @f34()
>       ; CHECK: define void @f34()
>       {
>               call void @nobuiltin() nobuiltin
>     -; CHECK: call void @nobuiltin() #32
>     +; CHECK: call void @nobuiltin() #33
>               ret void;
>       }
>
>     @@ -328,6 +328,12 @@ define i8* @f55(i32, i32) allocsize(0, 1
>         ret i8* null
>       }
>
>     +; CHECK: define void @f56() #32
>     +define void @f56() writeonly
>     +{
>     +  ret void
>     +}
>     +
>       ; CHECK: attributes #0 = { noreturn }
>       ; CHECK: attributes #1 = { nounwind }
>       ; CHECK: attributes #2 = { readnone }
>     @@ -360,4 +366,5 @@ define i8* @f55(i32, i32) allocsize(0, 1
>       ; CHECK: attributes #29 = { inaccessiblemem_or_argmemonly }
>       ; CHECK: attributes #30 = { allocsize(0) }
>       ; CHECK: attributes #31 = { allocsize(0,1) }
>     -; CHECK: attributes #32 = { nobuiltin }
>     +; CHECK: attributes #32 = { writeonly }
>     +; CHECK: attributes #33 = { nobuiltin }
>
>     Modified: llvm/trunk/test/Bitcode/compatibility.ll
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility.ll?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/test/Bitcode/compatibility.ll (original)
>     +++ llvm/trunk/test/Bitcode/compatibility.ll Mon Jul  4 03:01:29 2016
>     @@ -1244,7 +1244,7 @@ exit:
>         ; CHECK: select <2 x i1> <i1 true, i1 false>, <2 x i8> <i8 2, i8
>     3>, <2 x i8> <i8 3, i8 2>
>
>         call void @f.nobuiltin() builtin
>     -  ; CHECK: call void @f.nobuiltin() #39
>     +  ; CHECK: call void @f.nobuiltin() #40
>
>         call fastcc noalias i32* @f.noalias() noinline
>         ; CHECK: call fastcc noalias i32* @f.noalias() #12
>     @@ -1590,6 +1590,8 @@ normal:
>         ret void
>       }
>
>     +declare void @f.writeonly() writeonly
>     +; CHECK: declare void @f.writeonly() #39
>
>       ; CHECK: attributes #0 = { alignstack=4 }
>       ; CHECK: attributes #1 = { alignstack=8 }
>     @@ -1630,7 +1632,8 @@ normal:
>       ; CHECK: attributes #36 = { argmemonly nounwind readonly }
>       ; CHECK: attributes #37 = { argmemonly nounwind }
>       ; CHECK: attributes #38 = { nounwind readonly }
>     -; CHECK: attributes #39 = { builtin }
>     +; CHECK: attributes #39 = { writeonly }
>     +; CHECK: attributes #40 = { builtin }
>
>       ;; Metadata
>
>
>     Modified: llvm/trunk/test/Bitcode/invalid.ll
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/invalid.ll?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/test/Bitcode/invalid.ll (original)
>     +++ llvm/trunk/test/Bitcode/invalid.ll Mon Jul  4 03:01:29 2016
>     @@ -1,6 +1,6 @@
>       ; RUN:  not llvm-dis < %s.bc 2>&1 | FileCheck %s
>
>     -; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (52)
>     +; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (63)
>
>       ; invalid.ll.bc has an invalid attribute number.
>       ; The test checks that LLVM reports the error and doesn't access
>     freed memory
>
>     Modified: llvm/trunk/test/Bitcode/invalid.ll.bc
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/invalid.ll.bc?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     Binary files llvm/trunk/test/Bitcode/invalid.ll.bc (original) and
>     llvm/trunk/test/Bitcode/invalid.ll.bc Mon Jul  4 03:01:29 2016 differ
>
>     Modified: llvm/trunk/test/LTO/X86/Inputs/invalid.ll.bc
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/X86/Inputs/invalid.ll.bc?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     Binary files - no diff available.
>
>     Modified: llvm/trunk/test/LTO/X86/invalid.ll
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/X86/invalid.ll?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/test/LTO/X86/invalid.ll (original)
>     +++ llvm/trunk/test/LTO/X86/invalid.ll Mon Jul  4 03:01:29 2016
>     @@ -1,4 +1,4 @@
>       ; RUN: not llvm-lto %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
>
>
>     -; CHECK: llvm-lto{{.*}}: error loading file
>     '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (52)
>     +; CHECK: llvm-lto{{.*}}: error loading file
>     '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (63)
>
>     Added: llvm/trunk/test/Verifier/writeonly.ll
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/writeonly.ll?rev=274485&view=auto
>     ==============================================================================
>     --- llvm/trunk/test/Verifier/writeonly.ll (added)
>     +++ llvm/trunk/test/Verifier/writeonly.ll Mon Jul  4 03:01:29 2016
>     @@ -0,0 +1,13 @@
>     +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
>     +
>     +declare void @a() readnone writeonly
>     +; CHECK: Attributes {{.*}} are incompatible
>     +
>     +declare void @b() readonly writeonly
>     +; CHECK: Attributes {{.*}} are incompatible
>     +
>     +declare void @c(i32* readnone writeonly %p)
>     +; CHECK: Attributes {{.*}} are incompatible
>     +
>     +declare void @d(i32* readonly writeonly %p)
>     +; CHECK: Attributes {{.*}} are incompatible
>
>     Modified: llvm/trunk/utils/TableGen/CodeGenIntrinsics.h
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenIntrinsics.h?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/utils/TableGen/CodeGenIntrinsics.h (original)
>     +++ llvm/trunk/utils/TableGen/CodeGenIntrinsics.h Mon Jul  4
>     03:01:29 2016
>     @@ -112,6 +112,7 @@ namespace llvm {
>           enum ArgAttribute {
>             NoCapture,
>             ReadOnly,
>     +      WriteOnly,
>             ReadNone
>           };
>           std::vector<std::pair<unsigned, ArgAttribute> >
>     ArgumentAttributes;
>
>     Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original)
>     +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Mon Jul  4 03:01:29 2016
>     @@ -595,6 +595,9 @@ CodeGenIntrinsic::CodeGenIntrinsic(Recor
>           } else if (Property->isSubClassOf("ReadOnly")) {
>             unsigned ArgNo = Property->getValueAsInt("ArgNo");
>             ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly));
>     +    } else if (Property->isSubClassOf("WriteOnly")) {
>     +      unsigned ArgNo = Property->getValueAsInt("ArgNo");
>     +      ArgumentAttributes.push_back(std::make_pair(ArgNo, WriteOnly));
>           } else if (Property->isSubClassOf("ReadNone")) {
>             unsigned ArgNo = Property->getValueAsInt("ArgNo");
>             ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
>
>     Modified: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp?rev=274485&r1=274484&r2=274485&view=diff
>     ==============================================================================
>     --- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp (original)
>     +++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp Mon Jul  4
>     03:01:29 2016
>     @@ -554,6 +554,12 @@ EmitAttributes(const std::vector<CodeGen
>                   OS << "Attribute::ReadOnly";
>                   addComma = true;
>                   break;
>     +          case CodeGenIntrinsic::WriteOnly:
>     +            if (addComma)
>     +              OS << ",";
>     +            OS << "Attribute::WriteOnly";
>     +            addComma = true;
>     +            break;
>                 case CodeGenIntrinsic::ReadNone:
>                   if (addComma)
>                     OS << ",";
>     @@ -617,12 +623,21 @@ EmitAttributes(const std::vector<CodeGen
>               OS << "Attribute::ReadOnly";
>               break;
>             case CodeGenIntrinsic::WriteArgMem:
>     -      case CodeGenIntrinsic::ReadWriteArgMem:
>               if (addComma)
>                 OS << ",";
>     +        OS << "Attribute::WriteOnly,";
>               OS << "Attribute::ArgMemOnly";
>               break;
>             case CodeGenIntrinsic::WriteMem:
>     +        if (addComma)
>     +          OS << ",";
>     +        OS << "Attribute::WriteOnly";
>     +        break;
>     +      case CodeGenIntrinsic::ReadWriteArgMem:
>     +        if (addComma)
>     +          OS << ",";
>     +        OS << "Attribute::ArgMemOnly";
>     +        break;
>             case CodeGenIntrinsic::ReadWriteMem:
>               break;
>             }
>
>
>     _______________________________________________
>     llvm-commits mailing list
>     llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
>     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>


More information about the llvm-commits mailing list