Index: include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- include/llvm/Bitcode/LLVMBitCodes.h +++ include/llvm/Bitcode/LLVMBitCodes.h @@ -592,6 +592,9 @@ ATTR_KIND_OPT_FOR_FUZZING = 57, ATTR_KIND_SHADOWCALLSTACK = 58, ATTR_KIND_SPECULATIVE_LOAD_HARDENING = 59, + ATTR_KIND_MASK = 60, + ATTR_KIND_VECTORLENGTH = 61, + ATTR_KIND_MASKEDOUT_RET = 62, }; enum ComdatSelectionKindCodes { Index: include/llvm/IR/Attributes.td =================================================================== --- include/llvm/IR/Attributes.td +++ include/llvm/IR/Attributes.td @@ -130,6 +130,15 @@ /// Return value is always equal to this argument. def Returned : EnumAttr<"returned">; +/// Return value that is equal to this argument on enabled lanes (mask). +def MaskedoutReturned : EnumAttr<"maskedout_ret">; + +/// Mask argument that applies to this function. +def Mask : EnumAttr<"mask">; + +/// Dynamic Vector Length argument of this function. +def VectorLength : EnumAttr<"vlen">; + /// Function can return twice. def ReturnsTwice : EnumAttr<"returns_twice">; Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -88,6 +88,25 @@ int ArgNo = argNo; } +// VectorLength - The specified argument is the Dynamic Vector Length of the +// operation. +class VectorLength : IntrinsicProperty { + int ArgNo = argNo; +} + +// Mask - The specified argument contains the per-lane mask of this +// intrinsic. Inputs on masked-out lanes must not effect the result of this +// intrinsic (except for the MaskedoutReturned argument). +class Mask : IntrinsicProperty { + int ArgNo = argNo; +} +// MaskedoutReturned - The specified argument contains the per-lane return value +// for this vector intrinsic where the mask is false. +// (requires the Mask attribute in the same function) +class MaskedoutReturned : IntrinsicProperty { + int ArgNo = argNo; +} + def IntrNoReturn : IntrinsicProperty; // IntrNoduplicate - Calls to this intrinsic cannot be duplicated. @@ -900,6 +919,235 @@ def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], [], "llvm.clear_cache">; +//===---------------- Masked/Explicit Vector Length Intrinsic --------------===// +// Memory Intrinsics +def int_evl_store : Intrinsic<[], [llvm_anyvector_ty, + LLVMAnyPointerType>, + llvm_i32_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrArgMemOnly, Mask<2>, VectorLength<3>]>; + +def int_evl_load : Intrinsic<[llvm_anyvector_ty], + [LLVMAnyPointerType>, + llvm_i32_ty, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrReadMem, IntrArgMemOnly, MaskedoutReturned<2>, Mask<3>, VectorLength<4>]>; + +def int_evl_gather: Intrinsic<[llvm_anyvector_ty], + [LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrReadMem, MaskedoutReturned<2>, Mask<3>, VectorLength<4>]>; + +def int_evl_scatter: Intrinsic<[], + [llvm_anyvector_ty, + LLVMVectorOfAnyPointersToElt<0>, + llvm_i32_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [Mask<2>, VectorLength<3>]>; + +def int_evl_expandload: Intrinsic<[llvm_anyvector_ty], + [LLVMPointerToElt<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrReadMem, Mask<2>, MaskedoutReturned<1>, VectorLength<3>]>; + +def int_evl_compressstore: Intrinsic<[], + [llvm_anyvector_ty, + LLVMPointerToElt<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrArgMemOnly, Mask<2>, VectorLength<3>]>; + +// Reductions +def int_evl_reduce_fadd : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyfloat_ty, + llvm_anyvector_ty, + LLVMVectorSameWidth<2, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, IntrSpeculatable, Mask<2>, VectorLength<3>]>; +def int_evl_reduce_fmul : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyfloat_ty, + llvm_anyvector_ty, + LLVMVectorSameWidth<2, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<2>, VectorLength<3>]>; +def int_evl_reduce_add : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_mul : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_and : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_or : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_xor : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_smax : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_smin : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_umax : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_umin : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_fmax : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; +def int_evl_reduce_fmin : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, VectorLength<2>]>; + +// Binary operators +let IntrProperties = [IntrNoMem, MaskedoutReturned<0>, Mask<2>, VectorLength<3>] in { + def int_evl_add : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_sub : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_mul : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_sdiv : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_udiv : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + + def int_evl_fadd : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_fsub : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_fmul : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_fdiv : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_frem : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + +// Logical operators + def int_evl_ashr : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_lshr : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_shl : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_or : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_and : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_evl_xor : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; +} + +def int_evl_fma : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, MaskedoutReturned<0>, Mask<3>, VectorLength<4>]>; + +// Select +def int_evl_select : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, MaskedoutReturned<0>, Mask<2>, VectorLength<3>]>; + +// Compose +def int_evl_compose : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, + LLVMMatchType<0>, + llvm_i32_ty, + llvm_i32_ty], + [IntrNoMem, VectorLength<2>]>; + + + + //===-------------------------- Masked Intrinsics -------------------------===// // def int_masked_store : Intrinsic<[], [llvm_anyvector_ty, Index: lib/AsmParser/LLLexer.cpp =================================================================== --- lib/AsmParser/LLLexer.cpp +++ lib/AsmParser/LLLexer.cpp @@ -643,6 +643,8 @@ KEYWORD(inlinehint); KEYWORD(inreg); KEYWORD(jumptable); + KEYWORD(mask); + KEYWORD(maskedout_ret); KEYWORD(minsize); KEYWORD(naked); KEYWORD(nest); @@ -683,6 +685,7 @@ KEYWORD(swifterror); KEYWORD(swiftself); KEYWORD(uwtable); + KEYWORD(vlen); KEYWORD(writeonly); KEYWORD(zeroext); Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -1295,6 +1295,8 @@ case lltok::kw_dereferenceable: case lltok::kw_dereferenceable_or_null: case lltok::kw_inalloca: + case lltok::kw_mask: + case lltok::kw_maskedout_ret: case lltok::kw_nest: case lltok::kw_noalias: case lltok::kw_nocapture: @@ -1303,6 +1305,7 @@ case lltok::kw_sret: case lltok::kw_swifterror: case lltok::kw_swiftself: + case lltok::kw_vlen: HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute on a function"); @@ -1583,6 +1586,8 @@ } case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break; case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; + case lltok::kw_mask: B.addAttribute(Attribute::Mask); break; + case lltok::kw_maskedout_ret: B.addAttribute(Attribute::MaskedoutReturned); break; case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break; @@ -1594,6 +1599,7 @@ 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_vlen: B.addAttribute(Attribute::VectorLength); break; case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break; case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; @@ -1684,12 +1690,15 @@ // Error handling. case lltok::kw_byval: case lltok::kw_inalloca: + case lltok::kw_mask: + case lltok::kw_maskedout_ret: case lltok::kw_nest: case lltok::kw_nocapture: case lltok::kw_returned: case lltok::kw_sret: case lltok::kw_swifterror: case lltok::kw_swiftself: + case lltok::kw_vlen: HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute"); break; Index: lib/AsmParser/LLToken.h =================================================================== --- lib/AsmParser/LLToken.h +++ lib/AsmParser/LLToken.h @@ -187,6 +187,8 @@ kw_inlinehint, kw_inreg, kw_jumptable, + kw_mask, + kw_maskedout_ret, kw_minsize, kw_naked, kw_nest, @@ -225,6 +227,7 @@ kw_swifterror, kw_swiftself, kw_uwtable, + kw_vlen, kw_writeonly, kw_zeroext, Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -1311,6 +1311,8 @@ return Attribute::InReg; case bitc::ATTR_KIND_JUMP_TABLE: return Attribute::JumpTable; + case bitc::ATTR_KIND_MASK: + return Attribute::Mask; case bitc::ATTR_KIND_MIN_SIZE: return Attribute::MinSize; case bitc::ATTR_KIND_NAKED: @@ -1359,6 +1361,8 @@ return Attribute::ReadNone; case bitc::ATTR_KIND_READ_ONLY: return Attribute::ReadOnly; + case bitc::ATTR_KIND_MASKEDOUT_RET: + return Attribute::MaskedoutReturned; case bitc::ATTR_KIND_RETURNED: return Attribute::Returned; case bitc::ATTR_KIND_RETURNS_TWICE: @@ -1399,6 +1403,8 @@ return Attribute::SwiftSelf; case bitc::ATTR_KIND_UW_TABLE: return Attribute::UWTable; + case bitc::ATTR_KIND_VECTORLENGTH: + return Attribute::VectorLength; case bitc::ATTR_KIND_WRITEONLY: return Attribute::WriteOnly; case bitc::ATTR_KIND_Z_EXT: Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -660,6 +660,12 @@ return bitc::ATTR_KIND_READ_ONLY; case Attribute::Returned: return bitc::ATTR_KIND_RETURNED; + case Attribute::Mask: + return bitc::ATTR_KIND_MASK; + case Attribute::VectorLength: + return bitc::ATTR_KIND_VECTORLENGTH; + case Attribute::MaskedoutReturned: + return bitc::ATTR_KIND_MASKEDOUT_RET; case Attribute::ReturnsTwice: return bitc::ATTR_KIND_RETURNS_TWICE; case Attribute::SExt: Index: lib/IR/Attributes.cpp =================================================================== --- lib/IR/Attributes.cpp +++ lib/IR/Attributes.cpp @@ -257,6 +257,8 @@ return "byval"; if (hasAttribute(Attribute::Convergent)) return "convergent"; + if (hasAttribute(Attribute::VectorLength)) + return "vlen"; if (hasAttribute(Attribute::SwiftError)) return "swifterror"; if (hasAttribute(Attribute::SwiftSelf)) @@ -273,6 +275,10 @@ return "inreg"; if (hasAttribute(Attribute::JumpTable)) return "jumptable"; + if (hasAttribute(Attribute::Mask)) + return "mask"; + if (hasAttribute(Attribute::MaskedoutReturned)) + return "maskedout_ret"; if (hasAttribute(Attribute::MinSize)) return "minsize"; if (hasAttribute(Attribute::Naked)) Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -1622,11 +1622,14 @@ if (Attrs.isEmpty()) return; + bool SawMask = false; + bool SawMaskedoutReturned = false; bool SawNest = false; bool SawReturned = false; bool SawSRet = false; bool SawSwiftSelf = false; bool SawSwiftError = false; + bool SawVectorLength = false; // Verify return value attributes. AttributeSet RetAttrs = Attrs.getRetAttributes(); @@ -1689,12 +1692,33 @@ SawSwiftError = true; } + if (ArgAttrs.hasAttribute(Attribute::VectorLength)) { + Assert(!SawVectorLength, "Cannot have multiple 'vlen' parameters!", + V); + SawVectorLength = true; + } + + if (ArgAttrs.hasAttribute(Attribute::MaskedoutReturned)) { + Assert(!SawMaskedoutReturned, "Cannot have multiple 'maskedout_ret' parameters!", + V); + SawMaskedoutReturned = true; + } + + if (ArgAttrs.hasAttribute(Attribute::Mask)) { + Assert(!SawMask, "Cannot have multiple 'mask' parameters!", + V); + SawMask = true; + } + if (ArgAttrs.hasAttribute(Attribute::InAlloca)) { Assert(i == FT->getNumParams() - 1, "inalloca isn't on the last parameter!", V); } } + Assert(!SawMaskedoutReturned || SawMask, + "Cannot have 'maskedout_ret' parameter without 'mask' parameter!", V); + if (!Attrs.hasAttributes(AttributeList::FunctionIndex)) return; @@ -4764,7 +4788,7 @@ bool runOnFunction(Function &F) override { if (!V->verify(F) && FatalErrors) { - errs() << "in function " << F.getName() << '\n'; + errs() << "in function " << F.getName() << '\n'; report_fatal_error("Broken function found, compilation aborted!"); } return false; Index: lib/Transforms/Utils/CodeExtractor.cpp =================================================================== --- lib/Transforms/Utils/CodeExtractor.cpp +++ lib/Transforms/Utils/CodeExtractor.cpp @@ -716,6 +716,8 @@ case Attribute::InaccessibleMemOnly: case Attribute::InaccessibleMemOrArgMemOnly: case Attribute::JumpTable: + case Attribute::Mask: + case Attribute::MaskedoutReturned: case Attribute::Naked: case Attribute::Nest: case Attribute::NoAlias: @@ -734,6 +736,7 @@ case Attribute::StructRet: case Attribute::SwiftError: case Attribute::SwiftSelf: + case Attribute::VectorLength: case Attribute::WriteOnly: case Attribute::ZExt: case Attribute::EndAttrKinds: Index: test/Bitcode/attributes.ll =================================================================== --- test/Bitcode/attributes.ll +++ test/Bitcode/attributes.ll @@ -351,6 +351,11 @@ ret void } +; CHECK: define <8 x double> @f60(<8 x double> maskedout_ret, <8 x i1> mask, i32 vlen) { +define <8 x double> @f60(<8 x double> maskedout_ret, <8 x i1> mask, i32 vlen) { + ret <8 x double> undef +} + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } Index: test/Verifier/evl_attribs.ll =================================================================== --- /dev/null +++ test/Verifier/evl_attribs.ll @@ -0,0 +1,13 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s + +declare void @a(<16 x i1> mask %a, <16 x i1> mask %b) +; CHECK: Cannot have multiple 'mask' parameters! + +declare void @b(<16 x i1> mask %a, i32 vlen %x, i32 vlen %y) +; CHECK: Cannot have multiple 'vlen' parameters! + +declare <16 x double> @c(<16 x double> maskedout_ret %a) +; CHECK: Cannot have 'maskedout_ret' parameter without 'mask' parameter! + +declare <16 x double> @d(<16 x double> maskedout_ret %a, <16 x i1> mask %M, <16 x double> maskedout_ret %b) +; CHECK: Cannot have multiple 'maskedout_ret' parameters! Index: utils/TableGen/CodeGenIntrinsics.h =================================================================== --- utils/TableGen/CodeGenIntrinsics.h +++ utils/TableGen/CodeGenIntrinsics.h @@ -134,7 +134,7 @@ // True if the intrinsic is marked as speculatable. bool isSpeculatable; - enum ArgAttribute { NoCapture, Returned, ReadOnly, WriteOnly, ReadNone }; + enum ArgAttribute { NoCapture, Returned, ReadOnly, WriteOnly, ReadNone, Mask, MaskedoutReturned, VectorLength }; std::vector> ArgumentAttributes; bool hasProperty(enum SDNP Prop) const { Index: utils/TableGen/CodeGenTarget.cpp =================================================================== --- utils/TableGen/CodeGenTarget.cpp +++ utils/TableGen/CodeGenTarget.cpp @@ -692,6 +692,15 @@ } else if (Property->isSubClassOf("Returned")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, Returned)); + } else if (Property->isSubClassOf("MaskedoutReturned")) { + unsigned ArgNo = Property->getValueAsInt("ArgNo"); + ArgumentAttributes.push_back(std::make_pair(ArgNo, MaskedoutReturned)); + } else if (Property->isSubClassOf("VectorLength")) { + unsigned ArgNo = Property->getValueAsInt("ArgNo"); + ArgumentAttributes.push_back(std::make_pair(ArgNo, VectorLength)); + } else if (Property->isSubClassOf("Mask")) { + unsigned ArgNo = Property->getValueAsInt("ArgNo"); + ArgumentAttributes.push_back(std::make_pair(ArgNo, Mask)); } else if (Property->isSubClassOf("ReadOnly")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly)); Index: utils/TableGen/IntrinsicEmitter.cpp =================================================================== --- utils/TableGen/IntrinsicEmitter.cpp +++ utils/TableGen/IntrinsicEmitter.cpp @@ -592,6 +592,24 @@ OS << "Attribute::Returned"; addComma = true; break; + case CodeGenIntrinsic::VectorLength: + if (addComma) + OS << ","; + OS << "Attribute::VectorLength"; + addComma = true; + break; + case CodeGenIntrinsic::Mask: + if (addComma) + OS << ","; + OS << "Attribute::Mask"; + addComma = true; + break; + case CodeGenIntrinsic::MaskedoutReturned: + if (addComma) + OS << ","; + OS << "Attribute::MaskedoutReturned"; + addComma = true; + break; case CodeGenIntrinsic::ReadOnly: if (addComma) OS << ",";