diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index 24a0c8524230c..cf1ed46d422a9 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -13,334 +13,167 @@ include "llvm/IR/Intrinsics.td" -class DXILOpClass; +// Abstraction of DXIL Operation class. +// It encapsulates an associated function signature viz., +// returnTy(param1Ty, param2Ty, ...) represented as a list of LLVMTypes. +// DXIL Ops that belong to a DXILOpClass record the signature of that +// DXILOpClass -// Following is a set of DXIL Operation classes whose names appear to be -// arbitrary, yet need to be a substring of the function name used during -// lowering to DXIL Operation calls. These class name strings are specified -// as the third argument of add_dixil_op in utils/hct/hctdb.py and case converted -// in utils/hct/hctdb_instrhelp.py of DirectXShaderCompiler repo. The function -// name has the format "dx.op..". +class DXILOpClass OpSig> { + list OpSignature = OpSig; +} + +// Concrete definitions of DXIL Op Classes +// Refer to the design document +// (https://github.com/llvm/llvm-project/blob/main/llvm/docs/DirectX/DXILOpTableGenDesign.rst) +// for details about the use of DXIL Op Class name. +// NOTE: The following list is not complete. Classes need to be defined as new DXIL Ops +// are added. defset list OpClasses = { - def acceptHitAndEndSearch : DXILOpClass; - def allocateNodeOutputRecords : DXILOpClass; - def allocateRayQuery : DXILOpClass; - def annotateHandle : DXILOpClass; - def annotateNodeHandle : DXILOpClass; - def annotateNodeRecordHandle : DXILOpClass; - def atomicBinOp : DXILOpClass; - def atomicCompareExchange : DXILOpClass; - def attributeAtVertex : DXILOpClass; - def barrier : DXILOpClass; - def barrierByMemoryHandle : DXILOpClass; - def barrierByMemoryType : DXILOpClass; - def barrierByNodeRecordHandle : DXILOpClass; - def binary : DXILOpClass; - def binaryWithCarryOrBorrow : DXILOpClass; - def binaryWithTwoOuts : DXILOpClass; - def bitcastF16toI16 : DXILOpClass; - def bitcastF32toI32 : DXILOpClass; - def bitcastF64toI64 : DXILOpClass; - def bitcastI16toF16 : DXILOpClass; - def bitcastI32toF32 : DXILOpClass; - def bitcastI64toF64 : DXILOpClass; - def bufferLoad : DXILOpClass; - def bufferStore : DXILOpClass; - def bufferUpdateCounter : DXILOpClass; - def calculateLOD : DXILOpClass; - def callShader : DXILOpClass; - def cbufferLoad : DXILOpClass; - def cbufferLoadLegacy : DXILOpClass; - def checkAccessFullyMapped : DXILOpClass; - def coverage : DXILOpClass; - def createHandle : DXILOpClass; - def createHandleForLib : DXILOpClass; - def createHandleFromBinding : DXILOpClass; - def createHandleFromHeap : DXILOpClass; - def createNodeInputRecordHandle : DXILOpClass; - def createNodeOutputHandle : DXILOpClass; - def cutStream : DXILOpClass; - def cycleCounterLegacy : DXILOpClass; - def discard : DXILOpClass; - def dispatchMesh : DXILOpClass; - def dispatchRaysDimensions : DXILOpClass; - def dispatchRaysIndex : DXILOpClass; - def domainLocation : DXILOpClass; - def dot2 : DXILOpClass; - def dot2AddHalf : DXILOpClass; - def dot3 : DXILOpClass; - def dot4 : DXILOpClass; - def dot4AddPacked : DXILOpClass; - def emitIndices : DXILOpClass; - def emitStream : DXILOpClass; - def emitThenCutStream : DXILOpClass; - def evalCentroid : DXILOpClass; - def evalSampleIndex : DXILOpClass; - def evalSnapped : DXILOpClass; - def finishedCrossGroupSharing : DXILOpClass; - def flattenedThreadIdInGroup : DXILOpClass; - def geometryIndex : DXILOpClass; - def getDimensions : DXILOpClass; - def getInputRecordCount : DXILOpClass; - def getMeshPayload : DXILOpClass; - def getNodeRecordPtr : DXILOpClass; - def getRemainingRecursionLevels : DXILOpClass; - def groupId : DXILOpClass; - def gsInstanceID : DXILOpClass; - def hitKind : DXILOpClass; - def ignoreHit : DXILOpClass; - def incrementOutputCount : DXILOpClass; - def indexNodeHandle : DXILOpClass; - def innerCoverage : DXILOpClass; - def instanceID : DXILOpClass; - def instanceIndex : DXILOpClass; - def isHelperLane : DXILOpClass; - def isSpecialFloat : DXILOpClass; - def legacyDoubleToFloat : DXILOpClass; - def legacyDoubleToSInt32 : DXILOpClass; - def legacyDoubleToUInt32 : DXILOpClass; - def legacyF16ToF32 : DXILOpClass; - def legacyF32ToF16 : DXILOpClass; - def loadInput : DXILOpClass; - def loadOutputControlPoint : DXILOpClass; - def loadPatchConstant : DXILOpClass; - def makeDouble : DXILOpClass; - def minPrecXRegLoad : DXILOpClass; - def minPrecXRegStore : DXILOpClass; - def nodeOutputIsValid : DXILOpClass; - def objectRayDirection : DXILOpClass; - def objectRayOrigin : DXILOpClass; - def objectToWorld : DXILOpClass; - def outputComplete : DXILOpClass; - def outputControlPointID : DXILOpClass; - def pack4x8 : DXILOpClass; - def primitiveID : DXILOpClass; - def primitiveIndex : DXILOpClass; - def quadOp : DXILOpClass; - def quadReadLaneAt : DXILOpClass; - def quadVote : DXILOpClass; - def quaternary : DXILOpClass; - def rawBufferLoad : DXILOpClass; - def rawBufferStore : DXILOpClass; - def rayFlags : DXILOpClass; - def rayQuery_Abort : DXILOpClass; - def rayQuery_CommitNonOpaqueTriangleHit : DXILOpClass; - def rayQuery_CommitProceduralPrimitiveHit : DXILOpClass; - def rayQuery_Proceed : DXILOpClass; - def rayQuery_StateMatrix : DXILOpClass; - def rayQuery_StateScalar : DXILOpClass; - def rayQuery_StateVector : DXILOpClass; - def rayQuery_TraceRayInline : DXILOpClass; - def rayTCurrent : DXILOpClass; - def rayTMin : DXILOpClass; - def renderTargetGetSampleCount : DXILOpClass; - def renderTargetGetSamplePosition : DXILOpClass; - def reportHit : DXILOpClass; - def sample : DXILOpClass; - def sampleBias : DXILOpClass; - def sampleCmp : DXILOpClass; - def sampleCmpBias : DXILOpClass; - def sampleCmpGrad : DXILOpClass; - def sampleCmpLevel : DXILOpClass; - def sampleCmpLevelZero : DXILOpClass; - def sampleGrad : DXILOpClass; - def sampleIndex : DXILOpClass; - def sampleLevel : DXILOpClass; - def setMeshOutputCounts : DXILOpClass; - def splitDouble : DXILOpClass; - def startInstanceLocation : DXILOpClass; - def startVertexLocation : DXILOpClass; - def storeOutput : DXILOpClass; - def storePatchConstant : DXILOpClass; - def storePrimitiveOutput : DXILOpClass; - def storeVertexOutput : DXILOpClass; - def tempRegLoad : DXILOpClass; - def tempRegStore : DXILOpClass; - def tertiary : DXILOpClass; - def texture2DMSGetSamplePosition : DXILOpClass; - def textureGather : DXILOpClass; - def textureGatherCmp : DXILOpClass; - def textureGatherRaw : DXILOpClass; - def textureLoad : DXILOpClass; - def textureStore : DXILOpClass; - def textureStoreSample : DXILOpClass; - def threadId : DXILOpClass; - def threadIdInGroup : DXILOpClass; - def traceRay : DXILOpClass; - def unary : DXILOpClass; - def unaryBits : DXILOpClass; - def unpack4x8 : DXILOpClass; - def viewID : DXILOpClass; - def waveActiveAllEqual : DXILOpClass; - def waveActiveBallot : DXILOpClass; - def waveActiveBit : DXILOpClass; - def waveActiveOp : DXILOpClass; - def waveAllOp : DXILOpClass; - def waveAllTrue : DXILOpClass; - def waveAnyTrue : DXILOpClass; - def waveGetLaneCount : DXILOpClass; - def waveGetLaneIndex : DXILOpClass; - def waveIsFirstLane : DXILOpClass; - def waveMatch : DXILOpClass; - def waveMatrix_Accumulate : DXILOpClass; - def waveMatrix_Annotate : DXILOpClass; - def waveMatrix_Depth : DXILOpClass; - def waveMatrix_Fill : DXILOpClass; - def waveMatrix_LoadGroupShared : DXILOpClass; - def waveMatrix_LoadRawBuf : DXILOpClass; - def waveMatrix_Multiply : DXILOpClass; - def waveMatrix_ScalarOp : DXILOpClass; - def waveMatrix_StoreGroupShared : DXILOpClass; - def waveMatrix_StoreRawBuf : DXILOpClass; - def waveMultiPrefixBitCount : DXILOpClass; - def waveMultiPrefixOp : DXILOpClass; - def wavePrefixOp : DXILOpClass; - def waveReadLaneAt : DXILOpClass; - def waveReadLaneFirst : DXILOpClass; - def worldRayDirection : DXILOpClass; - def worldRayOrigin : DXILOpClass; - def worldToObject : DXILOpClass; - def writeSamplerFeedback : DXILOpClass; - def writeSamplerFeedbackBias : DXILOpClass; - def writeSamplerFeedbackGrad : DXILOpClass; - def writeSamplerFeedbackLevel: DXILOpClass; + def acceptHitAndEndSearch : DXILOpClass<[llvm_void_ty]>; + def allocateRayQuery : DXILOpClass<[llvm_i32_ty, llvm_i32_ty]>; + def attributeAtVertex : DXILOpClass<[llvm_any_ty, llvm_i32_ty, llvm_i32_ty, llvm_i8_ty, llvm_i8_ty]>; + def barrier : DXILOpClass<[llvm_void_ty, llvm_i32_ty]>; + def barrierByMemoryType : DXILOpClass<[llvm_void_ty, llvm_i32_ty, llvm_i32_ty]>; + def binary : DXILOpClass<[llvm_any_ty, LLVMMatchType<0>, LLVMMatchType<0>]>; + def binaryWithCarryOrBorrow : DXILOpClass<[llvm_i32_ty, llvm_any_ty, LLVMMatchType<0>]>; + def dot2 : DXILOpClass; + def dot3 : DXILOpClass; + def dot4 : DXILOpClass; + def flattenedThreadIdInGroup : DXILOpClass<[llvm_i32_ty]>; + def groupId : DXILOpClass<[llvm_i32_ty, llvm_i32_ty]>; + def isSpecialFloat : DXILOpClass<[llvm_i1_ty, llvm_anyfloat_ty]>; + def tertiary : DXILOpClass<[llvm_any_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>; + def threadId : DXILOpClass<[llvm_i32_ty, llvm_i32_ty]>; + def threadIdInGroup : DXILOpClass<[llvm_i32_ty, llvm_i32_ty]>; + def unary : DXILOpClass<[llvm_any_ty, LLVMMatchType<0>]>; // This is a sentinel definition. Hence placed at the end of the list // and not as part of the above alphabetically sorted valid definitions. // Additionally it is capitalized unlike all the others. - def UnknownOpClass: DXILOpClass; + def UnknownOpClass: DXILOpClass<[]>; } -// Several of the overloaded DXIL Operations support for data types -// that are a subset of the overloaded LLVM intrinsics that they map to. -// For e.g., llvm.sin.* intrinsic operates on any floating-point type and -// maps for lowering to DXIL Op Sin. However, valid overloads of DXIL Sin -// operation overloads are half (f16) and float (f32) only. -// -// The following abstracts overload types specific to DXIL operations. +// Abstraction DXIL Operation +class DXILOpPropertiesBase { + int OpCode = 0; // Opcode of DXIL Operation + DXILOpClass OpClass = UnknownOpClass;// Class of DXIL Operation. + Intrinsic LLVMIntrinsic = ?; // LLVM Intrinsic DXIL Operation maps to + list OpOverloadTypes = ?; // Valid overload type + // of DXIL Operation + string Doc = ""; // A short description of the operation +} -class DXILType : LLVMType { - let isAny = 1; - int isI16OrI32 = 0; - int isHalfOrFloat = 0; +class DXILOpProperties overloadTypes, + string doc> : DXILOpPropertiesBase { + int OpCode = opCode; + Intrinsic LLVMIntrinsic = intrinsic; + list OpOverloadTypes = overloadTypes; + string Doc = doc; } -// Concrete records for various overload types supported specifically by -// DXIL Operations. -let isI16OrI32 = 1 in - def llvm_i16ori32_ty : DXILType; +// Concrete definitions of DXIL Operation Properties to corresponding LLVM intrinsic -let isHalfOrFloat = 1 in - def llvm_halforfloat_ty : DXILType; +// IsSpecialFloat Class +let OpClass = isSpecialFloat in { + def IsInf : DXILOpProperties<9, int_dx_isinf, [llvm_half_ty, llvm_float_ty], + "Determines if the specified value is infinite.">; +} -// Abstraction DXIL Operation to LLVM intrinsic -class DXILOpMappingBase { - int OpCode = 0; // Opcode of DXIL Operation - DXILOpClass OpClass = UnknownOpClass;// Class of DXIL Operation. - Intrinsic LLVMIntrinsic = ?; // LLVM Intrinsic DXIL Operation maps to - string Doc = ""; // A short description of the operation - list OpTypes = ?; // Valid types of DXIL Operation in the - // format [returnTy, param1ty, ...] +let OpClass = unary in { + def Abs : DXILOpProperties<6, int_fabs, [llvm_half_ty, llvm_float_ty, llvm_double_ty], + "Returns the absolute value of the input.">; + + def Cos : DXILOpProperties<12, int_cos, [llvm_half_ty, llvm_float_ty], + "Returns cosine(theta) for theta in radians.">; + def Sin : DXILOpProperties<13, int_sin, [llvm_half_ty, llvm_float_ty], + "Returns sine(theta) for theta in radians.">; + def Tan : DXILOpProperties<14, int_tan, [llvm_half_ty, llvm_float_ty], + "Returns tangent(theta) for theta in radians.">; + def Exp2 : DXILOpProperties<21, int_exp2, [llvm_half_ty, llvm_float_ty], + "Returns the base 2 exponential, or 2**x, of the" + " specified value. exp2(x) = 2**x.">; + def Frac : DXILOpProperties<22, int_dx_frac, [llvm_half_ty, llvm_float_ty], + "Returns a fraction from 0 to 1 that represents the" + " decimal part of the input.">; + def Log2 : DXILOpProperties<23, int_log2, [llvm_half_ty, llvm_float_ty], + "Returns the base-2 logarithm of the specified value.">; + def Sqrt : DXILOpProperties<24, int_sqrt, [llvm_half_ty, llvm_float_ty], + "Returns the square root of the specified floating-point" + "value, per component.">; + def RSqrt : DXILOpProperties<25, int_dx_rsqrt, [llvm_half_ty, llvm_float_ty], + "Returns the reciprocal of the square root of the" + " specified value. rsqrt(x) = 1 / sqrt(x).">; + def Round : DXILOpProperties<26, int_roundeven, [llvm_half_ty, llvm_float_ty], + "Returns the input rounded to the nearest integer" + "within a floating-point type.">; + def Floor : DXILOpProperties<27, int_floor, [llvm_half_ty, llvm_float_ty], + "Returns the largest integer that is less than or equal to the input.">; + def Ceil : DXILOpProperties<28, int_ceil, [llvm_half_ty, llvm_float_ty], + "Returns the smallest integer that is greater than or equal to the input.">; + def Trunc : DXILOpProperties<29, int_trunc, [llvm_half_ty, llvm_float_ty], + "Returns the specified value truncated to the integer component.">; + def Rbits : DXILOpProperties<30, int_bitreverse, [llvm_i16_ty, llvm_i32_ty, llvm_i64_ty], + "Returns the specified value with its bits reversed.">; +} + +let OpClass = binary in { +// Float overloads + def FMax : DXILOpProperties<35, int_maxnum, [llvm_half_ty, llvm_float_ty, llvm_double_ty], + "Float maximum. FMax(a,b) = a > b ? a : b">; + def FMin : DXILOpProperties<36, int_minnum, [llvm_half_ty, llvm_float_ty, llvm_double_ty], + "Float minimum. FMin(a,b) = a < b ? a : b">; +// Int overloads + def SMax : DXILOpProperties<37, int_smax, [llvm_i16_ty, llvm_i32_ty, llvm_i64_ty], + "Signed integer maximum. SMax(a,b) = a > b ? a : b">; + def SMin : DXILOpProperties<38, int_smin, [llvm_i16_ty, llvm_i32_ty, llvm_i64_ty], + "Signed integer minimum. SMin(a,b) = a < b ? a : b">; + def UMax : DXILOpProperties<39, int_umax, [llvm_i16_ty, llvm_i32_ty, llvm_i64_ty], + "Unsigned integer maximum. UMax(a,b) = a > b ? a : b">; + def UMin : DXILOpProperties<40, int_umin, [llvm_i16_ty, llvm_i32_ty, llvm_i64_ty], + "Unsigned integer minimum. UMin(a,b) = a < b ? a : b">; } -class DXILOpMapping opTys = []> : DXILOpMappingBase { - int OpCode = opCode; // Opcode corresponding to DXIL Operation - DXILOpClass OpClass = opClass; // Class of DXIL Operation. - Intrinsic LLVMIntrinsic = intrinsic; // LLVM Intrinsic the DXIL Operation maps - string Doc = doc; // to a short description of the operation - list OpTypes = !if(!eq(!size(opTys), 0), LLVMIntrinsic.Types, opTys); +let OpClass = tertiary in { + def FMad : DXILOpProperties<46, int_fmuladd, [llvm_half_ty, llvm_float_ty, llvm_double_ty], + "Floating point arithmetic multiply/add operation." + " fmad(m,a,b) = m * a + b.">; +// Int overloads +def IMad : DXILOpProperties<48, int_dx_imad, [llvm_i16_ty, llvm_i32_ty, llvm_i64_ty], + "Signed integer arithmetic multiply/add operation." + " imad(m,a,b) = m * a + b.">; +def UMad : DXILOpProperties<49, int_dx_umad, [llvm_i16_ty, llvm_i32_ty, llvm_i64_ty], + "Unsigned integer arithmetic multiply/add operation." + " umad(m,a, = m * a + b.">; } -// Concrete definition of DXIL Operation mapping to corresponding LLVM intrinsic -def Abs : DXILOpMapping<6, unary, int_fabs, - "Returns the absolute value of the input.">; -def IsInf : DXILOpMapping<9, isSpecialFloat, int_dx_isinf, - "Determines if the specified value is infinite.", - [llvm_i1_ty, llvm_halforfloat_ty]>; -def Cos : DXILOpMapping<12, unary, int_cos, - "Returns cosine(theta) for theta in radians.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Sin : DXILOpMapping<13, unary, int_sin, - "Returns sine(theta) for theta in radians.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Tan : DXILOpMapping<14, unary, int_tan, - "Returns tangent(theta) for theta in radians.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Exp2 : DXILOpMapping<21, unary, int_exp2, - "Returns the base 2 exponential, or 2**x, of the specified value." - "exp2(x) = 2**x.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Frac : DXILOpMapping<22, unary, int_dx_frac, - "Returns a fraction from 0 to 1 that represents the " - "decimal part of the input.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Log2 : DXILOpMapping<23, unary, int_log2, - "Returns the base-2 logarithm of the specified value.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Sqrt : DXILOpMapping<24, unary, int_sqrt, - "Returns the square root of the specified floating-point" - "value, per component.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def RSqrt : DXILOpMapping<25, unary, int_dx_rsqrt, - "Returns the reciprocal of the square root of the specified value." - "rsqrt(x) = 1 / sqrt(x).", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Round : DXILOpMapping<26, unary, int_roundeven, - "Returns the input rounded to the nearest integer" - "within a floating-point type.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Floor : DXILOpMapping<27, unary, int_floor, - "Returns the largest integer that is less than or equal to the input.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Ceil : DXILOpMapping<28, unary, int_ceil, - "Returns the smallest integer that is greater than or equal to the input.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Trunc : DXILOpMapping<29, unary, int_trunc, - "Returns the specified value truncated to the integer component.", - [llvm_halforfloat_ty, LLVMMatchType<0>]>; -def Rbits : DXILOpMapping<30, unary, int_bitreverse, - "Returns the specified value with its bits reversed.", - [llvm_anyint_ty, LLVMMatchType<0>]>; -def FMax : DXILOpMapping<35, binary, int_maxnum, - "Float maximum. FMax(a,b) = a > b ? a : b">; -def FMin : DXILOpMapping<36, binary, int_minnum, - "Float minimum. FMin(a,b) = a < b ? a : b">; -def SMax : DXILOpMapping<37, binary, int_smax, - "Signed integer maximum. SMax(a,b) = a > b ? a : b">; -def SMin : DXILOpMapping<38, binary, int_smin, - "Signed integer minimum. SMin(a,b) = a < b ? a : b">; -def UMax : DXILOpMapping<39, binary, int_umax, - "Unsigned integer maximum. UMax(a,b) = a > b ? a : b">; -def UMin : DXILOpMapping<40, binary, int_umin, - "Unsigned integer minimum. UMin(a,b) = a < b ? a : b">; -def FMad : DXILOpMapping<46, tertiary, int_fmuladd, - "Floating point arithmetic multiply/add operation. fmad(m,a,b) = m * a + b.">; -def IMad : DXILOpMapping<48, tertiary, int_dx_imad, - "Signed integer arithmetic multiply/add operation. imad(m,a,b) = m * a + b.">; -def UMad : DXILOpMapping<49, tertiary, int_dx_umad, - "Unsigned integer arithmetic multiply/add operation. umad(m,a,b) = m * a + b.">; -let OpTypes = !listconcat([llvm_halforfloat_ty], !listsplat(llvm_halforfloat_ty, 4)) in - def Dot2 : DXILOpMapping<54, dot2, int_dx_dot2, - "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + a[n]*b[n] where n is between 0 and 1">; -let OpTypes = !listconcat([llvm_halforfloat_ty], !listsplat(llvm_halforfloat_ty, 6)) in - def Dot3 : DXILOpMapping<55, dot3, int_dx_dot3, - "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + a[n]*b[n] where n is between 0 and 2">; -let OpTypes = !listconcat([llvm_halforfloat_ty], !listsplat(llvm_halforfloat_ty, 8)) in - def Dot4 : DXILOpMapping<56, dot4, int_dx_dot4, - "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + a[n]*b[n] where n is between 0 and 3">; -def ThreadId : DXILOpMapping<93, threadId, int_dx_thread_id, - "Reads the thread ID">; -def GroupId : DXILOpMapping<94, groupId, int_dx_group_id, - "Reads the group ID (SV_GroupID)">; -def ThreadIdInGroup : DXILOpMapping<95, threadIdInGroup, - int_dx_thread_id_in_group, - "Reads the thread ID within the group " - "(SV_GroupThreadID)">; -def FlattenedThreadIdInGroup : DXILOpMapping<96, flattenedThreadIdInGroup, - int_dx_flattened_thread_id_in_group, - "Provides a flattened index for a " - "given thread within a given " - "group (SV_GroupIndex)">; +let OpClass = dot2 in + def Dot2 : DXILOpProperties<54, int_dx_dot2, [llvm_half_ty, llvm_float_ty], + "dot product of two float vectors Dot(a,b) = a[0]*b[0] +" + " ... + a[n]*b[n] where n is between 0 and 1">; +let OpClass = dot3 in + def Dot3 : DXILOpProperties<55, int_dx_dot3, [llvm_half_ty, llvm_float_ty], + "dot product of two float vectors Dot(a,b) = a[0]*b[0] +" + " ... + a[n]*b[n] where n is between 0 and 2">; +let OpClass = dot4 in + def Dot4 : DXILOpProperties<56, int_dx_dot4, [llvm_half_ty, llvm_float_ty], + "dot product of two float vectors Dot(a,b) = a[0]*b[0] +" + " ... + a[n]*b[n] where n is between 0 and 3">; +let OpClass = threadId in + def ThreadId : DXILOpProperties<93, int_dx_thread_id, [llvm_i32_ty], + "Reads the thread ID">; +let OpClass = groupId in + def GroupId : DXILOpProperties<94, int_dx_group_id, [llvm_i32_ty], + "Reads the group ID (SV_GroupID)">; +let OpClass = threadIdInGroup in + def ThreadIdInGroup : DXILOpProperties<95, int_dx_thread_id_in_group, [llvm_i32_ty], + "Reads the thread ID within the group " + "(SV_GroupThreadID)">; +let OpClass = flattenedThreadIdInGroup in + def FlattenedThreadIdInGroup : DXILOpProperties<96, int_dx_flattened_thread_id_in_group, + [llvm_i32_ty], + "Provides a flattened index for a given" + " thread within a given group (SV_GroupIndex)">; diff --git a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp index 0b3982ea0f438..dab3d6bb02da5 100644 --- a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp +++ b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp @@ -308,14 +308,15 @@ Type *DXILOpBuilder::getOverloadTy(dxil::OpCode OpCode, FunctionType *FT) { } } - // Prop->OverloadParamIndex is 0, overload type is FT->getReturnType(). + // Consider FT->getReturnType() as default overload type, unless + // Prop->OverloadParamIndex != 0. Type *OverloadType = FT->getReturnType(); if (Prop->OverloadParamIndex != 0) { // Skip Return Type. OverloadType = FT->getParamType(Prop->OverloadParamIndex - 1); } - auto ParamKinds = getOpCodeParameterKind(*Prop); + const auto *ParamKinds = getOpCodeParameterKind(*Prop); auto Kind = ParamKinds[Prop->OverloadParamIndex]; // For ResRet and CBufferRet, OverloadTy is in field of StructType. if (Kind == ParameterKind::CBufferRet || diff --git a/llvm/lib/Target/DirectX/DXILOpBuilder.h b/llvm/lib/Target/DirectX/DXILOpBuilder.h index 5babeae470178..2b705d43afd2f 100644 --- a/llvm/lib/Target/DirectX/DXILOpBuilder.h +++ b/llvm/lib/Target/DirectX/DXILOpBuilder.h @@ -30,9 +30,12 @@ class DXILOpBuilder { public: DXILOpBuilder(Module &M, IRBuilderBase &B) : M(M), B(B) {} /// Create an instruction that calls DXIL Op with return type, specified - /// opcode, and call arguments. \param OpCode Opcode of the DXIL Op call - /// constructed \param ReturnTy Return type of the DXIL Op call constructed + /// opcode, and call arguments. + /// + /// \param OpCode Opcode of the DXIL Op call constructed + /// \param ReturnTy Return type of the DXIL Op call constructed /// \param OverloadTy Overload type of the DXIL Op call constructed + /// \param Args Arguments for the DXIL Op call constructed /// \return DXIL Op call constructed CallInst *createDXILOpCall(dxil::OpCode OpCode, Type *ReturnTy, Type *OverloadTy, SmallVector Args); diff --git a/llvm/test/CodeGen/DirectX/abs.ll b/llvm/test/CodeGen/DirectX/abs.ll index 822580e8c089a..73bc00042ac16 100644 --- a/llvm/test/CodeGen/DirectX/abs.ll +++ b/llvm/test/CodeGen/DirectX/abs.ll @@ -1,5 +1,5 @@ ; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK ; Make sure dxil operation function calls for abs are generated for int16_t/int/int64_t. diff --git a/llvm/test/CodeGen/DirectX/ceil.ll b/llvm/test/CodeGen/DirectX/ceil.ll index 1585471467801..c7583cb70ba19 100644 --- a/llvm/test/CodeGen/DirectX/ceil.ll +++ b/llvm/test/CodeGen/DirectX/ceil.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for ceil are generated for float and half. @@ -18,3 +18,4 @@ entry: declare half @llvm.ceil.f16(half) declare float @llvm.ceil.f32(float) + diff --git a/llvm/test/CodeGen/DirectX/ceil_error.ll b/llvm/test/CodeGen/DirectX/ceil_error.ll index 1b554d8715566..da6f083550186 100644 --- a/llvm/test/CodeGen/DirectX/ceil_error.ll +++ b/llvm/test/CodeGen/DirectX/ceil_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation ceil does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/clamp.ll b/llvm/test/CodeGen/DirectX/clamp.ll index f122313b8d7dc..2f29e4479f9ca 100644 --- a/llvm/test/CodeGen/DirectX/clamp.ll +++ b/llvm/test/CodeGen/DirectX/clamp.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for clamp/uclamp are generated for half/float/double/i16/i32/i64. diff --git a/llvm/test/CodeGen/DirectX/cos.ll b/llvm/test/CodeGen/DirectX/cos.ll index 00f2e2c3f6e5a..72f4bfca23f9d 100644 --- a/llvm/test/CodeGen/DirectX/cos.ll +++ b/llvm/test/CodeGen/DirectX/cos.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for cos are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/cos_error.ll b/llvm/test/CodeGen/DirectX/cos_error.ll index a074f5b493dfd..6bb85a7cec1e3 100644 --- a/llvm/test/CodeGen/DirectX/cos_error.ll +++ b/llvm/test/CodeGen/DirectX/cos_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation cos does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/dot2_error.ll b/llvm/test/CodeGen/DirectX/dot2_error.ll index a27bfaedacd57..54780d18e71fb 100644 --- a/llvm/test/CodeGen/DirectX/dot2_error.ll +++ b/llvm/test/CodeGen/DirectX/dot2_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation dot2 does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload diff --git a/llvm/test/CodeGen/DirectX/dot3_error.ll b/llvm/test/CodeGen/DirectX/dot3_error.ll index eb69fb145038a..242716b0b71ba 100644 --- a/llvm/test/CodeGen/DirectX/dot3_error.ll +++ b/llvm/test/CodeGen/DirectX/dot3_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation dot3 does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload diff --git a/llvm/test/CodeGen/DirectX/dot4_error.ll b/llvm/test/CodeGen/DirectX/dot4_error.ll index 5cd632684c0c0..731adda153def 100644 --- a/llvm/test/CodeGen/DirectX/dot4_error.ll +++ b/llvm/test/CodeGen/DirectX/dot4_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation dot4 does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload diff --git a/llvm/test/CodeGen/DirectX/exp.ll b/llvm/test/CodeGen/DirectX/exp.ll index fdafc1438cf0e..f67e2744c4ee3 100644 --- a/llvm/test/CodeGen/DirectX/exp.ll +++ b/llvm/test/CodeGen/DirectX/exp.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for exp are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/exp2_error.ll b/llvm/test/CodeGen/DirectX/exp2_error.ll index 6b9126785fd4b..4d13f936eb6be 100644 --- a/llvm/test/CodeGen/DirectX/exp2_error.ll +++ b/llvm/test/CodeGen/DirectX/exp2_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation exp2 does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload diff --git a/llvm/test/CodeGen/DirectX/fabs.ll b/llvm/test/CodeGen/DirectX/fabs.ll index 3b3f8aa9a4a92..1b3e91dcfb30f 100644 --- a/llvm/test/CodeGen/DirectX/fabs.ll +++ b/llvm/test/CodeGen/DirectX/fabs.ll @@ -1,8 +1,7 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for abs are generated for float, half, and double. - ; CHECK-LABEL: fabs_half define noundef half @fabs_half(half noundef %a) { entry: diff --git a/llvm/test/CodeGen/DirectX/fdot.ll b/llvm/test/CodeGen/DirectX/fdot.ll index 3e13b2ad2650c..bad65cfb1e561 100644 --- a/llvm/test/CodeGen/DirectX/fdot.ll +++ b/llvm/test/CodeGen/DirectX/fdot.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for dot are generated for int/uint vectors. diff --git a/llvm/test/CodeGen/DirectX/floor.ll b/llvm/test/CodeGen/DirectX/floor.ll index b033e2eaa491e..f667cab4aa249 100644 --- a/llvm/test/CodeGen/DirectX/floor.ll +++ b/llvm/test/CodeGen/DirectX/floor.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for floor are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/floor_error.ll b/llvm/test/CodeGen/DirectX/floor_error.ll index 3b51a4b543b7f..e3190e5afb63f 100644 --- a/llvm/test/CodeGen/DirectX/floor_error.ll +++ b/llvm/test/CodeGen/DirectX/floor_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation floor does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/fmax.ll b/llvm/test/CodeGen/DirectX/fmax.ll index aff722c29309c..05852ee33486d 100644 --- a/llvm/test/CodeGen/DirectX/fmax.ll +++ b/llvm/test/CodeGen/DirectX/fmax.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for fmax are generated for half/float/double. diff --git a/llvm/test/CodeGen/DirectX/fmin.ll b/llvm/test/CodeGen/DirectX/fmin.ll index 2f7c209f0278a..1c6c7ca3f2e38 100644 --- a/llvm/test/CodeGen/DirectX/fmin.ll +++ b/llvm/test/CodeGen/DirectX/fmin.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for fmin are generated for half/float/double. diff --git a/llvm/test/CodeGen/DirectX/frac_error.ll b/llvm/test/CodeGen/DirectX/frac_error.ll index ebce76105ad4d..1bc3558ab0c9a 100644 --- a/llvm/test/CodeGen/DirectX/frac_error.ll +++ b/llvm/test/CodeGen/DirectX/frac_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation frac does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/idot.ll b/llvm/test/CodeGen/DirectX/idot.ll index 9f89a8d6d340d..8fad7b00700f5 100644 --- a/llvm/test/CodeGen/DirectX/idot.ll +++ b/llvm/test/CodeGen/DirectX/idot.ll @@ -1,5 +1,5 @@ ; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK ; Make sure dxil operation function calls for dot are generated for int/uint vectors. diff --git a/llvm/test/CodeGen/DirectX/isinf.ll b/llvm/test/CodeGen/DirectX/isinf.ll index e2975da90bfc1..bbacaa0f99bac 100644 --- a/llvm/test/CodeGen/DirectX/isinf.ll +++ b/llvm/test/CodeGen/DirectX/isinf.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library < %s | FileCheck %s ; Make sure dxil operation function calls for isinf are generated for float and half. ; CHECK: call i1 @dx.op.isSpecialFloat.f32(i32 9, float %{{.*}}) diff --git a/llvm/test/CodeGen/DirectX/isinf_error.ll b/llvm/test/CodeGen/DirectX/isinf_error.ll index 95b2d0cabcc43..39b83554d74d0 100644 --- a/llvm/test/CodeGen/DirectX/isinf_error.ll +++ b/llvm/test/CodeGen/DirectX/isinf_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation isinf does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/log.ll b/llvm/test/CodeGen/DirectX/log.ll index 172c3bfed3b77..36344cf7a5f6d 100644 --- a/llvm/test/CodeGen/DirectX/log.ll +++ b/llvm/test/CodeGen/DirectX/log.ll @@ -1,5 +1,5 @@ ; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK ; Make sure dxil operation function calls for log are generated. diff --git a/llvm/test/CodeGen/DirectX/log10.ll b/llvm/test/CodeGen/DirectX/log10.ll index d4f827a0d1af8..8e40ccd8d1331 100644 --- a/llvm/test/CodeGen/DirectX/log10.ll +++ b/llvm/test/CodeGen/DirectX/log10.ll @@ -1,5 +1,5 @@ ; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK ; Make sure dxil operation function calls for log10 are generated. diff --git a/llvm/test/CodeGen/DirectX/log2.ll b/llvm/test/CodeGen/DirectX/log2.ll index 2164d4db9396d..d6a7ba0b7dda7 100644 --- a/llvm/test/CodeGen/DirectX/log2.ll +++ b/llvm/test/CodeGen/DirectX/log2.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for log2 are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/log2_error.ll b/llvm/test/CodeGen/DirectX/log2_error.ll index a26f6e8c3117f..b8876854d389f 100644 --- a/llvm/test/CodeGen/DirectX/log2_error.ll +++ b/llvm/test/CodeGen/DirectX/log2_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation log2 does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/pow.ll b/llvm/test/CodeGen/DirectX/pow.ll index 25ce0fe731d0b..4ed886532f590 100644 --- a/llvm/test/CodeGen/DirectX/pow.ll +++ b/llvm/test/CodeGen/DirectX/pow.ll @@ -1,5 +1,5 @@ ; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK ; Make sure dxil operation function calls for pow are generated. diff --git a/llvm/test/CodeGen/DirectX/reversebits.ll b/llvm/test/CodeGen/DirectX/reversebits.ll index b6a7a1bc6152e..1ade57b40100f 100644 --- a/llvm/test/CodeGen/DirectX/reversebits.ll +++ b/llvm/test/CodeGen/DirectX/reversebits.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for reversebits are generated for all integer types. diff --git a/llvm/test/CodeGen/DirectX/round.ll b/llvm/test/CodeGen/DirectX/round.ll index e0a3772ebca8f..db953fb29c204 100644 --- a/llvm/test/CodeGen/DirectX/round.ll +++ b/llvm/test/CodeGen/DirectX/round.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for round are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/round_error.ll b/llvm/test/CodeGen/DirectX/round_error.ll index 2d27fbb5ee20d..9d2a4e778a924 100644 --- a/llvm/test/CodeGen/DirectX/round_error.ll +++ b/llvm/test/CodeGen/DirectX/round_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; This test is expected to fail with the following error ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/rsqrt.ll b/llvm/test/CodeGen/DirectX/rsqrt.ll index 52af0e62220b3..054c84483ef82 100644 --- a/llvm/test/CodeGen/DirectX/rsqrt.ll +++ b/llvm/test/CodeGen/DirectX/rsqrt.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for rsqrt are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/rsqrt_error.ll b/llvm/test/CodeGen/DirectX/rsqrt_error.ll index 9cd5002c20f7e..5e29e37113d19 100644 --- a/llvm/test/CodeGen/DirectX/rsqrt_error.ll +++ b/llvm/test/CodeGen/DirectX/rsqrt_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation rsqrt does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/sin.ll b/llvm/test/CodeGen/DirectX/sin.ll index 1f285c433581c..ae2eaba5142ca 100644 --- a/llvm/test/CodeGen/DirectX/sin.ll +++ b/llvm/test/CodeGen/DirectX/sin.ll @@ -1,8 +1,16 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s -check-prefix=SM6_3 +; SM6_3: call half @dx.op.unary.f16(i32 13, half %{{.*}}) +; SM6_3: call float @dx.op.unary.f32(i32 13, float %{{.*}}) -; Make sure dxil operation function calls for sin are generated for float and half. -; CHECK:call float @dx.op.unary.f32(i32 13, float %{{.*}}) -; CHECK:call half @dx.op.unary.f16(i32 13, half %{{.*}}) +; Function Attrs: noinline nounwind optnone +define noundef half @sin_half(half noundef %a) #0 { +entry: + %a.addr = alloca half, align 2 + store half %a, ptr %a.addr, align 2 + %0 = load half, ptr %a.addr, align 2 + %1 = call half @llvm.sin.f16(half %0) + ret half %1 +} ; Function Attrs: noinline nounwind optnone define noundef float @sin_float(float noundef %a) #0 { @@ -14,12 +22,3 @@ entry: ret float %1 } -; Function Attrs: noinline nounwind optnone -define noundef half @sin_half(half noundef %a) #0 { -entry: - %a.addr = alloca half, align 2 - store half %a, ptr %a.addr, align 2 - %0 = load half, ptr %a.addr, align 2 - %1 = call half @llvm.sin.f16(half %0) - ret half %1 -} diff --git a/llvm/test/CodeGen/DirectX/sin_error.ll b/llvm/test/CodeGen/DirectX/sin_error.ll index ece0e530315b2..2e4c25058ca96 100644 --- a/llvm/test/CodeGen/DirectX/sin_error.ll +++ b/llvm/test/CodeGen/DirectX/sin_error.ll @@ -1,7 +1,9 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.0-library %s 2>&1 | FileCheck %s --check-prefix=SM6_0_DOUBLE +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s --check-prefix=SM6_3_DOUBLE -; DXIL operation sin does not support double overload type -; CHECK: LLVM ERROR: Invalid Overload +; Double is not valid in any Shader Model version +; SM6_0_DOUBLE: LLVM ERROR: Invalid Overload +; SM6_3_DOUBLE: LLVM ERROR: Invalid Overload define noundef double @sin_double(double noundef %a) #0 { entry: diff --git a/llvm/test/CodeGen/DirectX/smax.ll b/llvm/test/CodeGen/DirectX/smax.ll index 8b2406782c093..bcda51cb0bfba 100644 --- a/llvm/test/CodeGen/DirectX/smax.ll +++ b/llvm/test/CodeGen/DirectX/smax.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for smax are generated for i16/i32/i64. diff --git a/llvm/test/CodeGen/DirectX/smin.ll b/llvm/test/CodeGen/DirectX/smin.ll index b2b40a1b62433..8d4884704df21 100644 --- a/llvm/test/CodeGen/DirectX/smin.ll +++ b/llvm/test/CodeGen/DirectX/smin.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for smin are generated for i16/i32/i64. diff --git a/llvm/test/CodeGen/DirectX/sqrt.ll b/llvm/test/CodeGen/DirectX/sqrt.ll index 76a572efd2055..792fbc8d0614d 100644 --- a/llvm/test/CodeGen/DirectX/sqrt.ll +++ b/llvm/test/CodeGen/DirectX/sqrt.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for sqrt are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/sqrt_error.ll b/llvm/test/CodeGen/DirectX/sqrt_error.ll index fffa2e19b80fa..1477abc62c13a 100644 --- a/llvm/test/CodeGen/DirectX/sqrt_error.ll +++ b/llvm/test/CodeGen/DirectX/sqrt_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation sqrt does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/tan.ll b/llvm/test/CodeGen/DirectX/tan.ll index 567ab02d40f91..bc4d585e0984b 100644 --- a/llvm/test/CodeGen/DirectX/tan.ll +++ b/llvm/test/CodeGen/DirectX/tan.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.0-library %s | FileCheck %s ; Make sure dxil operation function calls for tan are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/tan_error.ll b/llvm/test/CodeGen/DirectX/tan_error.ll index c870c36f54925..33efc63254130 100644 --- a/llvm/test/CodeGen/DirectX/tan_error.ll +++ b/llvm/test/CodeGen/DirectX/tan_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.0-library %s 2>&1 | FileCheck %s ; DXIL operation tan does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload diff --git a/llvm/test/CodeGen/DirectX/trunc.ll b/llvm/test/CodeGen/DirectX/trunc.ll index 2072f28cef50a..f00b737da4dbb 100644 --- a/llvm/test/CodeGen/DirectX/trunc.ll +++ b/llvm/test/CodeGen/DirectX/trunc.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for trunc are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/trunc_error.ll b/llvm/test/CodeGen/DirectX/trunc_error.ll index 751b0b94c280d..ccc7b1df879ee 100644 --- a/llvm/test/CodeGen/DirectX/trunc_error.ll +++ b/llvm/test/CodeGen/DirectX/trunc_error.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s +; RUN: not opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s ; DXIL operation trunc does not support double overload type ; CHECK: LLVM ERROR: Invalid Overload Type diff --git a/llvm/test/CodeGen/DirectX/umax.ll b/llvm/test/CodeGen/DirectX/umax.ll index be0f557fc8da6..a4bd66ef0bd6c 100644 --- a/llvm/test/CodeGen/DirectX/umax.ll +++ b/llvm/test/CodeGen/DirectX/umax.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for umax are generated for i16/i32/i64. diff --git a/llvm/test/CodeGen/DirectX/umin.ll b/llvm/test/CodeGen/DirectX/umin.ll index 5051c71174489..a551f8ff3bfa9 100644 --- a/llvm/test/CodeGen/DirectX/umin.ll +++ b/llvm/test/CodeGen/DirectX/umin.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower < %s | FileCheck %s +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for umin are generated for i16/i32/i64. diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp index 0439df8067ede..6af1094cf929c 100644 --- a/llvm/utils/TableGen/DXILEmitter.cpp +++ b/llvm/utils/TableGen/DXILEmitter.cpp @@ -17,23 +17,18 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSet.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/CodeGenTypes/MachineValueType.h" #include "llvm/Support/DXILABI.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/TableGenBackend.h" #include +#include using namespace llvm; using namespace llvm::dxil; namespace { -struct DXILShaderModel { - int Major = 0; - int Minor = 0; -}; - struct DXILOperationDesc { std::string OpName; // name of DXIL operation int OpCode; // ID of DXIL operation @@ -41,23 +36,14 @@ struct DXILOperationDesc { StringRef Doc; // the documentation description of this instruction SmallVector OpTypes; // Vector of operand type records - // return type is at index 0 + SmallVector OpOverloads; // Vector of fixed types valid for + // operation overloads SmallVector OpAttributes; // operation attribute represented as strings StringRef Intrinsic; // The llvm intrinsic map to OpName. Default is "" which // means no map exists - bool IsDeriv = false; // whether this is some kind of derivative - bool IsGradient = false; // whether this requires a gradient calculation - bool IsFeedback = false; // whether this is a sampler feedback op - bool IsWave = - false; // whether this requires in-wave, cross-lane functionality - bool RequiresUniformInputs = false; // whether this operation requires that - // all of its inputs are uniform across - // the wave SmallVector ShaderStages; // shader stages to which this applies, empty for all. - DXILShaderModel ShaderModel; // minimum shader model required - DXILShaderModel ShaderModelTranslated; // minimum shader model required with - // translation by linker int OverloadParamIndex; // Index of parameter with overload type. // -1 : no overload types SmallVector counters; // counters for this inst. @@ -91,15 +77,11 @@ static ParameterKind getParameterKind(const Record *R) { return ParameterKind::I32; case MVT::fAny: case MVT::iAny: + case MVT::Any: return ParameterKind::Overload; - case MVT::Other: - // Handle DXIL-specific overload types - if (R->getValueAsInt("isHalfOrFloat") || R->getValueAsInt("isI16OrI32")) { - return ParameterKind::Overload; - } - [[fallthrough]]; default: - llvm_unreachable("Support for specified DXIL Type not yet implemented"); + llvm_unreachable( + "Support for specified parameter type not yet implemented"); } } @@ -113,9 +95,9 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) { OpCode = R->getValueAsInt("OpCode"); Doc = R->getValueAsString("Doc"); - - auto TypeRecs = R->getValueAsListOfDefs("OpTypes"); - unsigned TypeRecsSize = TypeRecs.size(); + Record *OpClassRec = R->getValueAsDef("OpClass"); + auto ParamTypeRecs = OpClassRec->getValueAsListOfDefs("OpSignature"); + unsigned ParamTypeRecsSize = ParamTypeRecs.size(); // Populate OpTypes with return type and parameter types // Parameter indices of overloaded parameters. @@ -124,32 +106,29 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) { // the comment before the definition of class LLVMMatchType in // llvm/IR/Intrinsics.td SmallVector OverloadParamIndices; - for (unsigned i = 0; i < TypeRecsSize; i++) { - auto TR = TypeRecs[i]; + for (unsigned I = 0; I < ParamTypeRecsSize; I++) { + auto TR = ParamTypeRecs[I]; // Track operation parameter indices of any overload types - auto isAny = TR->getValueAsInt("isAny"); - if (isAny == 1) { + auto IsAny = TR->getValueAsInt("isAny"); + if (IsAny == 1) { // TODO: At present it is expected that all overload types in a DXIL Op // are of the same type. Hence, OverloadParamIndices will have only one // element. This implies we do not need a vector. However, until more // (all?) DXIL Ops are added in DXIL.td, a vector is being used to flag // cases this assumption would not hold. if (!OverloadParamIndices.empty()) { - bool knownType = true; + bool KnownType = true; // Ensure that the same overload type registered earlier is being used for (auto Idx : OverloadParamIndices) { - if (TR != TypeRecs[Idx]) { - knownType = false; + if (TR != ParamTypeRecs[Idx]) { + KnownType = false; break; } } - if (!knownType) { - report_fatal_error("Specification of multiple differing overload " - "parameter types not yet supported", - false); - } + assert(KnownType && "Specification of multiple differing overload " + "parameter types not yet supported"); } else { - OverloadParamIndices.push_back(i); + OverloadParamIndices.push_back(I); } } // Populate OpTypes array according to the type specification @@ -160,7 +139,7 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) { // Get the parameter index of anonymous type, TR, references auto OLParamIndex = TR->getValueAsInt("Number"); // Resolve and insert the type to that at OLParamIndex - OpTypes.emplace_back(TypeRecs[OLParamIndex]); + OpTypes.emplace_back(ParamTypeRecs[OLParamIndex]); } else { // A non-anonymous type. Just record it in OpTypes OpTypes.emplace_back(TR); @@ -170,11 +149,20 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) { // Set the index of the overload parameter, if any. OverloadParamIndex = -1; // default; indicating none if (!OverloadParamIndices.empty()) { - if (OverloadParamIndices.size() > 1) - report_fatal_error("Multiple overload type specification not supported", - false); + assert(OverloadParamIndices.size() == 1 && + "Multiple overload type specification not supported"); OverloadParamIndex = OverloadParamIndices[0]; } + + // Get valid overload types of the Operation + std::vector OverloadTypeRecs = + R->getValueAsListOfDefs("OpOverloadTypes"); + unsigned OverloadTypeRecsSize = OverloadTypeRecs.size(); + // Populate OpOverloads with + for (unsigned I = 0; I < OverloadTypeRecsSize; I++) { + OpOverloads.emplace_back(OverloadTypeRecs[I]); + } + // Get the operation class OpClass = R->getValueAsDef("OpClass")->getName(); @@ -188,10 +176,10 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) { // that of the intrinsic. Deviations are expected to be encoded in TableGen // record specification and handled accordingly here. Support to be added // as needed. - auto IntrPropList = IntrinsicDef->getValueAsListInit("IntrProperties"); + ListInit *IntrPropList = IntrinsicDef->getValueAsListInit("IntrProperties"); auto IntrPropListSize = IntrPropList->size(); - for (unsigned i = 0; i < IntrPropListSize; i++) { - OpAttributes.emplace_back(IntrPropList->getElement(i)->getAsString()); + for (unsigned I = 0; I < IntrPropListSize; I++) { + OpAttributes.emplace_back(IntrPropList->getElement(I)->getAsString()); } } } @@ -239,10 +227,8 @@ static std::string getParameterKindStr(ParameterKind Kind) { /// \return std::string string representation of OverloadKind static std::string getOverloadKindStr(const Record *R) { - auto VTRec = R->getValueAsDef("VT"); + Record *VTRec = R->getValueAsDef("VT"); switch (getValueType(VTRec)) { - case MVT::isVoid: - return "OverloadKind::VOID"; case MVT::f16: return "OverloadKind::HALF"; case MVT::f32: @@ -259,24 +245,23 @@ static std::string getOverloadKindStr(const Record *R) { return "OverloadKind::I32"; case MVT::i64: return "OverloadKind::I64"; - case MVT::iAny: - return "OverloadKind::I16 | OverloadKind::I32 | OverloadKind::I64"; - case MVT::fAny: - return "OverloadKind::HALF | OverloadKind::FLOAT | OverloadKind::DOUBLE"; - case MVT::Other: - // Handle DXIL-specific overload types - { - if (R->getValueAsInt("isHalfOrFloat")) { - return "OverloadKind::HALF | OverloadKind::FLOAT"; - } else if (R->getValueAsInt("isI16OrI32")) { - return "OverloadKind::I16 | OverloadKind::I32"; - } - } - [[fallthrough]]; default: - llvm_unreachable( - "Support for specified parameter OverloadKind not yet implemented"); + llvm_unreachable("Support for specified fixed type option for overload " + "type not supported"); + } +} +/// Return a string representation of OverloadKind enum that maps to +/// input LLVMType record +/// \param OLTys Overload types list record +/// \return std::string string representation of OverloadKind +static std::string getOverloadKindStrs(const SmallVector OLTys) { + std::string OverloadString = ""; + std::string Prefix = ""; + for (auto OLTy : OLTys) { + OverloadString.append(Prefix).append(getOverloadKindStr(OLTy)); + Prefix = " | "; } + return OverloadString; } /// Emit Enums of DXIL Ops @@ -397,6 +382,7 @@ static void emitDXILOperationTable(std::vector &Ops, "{\n"; OS << " static const OpCodeProperty OpCodeProps[] = {\n"; + std::string Prefix = ""; for (auto &Op : Ops) { // Consider Op.OverloadParamIndex as the overload parameter index, by // default @@ -408,13 +394,14 @@ static void emitDXILOperationTable(std::vector &Ops, if (OLParamIdx < 0) { OLParamIdx = (Op.OpTypes.size() > 1) ? 1 : 0; } - OS << " { dxil::OpCode::" << Op.OpName << ", " << OpStrings.get(Op.OpName) - << ", OpCodeClass::" << Op.OpClass << ", " + OS << Prefix << " { dxil::OpCode::" << Op.OpName << ", " + << OpStrings.get(Op.OpName) << ", OpCodeClass::" << Op.OpClass << ", " << OpClassStrings.get(Op.OpClass.data()) << ", " - << getOverloadKindStr(Op.OpTypes[OLParamIdx]) << ", " + << getOverloadKindStrs(Op.OpOverloads) << ", " << emitDXILOperationAttr(Op.OpAttributes) << ", " << Op.OverloadParamIndex << ", " << Op.OpTypes.size() - 1 << ", " - << Parameters.get(ParameterMap[Op.OpClass]) << " },\n"; + << Parameters.get(ParameterMap[Op.OpClass]) << " }\n"; + Prefix = ","; } OS << " };\n"; @@ -475,11 +462,11 @@ static void emitDXILOperationTable(std::vector &Ops, static void EmitDXILOperation(RecordKeeper &Records, raw_ostream &OS) { OS << "// Generated code, do not edit.\n"; OS << "\n"; - // Get all DXIL Ops to intrinsic mapping records - std::vector OpIntrMaps = - Records.getAllDerivedDefinitions("DXILOpMapping"); + // Get all DXIL Ops property records + std::vector OpIntrProps = + Records.getAllDerivedDefinitions("DXILOpPropertiesBase"); std::vector DXILOps; - for (auto *Record : OpIntrMaps) { + for (auto *Record : OpIntrProps) { DXILOps.emplace_back(DXILOperationDesc(Record)); } OS << "#ifdef DXIL_OP_ENUM\n";