diff --git a/mlir/include/mlir/Dialect/SPIRV/CMakeLists.txt b/mlir/include/mlir/Dialect/SPIRV/CMakeLists.txt index 9f57627c321fb..0e2b2af11346f 100644 --- a/mlir/include/mlir/Dialect/SPIRV/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/SPIRV/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(IR) +add_subdirectory(Interfaces) add_subdirectory(Transforms) diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td index cafe140469570..d5359da2a590e 100644 --- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td +++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td @@ -4274,242 +4274,245 @@ class SPIRV_OpCode { // Begin opcode section. Generated from SPIR-V spec; DO NOT MODIFY! -def SPIRV_OC_OpNop : I32EnumAttrCase<"OpNop", 0>; -def SPIRV_OC_OpUndef : I32EnumAttrCase<"OpUndef", 1>; -def SPIRV_OC_OpSourceContinued : I32EnumAttrCase<"OpSourceContinued", 2>; -def SPIRV_OC_OpSource : I32EnumAttrCase<"OpSource", 3>; -def SPIRV_OC_OpSourceExtension : I32EnumAttrCase<"OpSourceExtension", 4>; -def SPIRV_OC_OpName : I32EnumAttrCase<"OpName", 5>; -def SPIRV_OC_OpMemberName : I32EnumAttrCase<"OpMemberName", 6>; -def SPIRV_OC_OpString : I32EnumAttrCase<"OpString", 7>; -def SPIRV_OC_OpLine : I32EnumAttrCase<"OpLine", 8>; -def SPIRV_OC_OpExtension : I32EnumAttrCase<"OpExtension", 10>; -def SPIRV_OC_OpExtInstImport : I32EnumAttrCase<"OpExtInstImport", 11>; -def SPIRV_OC_OpExtInst : I32EnumAttrCase<"OpExtInst", 12>; -def SPIRV_OC_OpMemoryModel : I32EnumAttrCase<"OpMemoryModel", 14>; -def SPIRV_OC_OpEntryPoint : I32EnumAttrCase<"OpEntryPoint", 15>; -def SPIRV_OC_OpExecutionMode : I32EnumAttrCase<"OpExecutionMode", 16>; -def SPIRV_OC_OpCapability : I32EnumAttrCase<"OpCapability", 17>; -def SPIRV_OC_OpTypeVoid : I32EnumAttrCase<"OpTypeVoid", 19>; -def SPIRV_OC_OpTypeBool : I32EnumAttrCase<"OpTypeBool", 20>; -def SPIRV_OC_OpTypeInt : I32EnumAttrCase<"OpTypeInt", 21>; -def SPIRV_OC_OpTypeFloat : I32EnumAttrCase<"OpTypeFloat", 22>; -def SPIRV_OC_OpTypeVector : I32EnumAttrCase<"OpTypeVector", 23>; -def SPIRV_OC_OpTypeMatrix : I32EnumAttrCase<"OpTypeMatrix", 24>; -def SPIRV_OC_OpTypeImage : I32EnumAttrCase<"OpTypeImage", 25>; -def SPIRV_OC_OpTypeSampledImage : I32EnumAttrCase<"OpTypeSampledImage", 27>; -def SPIRV_OC_OpTypeArray : I32EnumAttrCase<"OpTypeArray", 28>; -def SPIRV_OC_OpTypeRuntimeArray : I32EnumAttrCase<"OpTypeRuntimeArray", 29>; -def SPIRV_OC_OpTypeStruct : I32EnumAttrCase<"OpTypeStruct", 30>; -def SPIRV_OC_OpTypePointer : I32EnumAttrCase<"OpTypePointer", 32>; -def SPIRV_OC_OpTypeFunction : I32EnumAttrCase<"OpTypeFunction", 33>; -def SPIRV_OC_OpTypeForwardPointer : I32EnumAttrCase<"OpTypeForwardPointer", 39>; -def SPIRV_OC_OpConstantTrue : I32EnumAttrCase<"OpConstantTrue", 41>; -def SPIRV_OC_OpConstantFalse : I32EnumAttrCase<"OpConstantFalse", 42>; -def SPIRV_OC_OpConstant : I32EnumAttrCase<"OpConstant", 43>; -def SPIRV_OC_OpConstantComposite : I32EnumAttrCase<"OpConstantComposite", 44>; -def SPIRV_OC_OpConstantNull : I32EnumAttrCase<"OpConstantNull", 46>; -def SPIRV_OC_OpSpecConstantTrue : I32EnumAttrCase<"OpSpecConstantTrue", 48>; -def SPIRV_OC_OpSpecConstantFalse : I32EnumAttrCase<"OpSpecConstantFalse", 49>; -def SPIRV_OC_OpSpecConstant : I32EnumAttrCase<"OpSpecConstant", 50>; -def SPIRV_OC_OpSpecConstantComposite : I32EnumAttrCase<"OpSpecConstantComposite", 51>; -def SPIRV_OC_OpSpecConstantOp : I32EnumAttrCase<"OpSpecConstantOp", 52>; -def SPIRV_OC_OpFunction : I32EnumAttrCase<"OpFunction", 54>; -def SPIRV_OC_OpFunctionParameter : I32EnumAttrCase<"OpFunctionParameter", 55>; -def SPIRV_OC_OpFunctionEnd : I32EnumAttrCase<"OpFunctionEnd", 56>; -def SPIRV_OC_OpFunctionCall : I32EnumAttrCase<"OpFunctionCall", 57>; -def SPIRV_OC_OpVariable : I32EnumAttrCase<"OpVariable", 59>; -def SPIRV_OC_OpLoad : I32EnumAttrCase<"OpLoad", 61>; -def SPIRV_OC_OpStore : I32EnumAttrCase<"OpStore", 62>; -def SPIRV_OC_OpCopyMemory : I32EnumAttrCase<"OpCopyMemory", 63>; -def SPIRV_OC_OpAccessChain : I32EnumAttrCase<"OpAccessChain", 65>; -def SPIRV_OC_OpPtrAccessChain : I32EnumAttrCase<"OpPtrAccessChain", 67>; -def SPIRV_OC_OpInBoundsPtrAccessChain : I32EnumAttrCase<"OpInBoundsPtrAccessChain", 70>; -def SPIRV_OC_OpDecorate : I32EnumAttrCase<"OpDecorate", 71>; -def SPIRV_OC_OpMemberDecorate : I32EnumAttrCase<"OpMemberDecorate", 72>; -def SPIRV_OC_OpVectorExtractDynamic : I32EnumAttrCase<"OpVectorExtractDynamic", 77>; -def SPIRV_OC_OpVectorInsertDynamic : I32EnumAttrCase<"OpVectorInsertDynamic", 78>; -def SPIRV_OC_OpVectorShuffle : I32EnumAttrCase<"OpVectorShuffle", 79>; -def SPIRV_OC_OpCompositeConstruct : I32EnumAttrCase<"OpCompositeConstruct", 80>; -def SPIRV_OC_OpCompositeExtract : I32EnumAttrCase<"OpCompositeExtract", 81>; -def SPIRV_OC_OpCompositeInsert : I32EnumAttrCase<"OpCompositeInsert", 82>; -def SPIRV_OC_OpTranspose : I32EnumAttrCase<"OpTranspose", 84>; -def SPIRV_OC_OpImageDrefGather : I32EnumAttrCase<"OpImageDrefGather", 97>; -def SPIRV_OC_OpImageWrite : I32EnumAttrCase<"OpImageWrite", 99>; -def SPIRV_OC_OpImage : I32EnumAttrCase<"OpImage", 100>; -def SPIRV_OC_OpImageQuerySize : I32EnumAttrCase<"OpImageQuerySize", 104>; -def SPIRV_OC_OpConvertFToU : I32EnumAttrCase<"OpConvertFToU", 109>; -def SPIRV_OC_OpConvertFToS : I32EnumAttrCase<"OpConvertFToS", 110>; -def SPIRV_OC_OpConvertSToF : I32EnumAttrCase<"OpConvertSToF", 111>; -def SPIRV_OC_OpConvertUToF : I32EnumAttrCase<"OpConvertUToF", 112>; -def SPIRV_OC_OpUConvert : I32EnumAttrCase<"OpUConvert", 113>; -def SPIRV_OC_OpSConvert : I32EnumAttrCase<"OpSConvert", 114>; -def SPIRV_OC_OpFConvert : I32EnumAttrCase<"OpFConvert", 115>; -def SPIRV_OC_OpConvertPtrToU : I32EnumAttrCase<"OpConvertPtrToU", 117>; -def SPIRV_OC_OpConvertUToPtr : I32EnumAttrCase<"OpConvertUToPtr", 120>; -def SPIRV_OC_OpPtrCastToGeneric : I32EnumAttrCase<"OpPtrCastToGeneric", 121>; -def SPIRV_OC_OpGenericCastToPtr : I32EnumAttrCase<"OpGenericCastToPtr", 122>; -def SPIRV_OC_OpGenericCastToPtrExplicit : I32EnumAttrCase<"OpGenericCastToPtrExplicit", 123>; -def SPIRV_OC_OpBitcast : I32EnumAttrCase<"OpBitcast", 124>; -def SPIRV_OC_OpSNegate : I32EnumAttrCase<"OpSNegate", 126>; -def SPIRV_OC_OpFNegate : I32EnumAttrCase<"OpFNegate", 127>; -def SPIRV_OC_OpIAdd : I32EnumAttrCase<"OpIAdd", 128>; -def SPIRV_OC_OpFAdd : I32EnumAttrCase<"OpFAdd", 129>; -def SPIRV_OC_OpISub : I32EnumAttrCase<"OpISub", 130>; -def SPIRV_OC_OpFSub : I32EnumAttrCase<"OpFSub", 131>; -def SPIRV_OC_OpIMul : I32EnumAttrCase<"OpIMul", 132>; -def SPIRV_OC_OpFMul : I32EnumAttrCase<"OpFMul", 133>; -def SPIRV_OC_OpUDiv : I32EnumAttrCase<"OpUDiv", 134>; -def SPIRV_OC_OpSDiv : I32EnumAttrCase<"OpSDiv", 135>; -def SPIRV_OC_OpFDiv : I32EnumAttrCase<"OpFDiv", 136>; -def SPIRV_OC_OpUMod : I32EnumAttrCase<"OpUMod", 137>; -def SPIRV_OC_OpSRem : I32EnumAttrCase<"OpSRem", 138>; -def SPIRV_OC_OpSMod : I32EnumAttrCase<"OpSMod", 139>; -def SPIRV_OC_OpFRem : I32EnumAttrCase<"OpFRem", 140>; -def SPIRV_OC_OpFMod : I32EnumAttrCase<"OpFMod", 141>; -def SPIRV_OC_OpVectorTimesScalar : I32EnumAttrCase<"OpVectorTimesScalar", 142>; -def SPIRV_OC_OpMatrixTimesScalar : I32EnumAttrCase<"OpMatrixTimesScalar", 143>; -def SPIRV_OC_OpVectorTimesMatrix : I32EnumAttrCase<"OpVectorTimesMatrix", 144>; -def SPIRV_OC_OpMatrixTimesVector : I32EnumAttrCase<"OpMatrixTimesVector", 145>; -def SPIRV_OC_OpMatrixTimesMatrix : I32EnumAttrCase<"OpMatrixTimesMatrix", 146>; -def SPIRV_OC_OpDot : I32EnumAttrCase<"OpDot", 148>; -def SPIRV_OC_OpIAddCarry : I32EnumAttrCase<"OpIAddCarry", 149>; -def SPIRV_OC_OpISubBorrow : I32EnumAttrCase<"OpISubBorrow", 150>; -def SPIRV_OC_OpUMulExtended : I32EnumAttrCase<"OpUMulExtended", 151>; -def SPIRV_OC_OpSMulExtended : I32EnumAttrCase<"OpSMulExtended", 152>; -def SPIRV_OC_OpIsNan : I32EnumAttrCase<"OpIsNan", 156>; -def SPIRV_OC_OpIsInf : I32EnumAttrCase<"OpIsInf", 157>; -def SPIRV_OC_OpOrdered : I32EnumAttrCase<"OpOrdered", 162>; -def SPIRV_OC_OpUnordered : I32EnumAttrCase<"OpUnordered", 163>; -def SPIRV_OC_OpLogicalEqual : I32EnumAttrCase<"OpLogicalEqual", 164>; -def SPIRV_OC_OpLogicalNotEqual : I32EnumAttrCase<"OpLogicalNotEqual", 165>; -def SPIRV_OC_OpLogicalOr : I32EnumAttrCase<"OpLogicalOr", 166>; -def SPIRV_OC_OpLogicalAnd : I32EnumAttrCase<"OpLogicalAnd", 167>; -def SPIRV_OC_OpLogicalNot : I32EnumAttrCase<"OpLogicalNot", 168>; -def SPIRV_OC_OpSelect : I32EnumAttrCase<"OpSelect", 169>; -def SPIRV_OC_OpIEqual : I32EnumAttrCase<"OpIEqual", 170>; -def SPIRV_OC_OpINotEqual : I32EnumAttrCase<"OpINotEqual", 171>; -def SPIRV_OC_OpUGreaterThan : I32EnumAttrCase<"OpUGreaterThan", 172>; -def SPIRV_OC_OpSGreaterThan : I32EnumAttrCase<"OpSGreaterThan", 173>; -def SPIRV_OC_OpUGreaterThanEqual : I32EnumAttrCase<"OpUGreaterThanEqual", 174>; -def SPIRV_OC_OpSGreaterThanEqual : I32EnumAttrCase<"OpSGreaterThanEqual", 175>; -def SPIRV_OC_OpULessThan : I32EnumAttrCase<"OpULessThan", 176>; -def SPIRV_OC_OpSLessThan : I32EnumAttrCase<"OpSLessThan", 177>; -def SPIRV_OC_OpULessThanEqual : I32EnumAttrCase<"OpULessThanEqual", 178>; -def SPIRV_OC_OpSLessThanEqual : I32EnumAttrCase<"OpSLessThanEqual", 179>; -def SPIRV_OC_OpFOrdEqual : I32EnumAttrCase<"OpFOrdEqual", 180>; -def SPIRV_OC_OpFUnordEqual : I32EnumAttrCase<"OpFUnordEqual", 181>; -def SPIRV_OC_OpFOrdNotEqual : I32EnumAttrCase<"OpFOrdNotEqual", 182>; -def SPIRV_OC_OpFUnordNotEqual : I32EnumAttrCase<"OpFUnordNotEqual", 183>; -def SPIRV_OC_OpFOrdLessThan : I32EnumAttrCase<"OpFOrdLessThan", 184>; -def SPIRV_OC_OpFUnordLessThan : I32EnumAttrCase<"OpFUnordLessThan", 185>; -def SPIRV_OC_OpFOrdGreaterThan : I32EnumAttrCase<"OpFOrdGreaterThan", 186>; -def SPIRV_OC_OpFUnordGreaterThan : I32EnumAttrCase<"OpFUnordGreaterThan", 187>; -def SPIRV_OC_OpFOrdLessThanEqual : I32EnumAttrCase<"OpFOrdLessThanEqual", 188>; -def SPIRV_OC_OpFUnordLessThanEqual : I32EnumAttrCase<"OpFUnordLessThanEqual", 189>; -def SPIRV_OC_OpFOrdGreaterThanEqual : I32EnumAttrCase<"OpFOrdGreaterThanEqual", 190>; -def SPIRV_OC_OpFUnordGreaterThanEqual : I32EnumAttrCase<"OpFUnordGreaterThanEqual", 191>; -def SPIRV_OC_OpShiftRightLogical : I32EnumAttrCase<"OpShiftRightLogical", 194>; -def SPIRV_OC_OpShiftRightArithmetic : I32EnumAttrCase<"OpShiftRightArithmetic", 195>; -def SPIRV_OC_OpShiftLeftLogical : I32EnumAttrCase<"OpShiftLeftLogical", 196>; -def SPIRV_OC_OpBitwiseOr : I32EnumAttrCase<"OpBitwiseOr", 197>; -def SPIRV_OC_OpBitwiseXor : I32EnumAttrCase<"OpBitwiseXor", 198>; -def SPIRV_OC_OpBitwiseAnd : I32EnumAttrCase<"OpBitwiseAnd", 199>; -def SPIRV_OC_OpNot : I32EnumAttrCase<"OpNot", 200>; -def SPIRV_OC_OpBitFieldInsert : I32EnumAttrCase<"OpBitFieldInsert", 201>; -def SPIRV_OC_OpBitFieldSExtract : I32EnumAttrCase<"OpBitFieldSExtract", 202>; -def SPIRV_OC_OpBitFieldUExtract : I32EnumAttrCase<"OpBitFieldUExtract", 203>; -def SPIRV_OC_OpBitReverse : I32EnumAttrCase<"OpBitReverse", 204>; -def SPIRV_OC_OpBitCount : I32EnumAttrCase<"OpBitCount", 205>; -def SPIRV_OC_OpEmitVertex : I32EnumAttrCase<"OpEmitVertex", 218>; -def SPIRV_OC_OpEndPrimitive : I32EnumAttrCase<"OpEndPrimitive", 219>; -def SPIRV_OC_OpControlBarrier : I32EnumAttrCase<"OpControlBarrier", 224>; -def SPIRV_OC_OpMemoryBarrier : I32EnumAttrCase<"OpMemoryBarrier", 225>; -def SPIRV_OC_OpAtomicExchange : I32EnumAttrCase<"OpAtomicExchange", 229>; -def SPIRV_OC_OpAtomicCompareExchange : I32EnumAttrCase<"OpAtomicCompareExchange", 230>; -def SPIRV_OC_OpAtomicCompareExchangeWeak : I32EnumAttrCase<"OpAtomicCompareExchangeWeak", 231>; -def SPIRV_OC_OpAtomicIIncrement : I32EnumAttrCase<"OpAtomicIIncrement", 232>; -def SPIRV_OC_OpAtomicIDecrement : I32EnumAttrCase<"OpAtomicIDecrement", 233>; -def SPIRV_OC_OpAtomicIAdd : I32EnumAttrCase<"OpAtomicIAdd", 234>; -def SPIRV_OC_OpAtomicISub : I32EnumAttrCase<"OpAtomicISub", 235>; -def SPIRV_OC_OpAtomicSMin : I32EnumAttrCase<"OpAtomicSMin", 236>; -def SPIRV_OC_OpAtomicUMin : I32EnumAttrCase<"OpAtomicUMin", 237>; -def SPIRV_OC_OpAtomicSMax : I32EnumAttrCase<"OpAtomicSMax", 238>; -def SPIRV_OC_OpAtomicUMax : I32EnumAttrCase<"OpAtomicUMax", 239>; -def SPIRV_OC_OpAtomicAnd : I32EnumAttrCase<"OpAtomicAnd", 240>; -def SPIRV_OC_OpAtomicOr : I32EnumAttrCase<"OpAtomicOr", 241>; -def SPIRV_OC_OpAtomicXor : I32EnumAttrCase<"OpAtomicXor", 242>; -def SPIRV_OC_OpPhi : I32EnumAttrCase<"OpPhi", 245>; -def SPIRV_OC_OpLoopMerge : I32EnumAttrCase<"OpLoopMerge", 246>; -def SPIRV_OC_OpSelectionMerge : I32EnumAttrCase<"OpSelectionMerge", 247>; -def SPIRV_OC_OpLabel : I32EnumAttrCase<"OpLabel", 248>; -def SPIRV_OC_OpBranch : I32EnumAttrCase<"OpBranch", 249>; -def SPIRV_OC_OpBranchConditional : I32EnumAttrCase<"OpBranchConditional", 250>; -def SPIRV_OC_OpKill : I32EnumAttrCase<"OpKill", 252>; -def SPIRV_OC_OpReturn : I32EnumAttrCase<"OpReturn", 253>; -def SPIRV_OC_OpReturnValue : I32EnumAttrCase<"OpReturnValue", 254>; -def SPIRV_OC_OpUnreachable : I32EnumAttrCase<"OpUnreachable", 255>; -def SPIRV_OC_OpGroupBroadcast : I32EnumAttrCase<"OpGroupBroadcast", 263>; -def SPIRV_OC_OpGroupIAdd : I32EnumAttrCase<"OpGroupIAdd", 264>; -def SPIRV_OC_OpGroupFAdd : I32EnumAttrCase<"OpGroupFAdd", 265>; -def SPIRV_OC_OpGroupFMin : I32EnumAttrCase<"OpGroupFMin", 266>; -def SPIRV_OC_OpGroupUMin : I32EnumAttrCase<"OpGroupUMin", 267>; -def SPIRV_OC_OpGroupSMin : I32EnumAttrCase<"OpGroupSMin", 268>; -def SPIRV_OC_OpGroupFMax : I32EnumAttrCase<"OpGroupFMax", 269>; -def SPIRV_OC_OpGroupUMax : I32EnumAttrCase<"OpGroupUMax", 270>; -def SPIRV_OC_OpGroupSMax : I32EnumAttrCase<"OpGroupSMax", 271>; -def SPIRV_OC_OpNoLine : I32EnumAttrCase<"OpNoLine", 317>; -def SPIRV_OC_OpModuleProcessed : I32EnumAttrCase<"OpModuleProcessed", 330>; -def SPIRV_OC_OpGroupNonUniformElect : I32EnumAttrCase<"OpGroupNonUniformElect", 333>; -def SPIRV_OC_OpGroupNonUniformBroadcast : I32EnumAttrCase<"OpGroupNonUniformBroadcast", 337>; -def SPIRV_OC_OpGroupNonUniformBallot : I32EnumAttrCase<"OpGroupNonUniformBallot", 339>; -def SPIRV_OC_OpGroupNonUniformBallotBitCount : I32EnumAttrCase<"OpGroupNonUniformBallotBitCount", 342>; -def SPIRV_OC_OpGroupNonUniformBallotFindLSB : I32EnumAttrCase<"OpGroupNonUniformBallotFindLSB", 343>; -def SPIRV_OC_OpGroupNonUniformBallotFindMSB : I32EnumAttrCase<"OpGroupNonUniformBallotFindMSB", 344>; -def SPIRV_OC_OpGroupNonUniformShuffle : I32EnumAttrCase<"OpGroupNonUniformShuffle", 345>; -def SPIRV_OC_OpGroupNonUniformShuffleXor : I32EnumAttrCase<"OpGroupNonUniformShuffleXor", 346>; -def SPIRV_OC_OpGroupNonUniformShuffleUp : I32EnumAttrCase<"OpGroupNonUniformShuffleUp", 347>; -def SPIRV_OC_OpGroupNonUniformShuffleDown : I32EnumAttrCase<"OpGroupNonUniformShuffleDown", 348>; -def SPIRV_OC_OpGroupNonUniformIAdd : I32EnumAttrCase<"OpGroupNonUniformIAdd", 349>; -def SPIRV_OC_OpGroupNonUniformFAdd : I32EnumAttrCase<"OpGroupNonUniformFAdd", 350>; -def SPIRV_OC_OpGroupNonUniformIMul : I32EnumAttrCase<"OpGroupNonUniformIMul", 351>; -def SPIRV_OC_OpGroupNonUniformFMul : I32EnumAttrCase<"OpGroupNonUniformFMul", 352>; -def SPIRV_OC_OpGroupNonUniformSMin : I32EnumAttrCase<"OpGroupNonUniformSMin", 353>; -def SPIRV_OC_OpGroupNonUniformUMin : I32EnumAttrCase<"OpGroupNonUniformUMin", 354>; -def SPIRV_OC_OpGroupNonUniformFMin : I32EnumAttrCase<"OpGroupNonUniformFMin", 355>; -def SPIRV_OC_OpGroupNonUniformSMax : I32EnumAttrCase<"OpGroupNonUniformSMax", 356>; -def SPIRV_OC_OpGroupNonUniformUMax : I32EnumAttrCase<"OpGroupNonUniformUMax", 357>; -def SPIRV_OC_OpGroupNonUniformFMax : I32EnumAttrCase<"OpGroupNonUniformFMax", 358>; -def SPIRV_OC_OpGroupNonUniformBitwiseAnd : I32EnumAttrCase<"OpGroupNonUniformBitwiseAnd", 359>; -def SPIRV_OC_OpGroupNonUniformBitwiseOr : I32EnumAttrCase<"OpGroupNonUniformBitwiseOr", 360>; -def SPIRV_OC_OpGroupNonUniformBitwiseXor : I32EnumAttrCase<"OpGroupNonUniformBitwiseXor", 361>; -def SPIRV_OC_OpGroupNonUniformLogicalAnd : I32EnumAttrCase<"OpGroupNonUniformLogicalAnd", 362>; -def SPIRV_OC_OpGroupNonUniformLogicalOr : I32EnumAttrCase<"OpGroupNonUniformLogicalOr", 363>; -def SPIRV_OC_OpGroupNonUniformLogicalXor : I32EnumAttrCase<"OpGroupNonUniformLogicalXor", 364>; -def SPIRV_OC_OpSubgroupBallotKHR : I32EnumAttrCase<"OpSubgroupBallotKHR", 4421>; -def SPIRV_OC_OpSDot : I32EnumAttrCase<"OpSDot", 4450>; -def SPIRV_OC_OpUDot : I32EnumAttrCase<"OpUDot", 4451>; -def SPIRV_OC_OpSUDot : I32EnumAttrCase<"OpSUDot", 4452>; -def SPIRV_OC_OpSDotAccSat : I32EnumAttrCase<"OpSDotAccSat", 4453>; -def SPIRV_OC_OpUDotAccSat : I32EnumAttrCase<"OpUDotAccSat", 4454>; -def SPIRV_OC_OpSUDotAccSat : I32EnumAttrCase<"OpSUDotAccSat", 4455>; -def SPIRV_OC_OpTypeCooperativeMatrixKHR : I32EnumAttrCase<"OpTypeCooperativeMatrixKHR", 4456>; -def SPIRV_OC_OpCooperativeMatrixLoadKHR : I32EnumAttrCase<"OpCooperativeMatrixLoadKHR", 4457>; -def SPIRV_OC_OpCooperativeMatrixStoreKHR : I32EnumAttrCase<"OpCooperativeMatrixStoreKHR", 4458>; -def SPIRV_OC_OpCooperativeMatrixMulAddKHR : I32EnumAttrCase<"OpCooperativeMatrixMulAddKHR", 4459>; -def SPIRV_OC_OpCooperativeMatrixLengthKHR : I32EnumAttrCase<"OpCooperativeMatrixLengthKHR", 4460>; -def SPIRV_OC_OpEmitMeshTasksEXT : I32EnumAttrCase<"OpEmitMeshTasksEXT", 5294>; -def SPIRV_OC_OpSetMeshOutputsEXT : I32EnumAttrCase<"OpSetMeshOutputsEXT", 5295>; -def SPIRV_OC_OpSubgroupBlockReadINTEL : I32EnumAttrCase<"OpSubgroupBlockReadINTEL", 5575>; -def SPIRV_OC_OpSubgroupBlockWriteINTEL : I32EnumAttrCase<"OpSubgroupBlockWriteINTEL", 5576>; -def SPIRV_OC_OpAssumeTrueKHR : I32EnumAttrCase<"OpAssumeTrueKHR", 5630>; -def SPIRV_OC_OpAtomicFAddEXT : I32EnumAttrCase<"OpAtomicFAddEXT", 6035>; -def SPIRV_OC_OpConvertFToBF16INTEL : I32EnumAttrCase<"OpConvertFToBF16INTEL", 6116>; -def SPIRV_OC_OpConvertBF16ToFINTEL : I32EnumAttrCase<"OpConvertBF16ToFINTEL", 6117>; -def SPIRV_OC_OpControlBarrierArriveINTEL : I32EnumAttrCase<"OpControlBarrierArriveINTEL", 6142>; -def SPIRV_OC_OpControlBarrierWaitINTEL : I32EnumAttrCase<"OpControlBarrierWaitINTEL", 6143>; -def SPIRV_OC_OpGroupIMulKHR : I32EnumAttrCase<"OpGroupIMulKHR", 6401>; -def SPIRV_OC_OpGroupFMulKHR : I32EnumAttrCase<"OpGroupFMulKHR", 6402>; +def SPIRV_OC_OpNop : I32EnumAttrCase<"OpNop", 0>; +def SPIRV_OC_OpUndef : I32EnumAttrCase<"OpUndef", 1>; +def SPIRV_OC_OpSourceContinued : I32EnumAttrCase<"OpSourceContinued", 2>; +def SPIRV_OC_OpSource : I32EnumAttrCase<"OpSource", 3>; +def SPIRV_OC_OpSourceExtension : I32EnumAttrCase<"OpSourceExtension", 4>; +def SPIRV_OC_OpName : I32EnumAttrCase<"OpName", 5>; +def SPIRV_OC_OpMemberName : I32EnumAttrCase<"OpMemberName", 6>; +def SPIRV_OC_OpString : I32EnumAttrCase<"OpString", 7>; +def SPIRV_OC_OpLine : I32EnumAttrCase<"OpLine", 8>; +def SPIRV_OC_OpExtension : I32EnumAttrCase<"OpExtension", 10>; +def SPIRV_OC_OpExtInstImport : I32EnumAttrCase<"OpExtInstImport", 11>; +def SPIRV_OC_OpExtInst : I32EnumAttrCase<"OpExtInst", 12>; +def SPIRV_OC_OpMemoryModel : I32EnumAttrCase<"OpMemoryModel", 14>; +def SPIRV_OC_OpEntryPoint : I32EnumAttrCase<"OpEntryPoint", 15>; +def SPIRV_OC_OpExecutionMode : I32EnumAttrCase<"OpExecutionMode", 16>; +def SPIRV_OC_OpCapability : I32EnumAttrCase<"OpCapability", 17>; +def SPIRV_OC_OpTypeVoid : I32EnumAttrCase<"OpTypeVoid", 19>; +def SPIRV_OC_OpTypeBool : I32EnumAttrCase<"OpTypeBool", 20>; +def SPIRV_OC_OpTypeInt : I32EnumAttrCase<"OpTypeInt", 21>; +def SPIRV_OC_OpTypeFloat : I32EnumAttrCase<"OpTypeFloat", 22>; +def SPIRV_OC_OpTypeVector : I32EnumAttrCase<"OpTypeVector", 23>; +def SPIRV_OC_OpTypeMatrix : I32EnumAttrCase<"OpTypeMatrix", 24>; +def SPIRV_OC_OpTypeImage : I32EnumAttrCase<"OpTypeImage", 25>; +def SPIRV_OC_OpTypeSampledImage : I32EnumAttrCase<"OpTypeSampledImage", 27>; +def SPIRV_OC_OpTypeArray : I32EnumAttrCase<"OpTypeArray", 28>; +def SPIRV_OC_OpTypeRuntimeArray : I32EnumAttrCase<"OpTypeRuntimeArray", 29>; +def SPIRV_OC_OpTypeStruct : I32EnumAttrCase<"OpTypeStruct", 30>; +def SPIRV_OC_OpTypePointer : I32EnumAttrCase<"OpTypePointer", 32>; +def SPIRV_OC_OpTypeFunction : I32EnumAttrCase<"OpTypeFunction", 33>; +def SPIRV_OC_OpTypeForwardPointer : I32EnumAttrCase<"OpTypeForwardPointer", 39>; +def SPIRV_OC_OpConstantTrue : I32EnumAttrCase<"OpConstantTrue", 41>; +def SPIRV_OC_OpConstantFalse : I32EnumAttrCase<"OpConstantFalse", 42>; +def SPIRV_OC_OpConstant : I32EnumAttrCase<"OpConstant", 43>; +def SPIRV_OC_OpConstantComposite : I32EnumAttrCase<"OpConstantComposite", 44>; +def SPIRV_OC_OpConstantNull : I32EnumAttrCase<"OpConstantNull", 46>; +def SPIRV_OC_OpSpecConstantTrue : I32EnumAttrCase<"OpSpecConstantTrue", 48>; +def SPIRV_OC_OpSpecConstantFalse : I32EnumAttrCase<"OpSpecConstantFalse", 49>; +def SPIRV_OC_OpSpecConstant : I32EnumAttrCase<"OpSpecConstant", 50>; +def SPIRV_OC_OpSpecConstantComposite : I32EnumAttrCase<"OpSpecConstantComposite", 51>; +def SPIRV_OC_OpSpecConstantOp : I32EnumAttrCase<"OpSpecConstantOp", 52>; +def SPIRV_OC_OpFunction : I32EnumAttrCase<"OpFunction", 54>; +def SPIRV_OC_OpFunctionParameter : I32EnumAttrCase<"OpFunctionParameter", 55>; +def SPIRV_OC_OpFunctionEnd : I32EnumAttrCase<"OpFunctionEnd", 56>; +def SPIRV_OC_OpFunctionCall : I32EnumAttrCase<"OpFunctionCall", 57>; +def SPIRV_OC_OpVariable : I32EnumAttrCase<"OpVariable", 59>; +def SPIRV_OC_OpLoad : I32EnumAttrCase<"OpLoad", 61>; +def SPIRV_OC_OpStore : I32EnumAttrCase<"OpStore", 62>; +def SPIRV_OC_OpCopyMemory : I32EnumAttrCase<"OpCopyMemory", 63>; +def SPIRV_OC_OpAccessChain : I32EnumAttrCase<"OpAccessChain", 65>; +def SPIRV_OC_OpPtrAccessChain : I32EnumAttrCase<"OpPtrAccessChain", 67>; +def SPIRV_OC_OpInBoundsPtrAccessChain : I32EnumAttrCase<"OpInBoundsPtrAccessChain", 70>; +def SPIRV_OC_OpDecorate : I32EnumAttrCase<"OpDecorate", 71>; +def SPIRV_OC_OpMemberDecorate : I32EnumAttrCase<"OpMemberDecorate", 72>; +def SPIRV_OC_OpVectorExtractDynamic : I32EnumAttrCase<"OpVectorExtractDynamic", 77>; +def SPIRV_OC_OpVectorInsertDynamic : I32EnumAttrCase<"OpVectorInsertDynamic", 78>; +def SPIRV_OC_OpVectorShuffle : I32EnumAttrCase<"OpVectorShuffle", 79>; +def SPIRV_OC_OpCompositeConstruct : I32EnumAttrCase<"OpCompositeConstruct", 80>; +def SPIRV_OC_OpCompositeExtract : I32EnumAttrCase<"OpCompositeExtract", 81>; +def SPIRV_OC_OpCompositeInsert : I32EnumAttrCase<"OpCompositeInsert", 82>; +def SPIRV_OC_OpTranspose : I32EnumAttrCase<"OpTranspose", 84>; +def SPIRV_OC_OpImageSampleImplicitLod : I32EnumAttrCase<"OpImageSampleImplicitLod", 87>; +def SPIRV_OC_OpImageSampleExplicitLod : I32EnumAttrCase<"OpImageSampleExplicitLod", 88>; +def SPIRV_OC_OpImageSampleProjDrefImplicitLod : I32EnumAttrCase<"OpImageSampleProjDrefImplicitLod", 93>; +def SPIRV_OC_OpImageDrefGather : I32EnumAttrCase<"OpImageDrefGather", 97>; +def SPIRV_OC_OpImageWrite : I32EnumAttrCase<"OpImageWrite", 99>; +def SPIRV_OC_OpImage : I32EnumAttrCase<"OpImage", 100>; +def SPIRV_OC_OpImageQuerySize : I32EnumAttrCase<"OpImageQuerySize", 104>; +def SPIRV_OC_OpConvertFToU : I32EnumAttrCase<"OpConvertFToU", 109>; +def SPIRV_OC_OpConvertFToS : I32EnumAttrCase<"OpConvertFToS", 110>; +def SPIRV_OC_OpConvertSToF : I32EnumAttrCase<"OpConvertSToF", 111>; +def SPIRV_OC_OpConvertUToF : I32EnumAttrCase<"OpConvertUToF", 112>; +def SPIRV_OC_OpUConvert : I32EnumAttrCase<"OpUConvert", 113>; +def SPIRV_OC_OpSConvert : I32EnumAttrCase<"OpSConvert", 114>; +def SPIRV_OC_OpFConvert : I32EnumAttrCase<"OpFConvert", 115>; +def SPIRV_OC_OpConvertPtrToU : I32EnumAttrCase<"OpConvertPtrToU", 117>; +def SPIRV_OC_OpConvertUToPtr : I32EnumAttrCase<"OpConvertUToPtr", 120>; +def SPIRV_OC_OpPtrCastToGeneric : I32EnumAttrCase<"OpPtrCastToGeneric", 121>; +def SPIRV_OC_OpGenericCastToPtr : I32EnumAttrCase<"OpGenericCastToPtr", 122>; +def SPIRV_OC_OpGenericCastToPtrExplicit : I32EnumAttrCase<"OpGenericCastToPtrExplicit", 123>; +def SPIRV_OC_OpBitcast : I32EnumAttrCase<"OpBitcast", 124>; +def SPIRV_OC_OpSNegate : I32EnumAttrCase<"OpSNegate", 126>; +def SPIRV_OC_OpFNegate : I32EnumAttrCase<"OpFNegate", 127>; +def SPIRV_OC_OpIAdd : I32EnumAttrCase<"OpIAdd", 128>; +def SPIRV_OC_OpFAdd : I32EnumAttrCase<"OpFAdd", 129>; +def SPIRV_OC_OpISub : I32EnumAttrCase<"OpISub", 130>; +def SPIRV_OC_OpFSub : I32EnumAttrCase<"OpFSub", 131>; +def SPIRV_OC_OpIMul : I32EnumAttrCase<"OpIMul", 132>; +def SPIRV_OC_OpFMul : I32EnumAttrCase<"OpFMul", 133>; +def SPIRV_OC_OpUDiv : I32EnumAttrCase<"OpUDiv", 134>; +def SPIRV_OC_OpSDiv : I32EnumAttrCase<"OpSDiv", 135>; +def SPIRV_OC_OpFDiv : I32EnumAttrCase<"OpFDiv", 136>; +def SPIRV_OC_OpUMod : I32EnumAttrCase<"OpUMod", 137>; +def SPIRV_OC_OpSRem : I32EnumAttrCase<"OpSRem", 138>; +def SPIRV_OC_OpSMod : I32EnumAttrCase<"OpSMod", 139>; +def SPIRV_OC_OpFRem : I32EnumAttrCase<"OpFRem", 140>; +def SPIRV_OC_OpFMod : I32EnumAttrCase<"OpFMod", 141>; +def SPIRV_OC_OpVectorTimesScalar : I32EnumAttrCase<"OpVectorTimesScalar", 142>; +def SPIRV_OC_OpMatrixTimesScalar : I32EnumAttrCase<"OpMatrixTimesScalar", 143>; +def SPIRV_OC_OpVectorTimesMatrix : I32EnumAttrCase<"OpVectorTimesMatrix", 144>; +def SPIRV_OC_OpMatrixTimesVector : I32EnumAttrCase<"OpMatrixTimesVector", 145>; +def SPIRV_OC_OpMatrixTimesMatrix : I32EnumAttrCase<"OpMatrixTimesMatrix", 146>; +def SPIRV_OC_OpDot : I32EnumAttrCase<"OpDot", 148>; +def SPIRV_OC_OpIAddCarry : I32EnumAttrCase<"OpIAddCarry", 149>; +def SPIRV_OC_OpISubBorrow : I32EnumAttrCase<"OpISubBorrow", 150>; +def SPIRV_OC_OpUMulExtended : I32EnumAttrCase<"OpUMulExtended", 151>; +def SPIRV_OC_OpSMulExtended : I32EnumAttrCase<"OpSMulExtended", 152>; +def SPIRV_OC_OpIsNan : I32EnumAttrCase<"OpIsNan", 156>; +def SPIRV_OC_OpIsInf : I32EnumAttrCase<"OpIsInf", 157>; +def SPIRV_OC_OpOrdered : I32EnumAttrCase<"OpOrdered", 162>; +def SPIRV_OC_OpUnordered : I32EnumAttrCase<"OpUnordered", 163>; +def SPIRV_OC_OpLogicalEqual : I32EnumAttrCase<"OpLogicalEqual", 164>; +def SPIRV_OC_OpLogicalNotEqual : I32EnumAttrCase<"OpLogicalNotEqual", 165>; +def SPIRV_OC_OpLogicalOr : I32EnumAttrCase<"OpLogicalOr", 166>; +def SPIRV_OC_OpLogicalAnd : I32EnumAttrCase<"OpLogicalAnd", 167>; +def SPIRV_OC_OpLogicalNot : I32EnumAttrCase<"OpLogicalNot", 168>; +def SPIRV_OC_OpSelect : I32EnumAttrCase<"OpSelect", 169>; +def SPIRV_OC_OpIEqual : I32EnumAttrCase<"OpIEqual", 170>; +def SPIRV_OC_OpINotEqual : I32EnumAttrCase<"OpINotEqual", 171>; +def SPIRV_OC_OpUGreaterThan : I32EnumAttrCase<"OpUGreaterThan", 172>; +def SPIRV_OC_OpSGreaterThan : I32EnumAttrCase<"OpSGreaterThan", 173>; +def SPIRV_OC_OpUGreaterThanEqual : I32EnumAttrCase<"OpUGreaterThanEqual", 174>; +def SPIRV_OC_OpSGreaterThanEqual : I32EnumAttrCase<"OpSGreaterThanEqual", 175>; +def SPIRV_OC_OpULessThan : I32EnumAttrCase<"OpULessThan", 176>; +def SPIRV_OC_OpSLessThan : I32EnumAttrCase<"OpSLessThan", 177>; +def SPIRV_OC_OpULessThanEqual : I32EnumAttrCase<"OpULessThanEqual", 178>; +def SPIRV_OC_OpSLessThanEqual : I32EnumAttrCase<"OpSLessThanEqual", 179>; +def SPIRV_OC_OpFOrdEqual : I32EnumAttrCase<"OpFOrdEqual", 180>; +def SPIRV_OC_OpFUnordEqual : I32EnumAttrCase<"OpFUnordEqual", 181>; +def SPIRV_OC_OpFOrdNotEqual : I32EnumAttrCase<"OpFOrdNotEqual", 182>; +def SPIRV_OC_OpFUnordNotEqual : I32EnumAttrCase<"OpFUnordNotEqual", 183>; +def SPIRV_OC_OpFOrdLessThan : I32EnumAttrCase<"OpFOrdLessThan", 184>; +def SPIRV_OC_OpFUnordLessThan : I32EnumAttrCase<"OpFUnordLessThan", 185>; +def SPIRV_OC_OpFOrdGreaterThan : I32EnumAttrCase<"OpFOrdGreaterThan", 186>; +def SPIRV_OC_OpFUnordGreaterThan : I32EnumAttrCase<"OpFUnordGreaterThan", 187>; +def SPIRV_OC_OpFOrdLessThanEqual : I32EnumAttrCase<"OpFOrdLessThanEqual", 188>; +def SPIRV_OC_OpFUnordLessThanEqual : I32EnumAttrCase<"OpFUnordLessThanEqual", 189>; +def SPIRV_OC_OpFOrdGreaterThanEqual : I32EnumAttrCase<"OpFOrdGreaterThanEqual", 190>; +def SPIRV_OC_OpFUnordGreaterThanEqual : I32EnumAttrCase<"OpFUnordGreaterThanEqual", 191>; +def SPIRV_OC_OpShiftRightLogical : I32EnumAttrCase<"OpShiftRightLogical", 194>; +def SPIRV_OC_OpShiftRightArithmetic : I32EnumAttrCase<"OpShiftRightArithmetic", 195>; +def SPIRV_OC_OpShiftLeftLogical : I32EnumAttrCase<"OpShiftLeftLogical", 196>; +def SPIRV_OC_OpBitwiseOr : I32EnumAttrCase<"OpBitwiseOr", 197>; +def SPIRV_OC_OpBitwiseXor : I32EnumAttrCase<"OpBitwiseXor", 198>; +def SPIRV_OC_OpBitwiseAnd : I32EnumAttrCase<"OpBitwiseAnd", 199>; +def SPIRV_OC_OpNot : I32EnumAttrCase<"OpNot", 200>; +def SPIRV_OC_OpBitFieldInsert : I32EnumAttrCase<"OpBitFieldInsert", 201>; +def SPIRV_OC_OpBitFieldSExtract : I32EnumAttrCase<"OpBitFieldSExtract", 202>; +def SPIRV_OC_OpBitFieldUExtract : I32EnumAttrCase<"OpBitFieldUExtract", 203>; +def SPIRV_OC_OpBitReverse : I32EnumAttrCase<"OpBitReverse", 204>; +def SPIRV_OC_OpBitCount : I32EnumAttrCase<"OpBitCount", 205>; +def SPIRV_OC_OpEmitVertex : I32EnumAttrCase<"OpEmitVertex", 218>; +def SPIRV_OC_OpEndPrimitive : I32EnumAttrCase<"OpEndPrimitive", 219>; +def SPIRV_OC_OpControlBarrier : I32EnumAttrCase<"OpControlBarrier", 224>; +def SPIRV_OC_OpMemoryBarrier : I32EnumAttrCase<"OpMemoryBarrier", 225>; +def SPIRV_OC_OpAtomicExchange : I32EnumAttrCase<"OpAtomicExchange", 229>; +def SPIRV_OC_OpAtomicCompareExchange : I32EnumAttrCase<"OpAtomicCompareExchange", 230>; +def SPIRV_OC_OpAtomicCompareExchangeWeak : I32EnumAttrCase<"OpAtomicCompareExchangeWeak", 231>; +def SPIRV_OC_OpAtomicIIncrement : I32EnumAttrCase<"OpAtomicIIncrement", 232>; +def SPIRV_OC_OpAtomicIDecrement : I32EnumAttrCase<"OpAtomicIDecrement", 233>; +def SPIRV_OC_OpAtomicIAdd : I32EnumAttrCase<"OpAtomicIAdd", 234>; +def SPIRV_OC_OpAtomicISub : I32EnumAttrCase<"OpAtomicISub", 235>; +def SPIRV_OC_OpAtomicSMin : I32EnumAttrCase<"OpAtomicSMin", 236>; +def SPIRV_OC_OpAtomicUMin : I32EnumAttrCase<"OpAtomicUMin", 237>; +def SPIRV_OC_OpAtomicSMax : I32EnumAttrCase<"OpAtomicSMax", 238>; +def SPIRV_OC_OpAtomicUMax : I32EnumAttrCase<"OpAtomicUMax", 239>; +def SPIRV_OC_OpAtomicAnd : I32EnumAttrCase<"OpAtomicAnd", 240>; +def SPIRV_OC_OpAtomicOr : I32EnumAttrCase<"OpAtomicOr", 241>; +def SPIRV_OC_OpAtomicXor : I32EnumAttrCase<"OpAtomicXor", 242>; +def SPIRV_OC_OpPhi : I32EnumAttrCase<"OpPhi", 245>; +def SPIRV_OC_OpLoopMerge : I32EnumAttrCase<"OpLoopMerge", 246>; +def SPIRV_OC_OpSelectionMerge : I32EnumAttrCase<"OpSelectionMerge", 247>; +def SPIRV_OC_OpLabel : I32EnumAttrCase<"OpLabel", 248>; +def SPIRV_OC_OpBranch : I32EnumAttrCase<"OpBranch", 249>; +def SPIRV_OC_OpBranchConditional : I32EnumAttrCase<"OpBranchConditional", 250>; +def SPIRV_OC_OpKill : I32EnumAttrCase<"OpKill", 252>; +def SPIRV_OC_OpReturn : I32EnumAttrCase<"OpReturn", 253>; +def SPIRV_OC_OpReturnValue : I32EnumAttrCase<"OpReturnValue", 254>; +def SPIRV_OC_OpUnreachable : I32EnumAttrCase<"OpUnreachable", 255>; +def SPIRV_OC_OpGroupBroadcast : I32EnumAttrCase<"OpGroupBroadcast", 263>; +def SPIRV_OC_OpGroupIAdd : I32EnumAttrCase<"OpGroupIAdd", 264>; +def SPIRV_OC_OpGroupFAdd : I32EnumAttrCase<"OpGroupFAdd", 265>; +def SPIRV_OC_OpGroupFMin : I32EnumAttrCase<"OpGroupFMin", 266>; +def SPIRV_OC_OpGroupUMin : I32EnumAttrCase<"OpGroupUMin", 267>; +def SPIRV_OC_OpGroupSMin : I32EnumAttrCase<"OpGroupSMin", 268>; +def SPIRV_OC_OpGroupFMax : I32EnumAttrCase<"OpGroupFMax", 269>; +def SPIRV_OC_OpGroupUMax : I32EnumAttrCase<"OpGroupUMax", 270>; +def SPIRV_OC_OpGroupSMax : I32EnumAttrCase<"OpGroupSMax", 271>; +def SPIRV_OC_OpNoLine : I32EnumAttrCase<"OpNoLine", 317>; +def SPIRV_OC_OpModuleProcessed : I32EnumAttrCase<"OpModuleProcessed", 330>; +def SPIRV_OC_OpGroupNonUniformElect : I32EnumAttrCase<"OpGroupNonUniformElect", 333>; +def SPIRV_OC_OpGroupNonUniformBroadcast : I32EnumAttrCase<"OpGroupNonUniformBroadcast", 337>; +def SPIRV_OC_OpGroupNonUniformBallot : I32EnumAttrCase<"OpGroupNonUniformBallot", 339>; +def SPIRV_OC_OpGroupNonUniformBallotBitCount : I32EnumAttrCase<"OpGroupNonUniformBallotBitCount", 342>; +def SPIRV_OC_OpGroupNonUniformBallotFindLSB : I32EnumAttrCase<"OpGroupNonUniformBallotFindLSB", 343>; +def SPIRV_OC_OpGroupNonUniformBallotFindMSB : I32EnumAttrCase<"OpGroupNonUniformBallotFindMSB", 344>; +def SPIRV_OC_OpGroupNonUniformShuffle : I32EnumAttrCase<"OpGroupNonUniformShuffle", 345>; +def SPIRV_OC_OpGroupNonUniformShuffleXor : I32EnumAttrCase<"OpGroupNonUniformShuffleXor", 346>; +def SPIRV_OC_OpGroupNonUniformShuffleUp : I32EnumAttrCase<"OpGroupNonUniformShuffleUp", 347>; +def SPIRV_OC_OpGroupNonUniformShuffleDown : I32EnumAttrCase<"OpGroupNonUniformShuffleDown", 348>; +def SPIRV_OC_OpGroupNonUniformIAdd : I32EnumAttrCase<"OpGroupNonUniformIAdd", 349>; +def SPIRV_OC_OpGroupNonUniformFAdd : I32EnumAttrCase<"OpGroupNonUniformFAdd", 350>; +def SPIRV_OC_OpGroupNonUniformIMul : I32EnumAttrCase<"OpGroupNonUniformIMul", 351>; +def SPIRV_OC_OpGroupNonUniformFMul : I32EnumAttrCase<"OpGroupNonUniformFMul", 352>; +def SPIRV_OC_OpGroupNonUniformSMin : I32EnumAttrCase<"OpGroupNonUniformSMin", 353>; +def SPIRV_OC_OpGroupNonUniformUMin : I32EnumAttrCase<"OpGroupNonUniformUMin", 354>; +def SPIRV_OC_OpGroupNonUniformFMin : I32EnumAttrCase<"OpGroupNonUniformFMin", 355>; +def SPIRV_OC_OpGroupNonUniformSMax : I32EnumAttrCase<"OpGroupNonUniformSMax", 356>; +def SPIRV_OC_OpGroupNonUniformUMax : I32EnumAttrCase<"OpGroupNonUniformUMax", 357>; +def SPIRV_OC_OpGroupNonUniformFMax : I32EnumAttrCase<"OpGroupNonUniformFMax", 358>; +def SPIRV_OC_OpGroupNonUniformBitwiseAnd : I32EnumAttrCase<"OpGroupNonUniformBitwiseAnd", 359>; +def SPIRV_OC_OpGroupNonUniformBitwiseOr : I32EnumAttrCase<"OpGroupNonUniformBitwiseOr", 360>; +def SPIRV_OC_OpGroupNonUniformBitwiseXor : I32EnumAttrCase<"OpGroupNonUniformBitwiseXor", 361>; +def SPIRV_OC_OpGroupNonUniformLogicalAnd : I32EnumAttrCase<"OpGroupNonUniformLogicalAnd", 362>; +def SPIRV_OC_OpGroupNonUniformLogicalOr : I32EnumAttrCase<"OpGroupNonUniformLogicalOr", 363>; +def SPIRV_OC_OpGroupNonUniformLogicalXor : I32EnumAttrCase<"OpGroupNonUniformLogicalXor", 364>; +def SPIRV_OC_OpSubgroupBallotKHR : I32EnumAttrCase<"OpSubgroupBallotKHR", 4421>; +def SPIRV_OC_OpSDot : I32EnumAttrCase<"OpSDot", 4450>; +def SPIRV_OC_OpUDot : I32EnumAttrCase<"OpUDot", 4451>; +def SPIRV_OC_OpSUDot : I32EnumAttrCase<"OpSUDot", 4452>; +def SPIRV_OC_OpSDotAccSat : I32EnumAttrCase<"OpSDotAccSat", 4453>; +def SPIRV_OC_OpUDotAccSat : I32EnumAttrCase<"OpUDotAccSat", 4454>; +def SPIRV_OC_OpSUDotAccSat : I32EnumAttrCase<"OpSUDotAccSat", 4455>; +def SPIRV_OC_OpTypeCooperativeMatrixKHR : I32EnumAttrCase<"OpTypeCooperativeMatrixKHR", 4456>; +def SPIRV_OC_OpCooperativeMatrixLoadKHR : I32EnumAttrCase<"OpCooperativeMatrixLoadKHR", 4457>; +def SPIRV_OC_OpCooperativeMatrixStoreKHR : I32EnumAttrCase<"OpCooperativeMatrixStoreKHR", 4458>; +def SPIRV_OC_OpCooperativeMatrixMulAddKHR : I32EnumAttrCase<"OpCooperativeMatrixMulAddKHR", 4459>; +def SPIRV_OC_OpCooperativeMatrixLengthKHR : I32EnumAttrCase<"OpCooperativeMatrixLengthKHR", 4460>; +def SPIRV_OC_OpEmitMeshTasksEXT : I32EnumAttrCase<"OpEmitMeshTasksEXT", 5294>; +def SPIRV_OC_OpSetMeshOutputsEXT : I32EnumAttrCase<"OpSetMeshOutputsEXT", 5295>; +def SPIRV_OC_OpSubgroupBlockReadINTEL : I32EnumAttrCase<"OpSubgroupBlockReadINTEL", 5575>; +def SPIRV_OC_OpSubgroupBlockWriteINTEL : I32EnumAttrCase<"OpSubgroupBlockWriteINTEL", 5576>; +def SPIRV_OC_OpAssumeTrueKHR : I32EnumAttrCase<"OpAssumeTrueKHR", 5630>; +def SPIRV_OC_OpAtomicFAddEXT : I32EnumAttrCase<"OpAtomicFAddEXT", 6035>; +def SPIRV_OC_OpConvertFToBF16INTEL : I32EnumAttrCase<"OpConvertFToBF16INTEL", 6116>; +def SPIRV_OC_OpConvertBF16ToFINTEL : I32EnumAttrCase<"OpConvertBF16ToFINTEL", 6117>; +def SPIRV_OC_OpControlBarrierArriveINTEL : I32EnumAttrCase<"OpControlBarrierArriveINTEL", 6142>; +def SPIRV_OC_OpControlBarrierWaitINTEL : I32EnumAttrCase<"OpControlBarrierWaitINTEL", 6143>; +def SPIRV_OC_OpGroupIMulKHR : I32EnumAttrCase<"OpGroupIMulKHR", 6401>; +def SPIRV_OC_OpGroupFMulKHR : I32EnumAttrCase<"OpGroupFMulKHR", 6402>; def SPIRV_OpcodeAttr : SPIRV_I32EnumAttr<"Opcode", "valid SPIR-V instructions", "opcode", [ @@ -4535,7 +4538,9 @@ def SPIRV_OpcodeAttr : SPIRV_OC_OpMemberDecorate, SPIRV_OC_OpVectorExtractDynamic, SPIRV_OC_OpVectorInsertDynamic, SPIRV_OC_OpVectorShuffle, SPIRV_OC_OpCompositeConstruct, SPIRV_OC_OpCompositeExtract, - SPIRV_OC_OpCompositeInsert, SPIRV_OC_OpTranspose, SPIRV_OC_OpImageDrefGather, + SPIRV_OC_OpCompositeInsert, SPIRV_OC_OpTranspose, + SPIRV_OC_OpImageSampleImplicitLod, SPIRV_OC_OpImageSampleExplicitLod, + SPIRV_OC_OpImageSampleProjDrefImplicitLod, SPIRV_OC_OpImageDrefGather, SPIRV_OC_OpImageWrite, SPIRV_OC_OpImage, SPIRV_OC_OpImageQuerySize, SPIRV_OC_OpConvertFToU, SPIRV_OC_OpConvertFToS, SPIRV_OC_OpConvertSToF, SPIRV_OC_OpConvertUToF, SPIRV_OC_OpUConvert, SPIRV_OC_OpSConvert, diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVImageOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVImageOps.td index 0cdd7b5e9facc..9999e5cc07b86 100644 --- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVImageOps.td +++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVImageOps.td @@ -15,6 +15,7 @@ #define MLIR_DIALECT_SPIRV_IR_IMAGE_OPS include "mlir/Dialect/SPIRV/IR/SPIRVBase.td" +include "mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.td" include "mlir/Interfaces/SideEffectInterfaces.td" // ----- @@ -48,14 +49,19 @@ class SPIRV_DimIsNot values, string transform="$_se class SPIRV_NoneOrElementMatchImage : PredOpTrait< "the " # operand # " component type must match the image sampled type", - CPred<"::llvm::isa(cast(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType()) ||" + CPred<"::llvm::isa(cast<::mlir::spirv::ImageType>(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType()) ||" "(getElementTypeOrSelf($" # operand # ")" "==" - "cast(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType())" + "cast<::mlir::spirv::ImageType>(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType())" > >; -def SPIRV_SampledImageTransform : StrFunc<"llvm::cast($_self).getImageType()">; +class SPIRV_ImageOperandIsPresent values> : PredOpTrait< + "either " # !interleave(values, " or ") # " image operands must be present", + CPred<"::mlir::spirv::bitEnumContainsAny($" # operand # ", " # "::mlir::spirv::ImageOperands::" # !interleave(values, " | ::mlir::spirv::ImageOperands::") # ")"> +>; + +def SPIRV_SampledImageTransform : StrFunc<"llvm::cast<::mlir::spirv::SampledImageType>($_self).getImageType()">; // ----- @@ -89,7 +95,7 @@ def SPIRV_ImageDrefGatherOp : SPIRV_Op<"ImageDrefGather", ```mlir %0 = spirv.ImageDrefGather %1, %2, %3 : !spirv.sampled_image>, vector<4xf32>, f32 -> vector<4xi32> - %0 = spirv.ImageDrefGather %1, %2, %3 : !spirv.sampled_image>, vector<4xf32>, f32 ["NonPrivateTexel"] -> vector<4xi32> + %0 = spirv.ImageDrefGather %1, %2, %3 ["NonPrivateTexel"] : !spirv.sampled_image>, vector<4xf32>, f32 -> vector<4xi32> ``` }]; @@ -268,4 +274,214 @@ def SPIRV_ImageOp : SPIRV_Op<"Image", let hasVerifier = 0; } -#endif // MLIR_DIALECT_SPIRV_IR_GL_OPS +// ----- + +def SPIRV_ImageSampleExplicitLodOp : SPIRV_Op<"ImageSampleExplicitLod", + [SPIRV_DimIsNot<"sampled_image", ["Buffer"], SPIRV_SampledImageTransform.result>, + SPIRV_MSOperandIs<"sampled_image", ["SingleSampled"], SPIRV_SampledImageTransform.result>, + SPIRV_NoneOrElementMatchImage<"result", "sampled_image", SPIRV_SampledImageTransform.result>, + SPIRV_ImageOperandIsPresent<"image_operands", ["Lod", "Grad"]>, + DeclareOpInterfaceMethods]> { + let summary = "Sample an image using an explicit level of detail."; + + let description = [{ + Result Type must be a vector of four components of floating-point type + or integer type. Its components must be the same as Sampled Type of the + underlying OpTypeImage (unless that underlying Sampled Type is + OpTypeVoid). + + Sampled Image must be an object whose type is OpTypeSampledImage. Its + OpTypeImage must not have a Dim of Buffer. The MS operand of the + underlying OpTypeImage must be 0. + + Coordinate must be a scalar or vector of floating-point type or integer + type. It contains (u[, v] ... [, array layer]) as needed by the + definition of Sampled Image. Unless the Kernel capability is declared, + it must be floating point. It may be a vector larger than needed, but + all unused components appear after all used components. + + Image Operands encodes what operands follow, as per Image Operands. + Either Lod or Grad image operands must be present. + + + + #### Example: + + ```mlir + %result = spirv.ImageSampleExplicitLod %image, %coord ["Lod"](%lod) : + !spirv.sampled_image>, + vector<2xf32> (f32) -> vector<4xf32> + ``` + }]; + + let arguments = (ins + SPIRV_AnySampledImage:$sampled_image, + AnyTypeOf<[SPIRV_ScalarOrVectorOf, SPIRV_ScalarOrVectorOf]>:$coordinate, + SPIRV_ImageOperandsAttr:$image_operands, + Variadic:$operand_arguments + ); + + let results = (outs + AnyTypeOf<[SPIRV_Vec4, SPIRV_Vec4]>:$result + ); + + let assemblyFormat = [{ + $sampled_image `,` $coordinate custom($image_operands) ( `,` $operand_arguments^ )? attr-dict + `:` type($sampled_image) `,` type($coordinate) ( `,` type($operand_arguments)^ )? + `->` type($result) + }]; +} + +// ----- + +def SPIRV_ImageSampleImplicitLodOp : SPIRV_Op<"ImageSampleImplicitLod", + [SPIRV_DimIsNot<"sampled_image", ["Buffer"], SPIRV_SampledImageTransform.result>, + SPIRV_MSOperandIs<"sampled_image", ["SingleSampled"], SPIRV_SampledImageTransform.result>, + SPIRV_NoneOrElementMatchImage<"result", "sampled_image", SPIRV_SampledImageTransform.result>, + DeclareOpInterfaceMethods]> { + let summary = "Sample an image with an implicit level of detail."; + + let description = [{ + An invocation will not execute a dynamic instance of this instruction + (X') until all invocations in its derivative group have executed all + dynamic instances that are program-ordered before X'. + + Result Type must be a vector of four components of floating-point type + or integer type. Its components must be the same as Sampled Type of the + underlying OpTypeImage (unless that underlying Sampled Type is + OpTypeVoid). + + Sampled Image must be an object whose type is OpTypeSampledImage. Its + OpTypeImage must not have a Dim of Buffer. The MS operand of the + underlying OpTypeImage must be 0. + + Coordinate must be a scalar or vector of floating-point type. It + contains (u[, v] ... [, array layer]) as needed by the definition of + Sampled Image. It may be a vector larger than needed, but all unused + components appear after all used components. + + Image Operands encodes what operands follow, as per Image Operands. + + This instruction is only valid in the Fragment Execution Model. In + addition, it consumes an implicit derivative that can be affected by + code motion. + + + + #### Example: + + ```mlir + %result = spirv.ImageSampleImplicitLod %image, %coord : + !spirv.sampled_image>, + vector<3xf32> -> vector<4xf32> + ``` + }]; + + let availability = [ + MinVersion, + MaxVersion, + Extension<[]>, + Capability<[SPIRV_C_Shader]> + ]; + + let arguments = (ins + SPIRV_AnySampledImage:$sampled_image, + SPIRV_ScalarOrVectorOf:$coordinate, + OptionalAttr:$image_operands, + Variadic:$operand_arguments + ); + + let results = (outs + AnyTypeOf<[SPIRV_Vec4, SPIRV_Vec4]>:$result + ); + + let assemblyFormat = [{ + $sampled_image `,` $coordinate custom($image_operands) ( `,` $operand_arguments^ )? attr-dict + `:` type($sampled_image) `,` type($coordinate) ( `,` type($operand_arguments)^ )? + `->` type($result) + }]; +} + +// ----- + +def SPIRV_ImageSampleProjDrefImplicitLodOp : SPIRV_Op<"ImageSampleProjDrefImplicitLod", + [SPIRV_DimIsNot<"sampled_image", ["Buffer"], SPIRV_SampledImageTransform.result>, + SPIRV_MSOperandIs<"sampled_image", ["SingleSampled"], SPIRV_SampledImageTransform.result>, + TypesMatchWith<"type of 'result' matches image type of 'sampled_image'", + "sampled_image", "result", + "::llvm::cast<::mlir::spirv::ImageType>(::llvm::cast($_self).getImageType()).getElementType()">, + DeclareOpInterfaceMethods]> { + + let summary = [{ + Sample an image with a project coordinate, doing depth-comparison, with + an implicit level of detail. + }]; + + let description = [{ + An invocation will not execute a dynamic instance of this instruction + (X') until all invocations in its derivative group have executed all + dynamic instances that are program-ordered before X'. + + Result Type must be a scalar of integer type or floating-point type. It + must be the same as Sampled Type of the underlying OpTypeImage. + + Sampled Image must be an object whose type is OpTypeSampledImage. The + Dim operand of the underlying OpTypeImage must be 1D, 2D, 3D, or Rect, + and the Arrayed and MS operands must be 0. + + Coordinate must be a vector of floating-point type. It contains (u[, + v] [, w], q), as needed by the definition of Sampled Image, with the q + component consumed for the projective division. That is, the actual + sample coordinate is (u/q [, v/q] [, w/q]), as needed by the definition + of Sampled Image. It may be a vector larger than needed, but all unused + components appear after all used components. + + Dref/q is the depth-comparison reference value. Dref must be a 32-bit + floating-point type scalar. + + Image Operands encodes what operands follow, as per Image Operands. + + This instruction is only valid in the Fragment Execution Model. In + addition, it consumes an implicit derivative that can be affected by + code motion. + + + + #### Example: + + ```mlir + %result = spirv.ImageSampleProjDrefImplicitLod %image, %coord, %dref : + !spirv.sampled_image>, + vector<4xf16>, f32 -> f32 + ``` + }]; + + let availability = [ + MinVersion, + MaxVersion, + Extension<[]>, + Capability<[SPIRV_C_Shader]> + ]; + + let arguments = (ins + SPIRV_AnySampledImage:$sampled_image, + AnyTypeOf<[SPIRV_ScalarOrVectorOf, SPIRV_ScalarOrVectorOf]>:$coordinate, + SPIRV_Float32:$dref, + OptionalAttr:$image_operands, + Variadic:$operand_arguments + ); + + let results = (outs + AnyTypeOf<[SPIRV_Integer, SPIRV_Float]>:$result + ); + + let assemblyFormat = [{ + $sampled_image `,` $coordinate `,` $dref custom($image_operands) ( `,` $operand_arguments^ )? attr-dict + `:` type($sampled_image) `,` type($coordinate) `,` type($dref) ( `,` type($operand_arguments)^ )? + `->` type($result) + }]; +} + +// ----- + +#endif // MLIR_DIALECT_SPIRV_IR_IMAGE_OPS diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.h b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.h index f9fc165998b52..2676e921c73fb 100644 --- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.h +++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.h @@ -17,6 +17,7 @@ #include "mlir/Dialect/SPIRV/IR/SPIRVAttributes.h" #include "mlir/Dialect/SPIRV/IR/SPIRVOpTraits.h" #include "mlir/Dialect/SPIRV/IR/SPIRVTypes.h" +#include "mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/OpImplementation.h" #include "mlir/Interfaces/CallInterfaces.h" diff --git a/mlir/include/mlir/Dialect/SPIRV/Interfaces/CMakeLists.txt b/mlir/include/mlir/Dialect/SPIRV/Interfaces/CMakeLists.txt new file mode 100644 index 0000000000000..3343882039d84 --- /dev/null +++ b/mlir/include/mlir/Dialect/SPIRV/Interfaces/CMakeLists.txt @@ -0,0 +1 @@ +add_mlir_interface(SPIRVImageInterfaces) diff --git a/mlir/include/mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.h b/mlir/include/mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.h new file mode 100644 index 0000000000000..ca5a1dcd88171 --- /dev/null +++ b/mlir/include/mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.h @@ -0,0 +1,14 @@ +//===- SPIRVImageInterfaces.h -----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_DIALECT_SPIRV_IMAGE_INTERFACES_H_ +#define MLIR_DIALECT_SPIRV_IMAGE_INTERFACES_H_ + +#include "mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.h.inc" + +#endif // MLIR_DIALECT_SPIRV_IMAGE_INTERFACES_H_ diff --git a/mlir/include/mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.td b/mlir/include/mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.td new file mode 100644 index 0000000000000..2b681d9367a4a --- /dev/null +++ b/mlir/include/mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.td @@ -0,0 +1,89 @@ +//===-- SPIRVImageInterfaces.td - MLIR SPIR-V Image Interfaces ------*- tablegen -*------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===------------------------------------------------------------------------------------===// +// +// This file contains interfaces used by image operations. +// +//===------------------------------------------------------------------------------------===// + +#ifndef MLIR_DIALECT_SPIRV_IMAGE_INTERFACES +#define MLIR_DIALECT_SPIRV_IMAGE_INTERFACES + +include "mlir/Dialect/SPIRV/IR/SPIRVBase.td" + +// ----- + +def SPIRV_SampleOpInterface : OpInterface<"SamplingOpInterface"> { + let description = [{ + The `SampleOpInterface` defines sampling image operations (`spirv.Image*Sample*`) + and provides interface methods to query operands common across all sampling + instructions. + + Currently only getters for sampled image and coordinate are provided. The + default implementation will work as long as the instruction the interface is + attached to uses standard names for the operands: `$sampled_image` and `$coordinate`. + }]; + let cppNamespace = "::mlir::spirv"; + let methods = [ + InterfaceMethod< + "Get SampledImage of the operation.", + "::mlir::TypedValue<::mlir::Type>", "getSampledImage", (ins), [{ + return $_op.getSampledImage(); + }]>, + InterfaceMethod< + "Get Coordinate of the operation.", + "::mlir::TypedValue<::mlir::Type>", "getCoordinate", (ins), [{ + return $_op.getCoordinate(); + }]> + ]; +} + +// ----- + +def SPIRV_ExplicitLodOpInterface : OpInterface<"ExplicitLodOpInterface", [SPIRV_SampleOpInterface]> { + let description = [{ + The `ExplicitLodOpInterface` defines explicit sampling lod operations (`spirv.*ExplicitLod`). Currently + the interface is only used to check whether the instruction is an explicit lod. + }]; + let cppNamespace = "::mlir::spirv"; +} + +// ----- + +def SPIRV_ImplicitLodOpInterface : OpInterface<"ImplicitLodOpInterface", [SPIRV_SampleOpInterface]> { + let description = [{ + The `ImplicitLodOpInterface` defines implicit sampling lod operations (`spirv.*ImplicitLod`). Currently + the interface is only used to check whether the instruction is an implicit lod. + }]; + let cppNamespace = "::mlir::spirv"; +} + +// ----- + +def SPIRV_FetchOpInterface : OpInterface<"FetchOpInterface"> { + let description = [{ + The `FetchOpInterface` defines fetch image operations (`spirv.ImageFetch` and + `spirv.ImageSpareFetch`) and provides interface methods to query operands common + across all fetch instructions. + + Currently only a getter for image is provided. The default implementation + will work as long as the instruction the interface is attached to uses + standard names for the operands: `$image`. + }]; + let cppNamespace = "::mlir::spirv"; + let methods = [ + InterfaceMethod< + "Get Image of the operation.", + "::mlir::TypedValue<::mlir::Type>", "getImage", (ins), [{ + return $_op.getImage(); + }]> + ]; +} + +// ----- + +#endif // MLIR_DIALECT_SPIRV_IMAGE_INTERFACES diff --git a/mlir/lib/Dialect/SPIRV/CMakeLists.txt b/mlir/lib/Dialect/SPIRV/CMakeLists.txt index 4d73d45f39ec0..211f67afd9fd0 100644 --- a/mlir/lib/Dialect/SPIRV/CMakeLists.txt +++ b/mlir/lib/Dialect/SPIRV/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(IR) +add_subdirectory(Interfaces) add_subdirectory(Linking) add_subdirectory(Transforms) add_subdirectory(Utils) diff --git a/mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt b/mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt index 235beb0b6a097..1a8f30dd39871 100644 --- a/mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt @@ -35,6 +35,7 @@ add_mlir_dialect_library(MLIRSPIRVDialect MLIRSPIRVCanonicalizationIncGen MLIRSPIRVEnumAvailabilityIncGen MLIRSPIRVEnumsIncGen + MLIRSPIRVImageInterfacesIncGen MLIRSPIRVOpsIncGen LINK_LIBS PUBLIC @@ -43,6 +44,7 @@ add_mlir_dialect_library(MLIRSPIRVDialect MLIRIR MLIRParser MLIRSideEffectInterfaces + MLIRSPIRVImageInterfaces MLIRSupport MLIRTransforms MLIRUBDialect diff --git a/mlir/lib/Dialect/SPIRV/IR/ImageOps.cpp b/mlir/lib/Dialect/SPIRV/IR/ImageOps.cpp index daf6d84660f2a..b198294b9bdd6 100644 --- a/mlir/lib/Dialect/SPIRV/IR/ImageOps.cpp +++ b/mlir/lib/Dialect/SPIRV/IR/ImageOps.cpp @@ -18,6 +18,8 @@ using namespace mlir; // Common utility functions //===----------------------------------------------------------------------===// +// TODO: In the future we should model image operands better, so we can move +// some verification into ODS. static LogicalResult verifyImageOperands(Operation *imageOp, spirv::ImageOperandsAttr attr, Operation::operand_range operands) { @@ -29,10 +31,123 @@ static LogicalResult verifyImageOperands(Operation *imageOp, "follow, as per Image Operands"); } + if (spirv::bitEnumContainsAll(attr.getValue(), + spirv::ImageOperands::Lod | + spirv::ImageOperands::Grad)) + return imageOp->emitError( + "it is invalid to set both the Lod and Grad bits"); + + size_t index = 0; + + // The order we process operands is important. In case of multiple argument + // taking operands, the arguments are ordered starting with operands having + // smaller-numbered bits first. + if (spirv::bitEnumContainsAny(attr.getValue(), spirv::ImageOperands::Lod)) { + if (!isa(imageOp) && + !isa(imageOp)) + return imageOp->emitError( + "Lod is only valid with explicit-lod and fetch instructions"); + + if (index + 1 > operands.size()) + return imageOp->emitError("Lod operand requires 1 argument"); + + spirv::ImageType imageType; + + if (isa(imageOp)) { + if (!isa(operands[index].getType())) + return imageOp->emitError("for sampling operations, Lod must be a " + "floating-point type scalar"); + + auto samplingOp = cast(imageOp); + auto sampledImageType = llvm::cast( + samplingOp.getSampledImage().getType()); + imageType = cast(sampledImageType.getImageType()); + } else { + if (!isa(operands[index].getType())) + return imageOp->emitError( + "for fetch operations, Lod must be an integer type scalar"); + + auto fetchOp = cast(imageOp); + imageType = cast(fetchOp.getImage().getType()); + } + + if (!llvm::is_contained({spirv::Dim::Dim1D, spirv::Dim::Dim2D, + spirv::Dim::Dim3D, spirv::Dim::Cube}, + imageType.getDim())) + return imageOp->emitError("Lod only be used with an image type that has " + "a dim operand of 1D, 2D, 3D, or Cube"); + + if (imageType.getSamplingInfo() != spirv::ImageSamplingInfo::SingleSampled) + return imageOp->emitError( + "Lod only be used with an image type that has a MS operand of 0"); + + ++index; + } + + if (spirv::bitEnumContainsAny(attr.getValue(), spirv::ImageOperands::Grad)) { + if (!isa(imageOp)) + return imageOp->emitError( + "Grad is only valid with explicit-lod instructions"); + + if (index + 2 > operands.size()) + return imageOp->emitError( + "Grad operand requires 2 arguments (scalars or vectors)"); + + auto samplingOp = cast(imageOp); + auto sampledImageType = + cast(samplingOp.getSampledImage().getType()); + auto imageType = cast(sampledImageType.getImageType()); + + if (imageType.getSamplingInfo() != spirv::ImageSamplingInfo::SingleSampled) + return imageOp->emitError( + "Grad only be used with an image type that has a MS operand of 0"); + + int64_t numberOfComponents = 0; + + auto coordVector = + dyn_cast(samplingOp.getCoordinate().getType()); + if (coordVector) { + numberOfComponents = coordVector.getNumElements(); + if (imageType.getArrayedInfo() == spirv::ImageArrayedInfo::Arrayed) + numberOfComponents -= 1; + } else { + numberOfComponents = 1; + } + + assert(numberOfComponents > 0); + + auto dXVector = dyn_cast(operands[index].getType()); + auto dYVector = dyn_cast(operands[index + 1].getType()); + if (dXVector && dYVector) { + if (dXVector.getNumElements() != dYVector.getNumElements() || + dXVector.getNumElements() != numberOfComponents) + return imageOp->emitError( + "number of components of each Grad argument must equal the number " + "of components in coordinate, minus the array layer component, if " + "present"); + + if (!isa(dXVector.getElementType()) || + !isa(dYVector.getElementType())) + return imageOp->emitError( + "Grad arguments must be a vector of floating-point type"); + } else if (isa(operands[index].getType()) && + isa(operands[index + 1].getType())) { + if (numberOfComponents != 1) + return imageOp->emitError( + "number of components of each Grad argument must equal the number " + "of components in coordinate, minus the array layer component, if " + "present"); + } else { + return imageOp->emitError( + "Grad arguments must be a scalar or vector of floating-point type"); + } + + index += 2; + } + // TODO: Add the validation rules for the following Image Operands. spirv::ImageOperands noSupportOperands = - spirv::ImageOperands::Bias | spirv::ImageOperands::Lod | - spirv::ImageOperands::Grad | spirv::ImageOperands::ConstOffset | + spirv::ImageOperands::Bias | spirv::ImageOperands::ConstOffset | spirv::ImageOperands::Offset | spirv::ImageOperands::ConstOffsets | spirv::ImageOperands::Sample | spirv::ImageOperands::MinLod | spirv::ImageOperands::MakeTexelAvailable | @@ -43,6 +158,10 @@ static LogicalResult verifyImageOperands(Operation *imageOp, "unimplemented operands of Image Operands"); (void)noSupportOperands; + if (index < operands.size()) + return imageOp->emitError( + "too many image operand arguments have been provided"); + return success(); } @@ -136,3 +255,33 @@ LogicalResult spirv::ImageQuerySizeOp::verify() { return success(); } + +//===----------------------------------------------------------------------===// +// spirv.ImageSampleImplicitLod +//===----------------------------------------------------------------------===// + +LogicalResult spirv::ImageSampleImplicitLodOp::verify() { + return verifyImageOperands(getOperation(), getImageOperandsAttr(), + getOperandArguments()); +} + +//===----------------------------------------------------------------------===// +// spirv.ImageSampleExplicitLod +//===----------------------------------------------------------------------===// + +LogicalResult spirv::ImageSampleExplicitLodOp::verify() { + // TODO: It should be verified somewhere that: "Unless the Kernel capability + // is declared, it [Coordinate] must be floating point." + + return verifyImageOperands(getOperation(), getImageOperandsAttr(), + getOperandArguments()); +} + +//===----------------------------------------------------------------------===// +// spirv.ImageSampleProjDrefImplicitLod +//===----------------------------------------------------------------------===// + +LogicalResult spirv::ImageSampleProjDrefImplicitLodOp::verify() { + return verifyImageOperands(getOperation(), getImageOperandsAttr(), + getOperandArguments()); +} diff --git a/mlir/lib/Dialect/SPIRV/Interfaces/CMakeLists.txt b/mlir/lib/Dialect/SPIRV/Interfaces/CMakeLists.txt new file mode 100644 index 0000000000000..2868e3b641b91 --- /dev/null +++ b/mlir/lib/Dialect/SPIRV/Interfaces/CMakeLists.txt @@ -0,0 +1,12 @@ +add_mlir_library(MLIRSPIRVImageInterfaces + SPIRVImageInterfaces.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/SPIRV + + DEPENDS + MLIRSPIRVImageInterfacesIncGen + + LINK_LIBS PUBLIC + MLIRIR +) diff --git a/mlir/lib/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.cpp b/mlir/lib/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.cpp new file mode 100644 index 0000000000000..e10da60184eeb --- /dev/null +++ b/mlir/lib/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.cpp @@ -0,0 +1,13 @@ +//===- SPIRVImageInterfaces.cpp ---------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "mlir/Dialect/SPIRV/IR/SPIRVOps.h" + +using namespace mlir; + +#include "mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.cpp.inc" diff --git a/mlir/test/Dialect/SPIRV/IR/image-ops.mlir b/mlir/test/Dialect/SPIRV/IR/image-ops.mlir index 0e8a6df5a1d7b..9a0b8b79e3e01 100644 --- a/mlir/test/Dialect/SPIRV/IR/image-ops.mlir +++ b/mlir/test/Dialect/SPIRV/IR/image-ops.mlir @@ -157,3 +157,221 @@ func.func @image_write_texel_type_mismatch(%arg0 : !spirv.image, vector<2xsi32>, vector<4xi32> spirv.Return } + +// ----- + +//===----------------------------------------------------------------------===// +// spirv.ImageSampleExplicitLod +//===----------------------------------------------------------------------===// + +func.func @sample_explicit_lod(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) -> () { + // CHECK: {{%.*}} = spirv.ImageSampleExplicitLod {{%.*}}, {{%.*}} ["Lod"], {{%.*}} : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xf32> + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Lod"], %arg2 : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @sample_explicit_lod_buffer_dim(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{the Dim operand of the underlying image must not be Buffer}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Lod"], %arg2 : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @sample_explicit_lod_multi_sampled(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{the MS operand of the underlying image type must be SingleSampled}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Lod"], %arg2 : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @sample_explicit_lod_wrong_result_type(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{the result component type must match the image sampled type}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Lod"], %arg2 : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xsi32> + spirv.Return +} + +// ----- + +func.func @sample_explicit_lod_no_lod(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{either Lod or Grad image operands must be present}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Bias"], %arg2 : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xf32> + spirv.Return +} + +// ----- + +//===----------------------------------------------------------------------===// +// spirv.ImageSampleImplicitLod +//===----------------------------------------------------------------------===// + +func.func @sample_implicit_lod(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>) -> () { + // CHECK: {{%.*}} = spirv.ImageSampleImplicitLod {{%.*}}, {{%.*}} : !spirv.sampled_image>, vector<2xf32> -> vector<4xf32> + %0 = spirv.ImageSampleImplicitLod %arg0, %arg1 : !spirv.sampled_image>, vector<2xf32> -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @sample_implicit_lod_buffer(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>) -> () { + // expected-error @+1 {{the Dim operand of the underlying image must not be Buffer}} + %0 = spirv.ImageSampleImplicitLod %arg0, %arg1 : !spirv.sampled_image>, vector<2xf32> -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @sample_implicit_lod_multi_sampled(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>) -> () { + // expected-error @+1 {{the MS operand of the underlying image type must be SingleSampled}} + %0 = spirv.ImageSampleImplicitLod %arg0, %arg1 : !spirv.sampled_image>, vector<2xf32> -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @sample_implicit_lod_wrong_result(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>) -> () { + // expected-error @+1 {{the result component type must match the image sampled type}} + %0 = spirv.ImageSampleImplicitLod %arg0, %arg1 : !spirv.sampled_image>, vector<2xf32> -> vector<4xi32> + spirv.Return +} + +// ----- + +//===----------------------------------------------------------------------===// +// spirv.ImageSampleProjDrefImplicitLod +//===----------------------------------------------------------------------===// + +func.func @sample_implicit_proj_dref(%arg0 : !spirv.sampled_image>, %arg1 : vector<4xf32>, %arg2 : f32) -> () { + // CHECK: {{%.*}} = spirv.ImageSampleProjDrefImplicitLod {{%.*}}, {{%.*}}, {{%.*}} : !spirv.sampled_image>, vector<4xf32>, f32 -> f32 + %0 = spirv.ImageSampleProjDrefImplicitLod %arg0, %arg1, %arg2 : !spirv.sampled_image>, vector<4xf32>, f32 -> f32 + spirv.Return +} + +// ----- + +func.func @sample_implicit_proj_dref_buffer_dim(%arg0 : !spirv.sampled_image>, %arg1 : vector<4xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{the Dim operand of the underlying image must not be Buffer}} + %0 = spirv.ImageSampleProjDrefImplicitLod %arg0, %arg1, %arg2 : !spirv.sampled_image>, vector<4xf32>, f32 -> f32 + spirv.Return +} + +// ----- + +func.func @sample_implicit_proj_dref_multi_sampled(%arg0 : !spirv.sampled_image>, %arg1 : vector<4xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{the MS operand of the underlying image type must be SingleSampled}} + %0 = spirv.ImageSampleProjDrefImplicitLod %arg0, %arg1, %arg2 : !spirv.sampled_image>, vector<4xf32>, f32 -> f32 + spirv.Return +} + +// ----- + +func.func @sample_implicit_proj_dref(%arg0 : !spirv.sampled_image>, %arg1 : vector<4xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{type of 'result' matches image type of 'sampled_image'}} + %0 = spirv.ImageSampleProjDrefImplicitLod %arg0, %arg1, %arg2 : !spirv.sampled_image>, vector<4xf32>, f32 -> i32 + spirv.Return +} + +// ----- + +//===----------------------------------------------------------------------===// +// spirv.ImageOperands: Lod +//===----------------------------------------------------------------------===// + +func.func @grad_and_lod_set(%arg0 : !spirv.sampled_image>, %arg1 : f32, %arg2 : f32) -> () { + // expected-error @+1 {{it is invalid to set both the Lod and Grad bits}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Lod | Grad"], %arg2, %arg2, %arg2 : !spirv.sampled_image>, f32, f32, f32, f32 -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @lod_with_implict_sample(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{Lod is only valid with explicit-lod and fetch instructions}} + %0 = spirv.ImageSampleImplicitLod %arg0, %arg1 ["Lod"], %arg2 : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @lod_too_many_arguments(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{too many image operand arguments have been provided}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Lod"], %arg2, %arg2 : !spirv.sampled_image>, vector<2xf32>, f32, f32 -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @lod_with_rect(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{Lod only be used with an image type that has a dim operand of 1D, 2D, 3D, or Cube}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Lod"], %arg2 : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xf32> + spirv.Return +} + +// TODO: We cannot currently test Lod with MS != 0 as all implemented explicit operations already check for that. + +// TODO: Add Lod tests for fetch operations once available. + +// ----- + +//===----------------------------------------------------------------------===// +// spirv.ImageOperands: Grad +//===----------------------------------------------------------------------===// + +func.func @gard_with_implicit_sample(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : vector<2xf32>) -> () { + // expected-error @+1 {{Grad is only valid with explicit-lod instructions}} + %0 = spirv.ImageSampleImplicitLod %arg0, %arg1 ["Grad"], %arg2, %arg2 : !spirv.sampled_image>, vector<2xf32>, vector<2xf32>, vector<2xf32> -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @gard_not_enough_args(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : vector<2xf32>) -> () { + // expected-error @+1 {{Grad operand requires 2 arguments (scalars or vectors)}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Grad"], %arg2 : !spirv.sampled_image>, vector<2xf32>, vector<2xf32> -> vector<4xf32> + spirv.Return +} + +// TODO: We cannot currently test Grad with MS != 0 as all implemented explicit operations already check for that. + +// ----- + +func.func @grad_arg_size_mismatch(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : vector<3xf32>) -> () { + // expected-error @+1 {{number of components of each Grad argument must equal the number of components in coordinate, minus the array layer component, if present}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Grad"], %arg2, %arg2 : !spirv.sampled_image>, vector<2xf32>, vector<3xf32>, vector<3xf32> -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @gard_arg_wrong_type(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : vector<2xsi32>) -> () { + // expected-error @+1 {{Grad arguments must be a vector of floating-point type}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Grad"], %arg2, %arg2 : !spirv.sampled_image>, vector<2xf32>, vector<2xsi32>, vector<2xsi32> -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @gard_arg_size_mismatch_scalar(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) -> () { + // expected-error @+1 {{number of components of each Grad argument must equal the number of components in coordinate, minus the array layer component, if present}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Grad"], %arg2, %arg2 : !spirv.sampled_image>, vector<2xf32>, f32, f32 -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @gard_int_args(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : i32) -> () { + // expected-error @+1 {{Grad arguments must be a scalar or vector of floating-point type}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Grad"], %arg2, %arg2 : !spirv.sampled_image>, vector<2xf32>, i32, i32 -> vector<4xf32> + spirv.Return +} + +// ----- + +func.func @gard_too_many_args(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : vector<2xf32>) -> () { + // expected-error @+1 {{too many image operand arguments have been provided}} + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Grad"], %arg2, %arg2, %arg2 : !spirv.sampled_image>, vector<2xf32>, vector<2xf32>, vector<2xf32>, vector<2xf32> -> vector<4xf32> + spirv.Return +} diff --git a/mlir/test/Target/SPIRV/image-ops.mlir b/mlir/test/Target/SPIRV/image-ops.mlir index 3c28c3f71bc2a..6dd23844d46a9 100644 --- a/mlir/test/Target/SPIRV/image-ops.mlir +++ b/mlir/test/Target/SPIRV/image-ops.mlir @@ -18,6 +18,21 @@ spirv.module Logical GLSL450 requires #spirv.vce, vector<2xsi32>, vector<4xf32> spirv.Return } + spirv.func @explicit_sample(%arg0 : !spirv.sampled_image>, %arg1 : vector<2xf32>, %arg2 : f32) "None" { + // CHECK: {{%.*}} = spirv.ImageSampleExplicitLod {{%.*}}, {{%.*}} ["Lod"], {{%.*}} : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xf32> + %0 = spirv.ImageSampleExplicitLod %arg0, %arg1 ["Lod"], %arg2 : !spirv.sampled_image>, vector<2xf32>, f32 -> vector<4xf32> + spirv.Return + } + spirv.func @implicit_sample(%arg0 : !spirv.sampled_image>, %arg1 : vector<3xf32>) "None" { + // CHECK: {{%.*}} = spirv.ImageSampleImplicitLod {{%.*}}, {{%.*}} : !spirv.sampled_image>, vector<3xf32> -> vector<4xf32> + %0 = spirv.ImageSampleImplicitLod %arg0, %arg1 : !spirv.sampled_image>, vector<3xf32> -> vector<4xf32> + spirv.Return + } + spirv.func @implicit_sample_proj_dref(%arg0 : !spirv.sampled_image>, %arg1 : vector<4xf32>, %arg2 : f32) "None" { + // CHECK: {{%.*}} = spirv.ImageSampleProjDrefImplicitLod {{%.*}}, {{%.*}}, {{%.*}} : !spirv.sampled_image>, vector<4xf32>, f32 -> f32 + %0 = spirv.ImageSampleProjDrefImplicitLod %arg0, %arg1, %arg2 : !spirv.sampled_image>, vector<4xf32>, f32 -> f32 + spirv.Return + } } // -----