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_DYNAMICVL = 61, + ATTR_KIND_UNMASKED_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 UnmaskedReturned : EnumAttr<"unmasked_ret">; + +/// Mask argument that applies to this function. +def Mask : EnumAttr<"mask">; + +/// Dynamic Vector Length argument of this function. +def DynamicVL : EnumAttr<"dynamic_vl">; + /// 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; } +// DynamicVL - The specified argument is the Dynamic Vector Length of the +// operation. +class DynamicVL : 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 UnmaskedReturned argument). +class Mask : IntrinsicProperty { + int ArgNo = argNo; +} +// UnmaskedReturned - 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 UnmaskedReturned : IntrinsicProperty { + int ArgNo = argNo; +} + def IntrNoReturn : IntrinsicProperty; // IntrNoduplicate - Calls to this intrinsic cannot be duplicated. @@ -867,6 +886,227 @@ def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], [], "llvm.clear_cache">; +//===---------------- Masked/Dynamic Vector Length Intrinsic --------------===// +// Memory Intrinsics +def int_dvl_store : Intrinsic<[], [llvm_anyvector_ty, + LLVMAnyPointerType>, + llvm_i32_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrArgMemOnly, Mask<2>, DynamicVL<3>]>; + +def int_dvl_load : Intrinsic<[llvm_anyvector_ty], + [LLVMAnyPointerType>, + llvm_i32_ty, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrReadMem, IntrArgMemOnly, UnmaskedReturned<2>, Mask<3>, DynamicVL<4>]>; + +def int_dvl_gather: Intrinsic<[llvm_anyvector_ty], + [LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrReadMem, UnmaskedReturned<2>, Mask<3>, DynamicVL<4>]>; + +def int_dvl_scatter: Intrinsic<[], + [llvm_anyvector_ty, + LLVMVectorOfAnyPointersToElt<0>, + llvm_i32_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [Mask<2>, DynamicVL<3>]>; + +def int_dvl_expandload: Intrinsic<[llvm_anyvector_ty], + [LLVMPointerToElt<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrReadMem, Mask<2>, UnmaskedReturned<1>, DynamicVL<3>]>; + +def int_dvl_compressstore: Intrinsic<[], + [llvm_anyvector_ty, + LLVMPointerToElt<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrArgMemOnly, Mask<2>, DynamicVL<3>]>; + +// Reductions +def int_dvl_reduce_fadd : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyfloat_ty, + llvm_anyvector_ty, + LLVMVectorSameWidth<2, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, IntrSpeculatable, Mask<2>, DynamicVL<3>]>; +def int_dvl_reduce_fmul : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyfloat_ty, + llvm_anyvector_ty, + LLVMVectorSameWidth<2, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<2>, DynamicVL<3>]>; +def int_dvl_reduce_add : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_mul : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_and : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_or : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_xor : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_smax : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_smin : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_umax : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_umin : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_fmax : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; +def int_dvl_reduce_fmin : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyvector_ty, + LLVMVectorSameWidth<1, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, Mask<1>, DynamicVL<2>]>; + +// Binary operators +let IntrProperties = [IntrNoMem, UnmaskedReturned<0>, Mask<2>, DynamicVL<3>] in { + def int_dvl_add : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_sub : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_mul : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_sdiv : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_udiv : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + + def int_dvl_fadd : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_fsub : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_fmul : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_fdiv : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_frem : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + +// Logical operators + def int_dvl_ashr : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_lshr : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_shl : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_or : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_and : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; + def int_dvl_xor : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; +} + +def int_dvl_fma : Intrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, UnmaskedReturned<0>, Mask<3>, DynamicVL<4>]>; + +// Select +def int_dvl_select : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMVectorSameWidth<0, llvm_i1_ty>, + llvm_i32_ty], + [IntrNoMem, UnmaskedReturned<0>, Mask<2>, DynamicVL<3>]>; + + + + //===-------------------------- Masked Intrinsics -------------------------===// // def int_masked_store : Intrinsic<[], [llvm_anyvector_ty, Index: lib/AsmParser/LLLexer.cpp =================================================================== --- lib/AsmParser/LLLexer.cpp +++ lib/AsmParser/LLLexer.cpp @@ -638,11 +638,13 @@ KEYWORD(convergent); KEYWORD(dereferenceable); KEYWORD(dereferenceable_or_null); + KEYWORD(dynamicvl); KEYWORD(inaccessiblememonly); KEYWORD(inaccessiblemem_or_argmemonly); KEYWORD(inlinehint); KEYWORD(inreg); KEYWORD(jumptable); + KEYWORD(mask); KEYWORD(minsize); KEYWORD(naked); KEYWORD(nest); @@ -682,6 +684,7 @@ KEYWORD(speculative_load_hardening); KEYWORD(swifterror); KEYWORD(swiftself); + KEYWORD(unmasked_ret); KEYWORD(uwtable); KEYWORD(writeonly); KEYWORD(zeroext); Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -1294,7 +1294,9 @@ case lltok::kw_byval: case lltok::kw_dereferenceable: case lltok::kw_dereferenceable_or_null: + case lltok::kw_dynamicvl: case lltok::kw_inalloca: + case lltok::kw_mask: 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_unmasked_ret: HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute on a function"); @@ -1581,8 +1584,10 @@ B.addDereferenceableOrNullAttr(Bytes); continue; } + case lltok::kw_dynamicvl: B.addAttribute(Attribute::DynamicVL); break; 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_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_unmasked_ret: B.addAttribute(Attribute::UnmaskedReturned); break; case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break; case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; @@ -1683,13 +1689,16 @@ // Error handling. case lltok::kw_byval: + case lltok::kw_dynamicvl: case lltok::kw_inalloca: + case lltok::kw_mask: 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_unmasked_ret: HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute"); break; Index: lib/AsmParser/LLToken.h =================================================================== --- lib/AsmParser/LLToken.h +++ lib/AsmParser/LLToken.h @@ -182,11 +182,13 @@ kw_convergent, kw_dereferenceable, kw_dereferenceable_or_null, + kw_dynamicvl, kw_inaccessiblememonly, kw_inaccessiblemem_or_argmemonly, kw_inlinehint, kw_inreg, kw_jumptable, + kw_mask, kw_minsize, kw_naked, kw_nest, @@ -224,6 +226,7 @@ kw_strictfp, kw_swifterror, kw_swiftself, + kw_unmasked_ret, kw_uwtable, kw_writeonly, kw_zeroext, Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -1359,6 +1359,12 @@ return Attribute::ReadNone; case bitc::ATTR_KIND_READ_ONLY: return Attribute::ReadOnly; + case bitc::ATTR_KIND_MASK: + return Attribute::Mask; + case bitc::ATTR_KIND_DYNAMICVL: + return Attribute::DynamicVL; + case bitc::ATTR_KIND_UNMASKED_RET: + return Attribute::UnmaskedReturned; case bitc::ATTR_KIND_RETURNED: return Attribute::Returned; case bitc::ATTR_KIND_RETURNS_TWICE: 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::DynamicVL: + return bitc::ATTR_KIND_DYNAMICVL; + case Attribute::UnmaskedReturned: + return bitc::ATTR_KIND_UNMASKED_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::DynamicVL)) + return "dynamicvl"; if (hasAttribute(Attribute::SwiftError)) return "swifterror"; if (hasAttribute(Attribute::SwiftSelf)) @@ -273,6 +275,8 @@ return "inreg"; if (hasAttribute(Attribute::JumpTable)) return "jumptable"; + if (hasAttribute(Attribute::Mask)) + return "mask"; if (hasAttribute(Attribute::MinSize)) return "minsize"; if (hasAttribute(Attribute::Naked)) @@ -345,6 +349,8 @@ return "sanitize_thread"; if (hasAttribute(Attribute::SanitizeMemory)) return "sanitize_memory"; + if (hasAttribute(Attribute::UnmaskedReturned)) + return "unmasked_ret"; if (hasAttribute(Attribute::UWTable)) return "uwtable"; if (hasAttribute(Attribute::ZExt)) Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -1622,6 +1622,9 @@ if (Attrs.isEmpty()) return; + bool SawDynamicVL = false; + bool SawMask = false; + bool SawUnmaskedReturned = false; bool SawNest = false; bool SawReturned = false; bool SawSRet = false; @@ -1689,12 +1692,33 @@ SawSwiftError = true; } + if (ArgAttrs.hasAttribute(Attribute::DynamicVL)) { + Assert(!SawDynamicVL, "Cannot have multiple 'dynamicvl' parameters!", + V); + SawDynamicVL = true; + } + + if (ArgAttrs.hasAttribute(Attribute::UnmaskedReturned)) { + Assert(!SawUnmaskedReturned, "Cannot have multiple 'unmasked_ret' parameters!", + V); + SawUnmaskedReturned = 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(!SawUnmaskedReturned || SawMask, + "Cannot have 'unmasked_ret' parameter without 'mask' parameter!", V); + if (!Attrs.hasAttributes(AttributeList::FunctionIndex)) return; @@ -4756,7 +4780,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: 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> unmasked_ret, <8 x i1> mask, i32 dynamicvl) { +define <8 x double> @f60(<8 x double> unmasked_ret, <8 x i1> mask, i32 dynamicvl) { + ret <8 x double> undef +} + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } Index: test/Verifier/dvl_attribs.ll =================================================================== --- /dev/null +++ test/Verifier/dvl_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 dynamicvl %x, i32 dynamicvl %y) +; CHECK: Cannot have multiple 'dynamicvl' parameters! + +declare <16 x double> @c(<16 x double> unmasked_ret %a) +; CHECK: Cannot have 'unmasked_ret' parameter without 'mask' parameter! + +declare <16 x double> @d(<16 x double> unmasked_ret %a, <16 x i1> mask %M, <16 x double> unmasked_ret %b) +; CHECK: Cannot have multiple 'unmasked_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, UnmaskedReturned, DynamicVL }; 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("UnmaskedReturned")) { + unsigned ArgNo = Property->getValueAsInt("ArgNo"); + ArgumentAttributes.push_back(std::make_pair(ArgNo, UnmaskedReturned)); + } else if (Property->isSubClassOf("DynamicVL")) { + unsigned ArgNo = Property->getValueAsInt("ArgNo"); + ArgumentAttributes.push_back(std::make_pair(ArgNo, DynamicVL)); + } 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::DynamicVL: + if (addComma) + OS << ","; + OS << "Attribute::DynamicVL"; + addComma = true; + break; + case CodeGenIntrinsic::Mask: + if (addComma) + OS << ","; + OS << "Attribute::Mask"; + addComma = true; + break; + case CodeGenIntrinsic::UnmaskedReturned: + if (addComma) + OS << ","; + OS << "Attribute::UnmaskedReturned"; + addComma = true; + break; case CodeGenIntrinsic::ReadOnly: if (addComma) OS << ",";