Skip to content

Commit 1390b76

Browse files
authored
[SM6.9] Lower vector dot calls to vector op (microsoft#7730)
Fixes microsoft#7689 Lowers vector calls to `dot` under SM6.9 to a single operation. Relies on microsoft/hlsl-specs#622 being accepted
1 parent 368da36 commit 1390b76

12 files changed

Lines changed: 214 additions & 57 deletions

File tree

docs/DXIL.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,6 +2423,9 @@ ID Name Description
24232423
306 MatVecMulAdd multiplies a MxK dimension matrix and a K sized input vector and adds an M-sized bias vector
24242424
307 OuterProductAccumulate Computes the outer product between column vectors and an MxN matrix is accumulated component-wise atomically (with device scope) in memory
24252425
308 VectorAccumulate Accumulates the components of a vector component-wise atomically (with device scope) to the corresponding elements of an array in memory
2426+
309 ReservedD0 reserved
2427+
310 ReservedD1 reserved
2428+
311 FDot computes the n-dimensional vector dot-product
24262429
=== ===================================================== =======================================================================================================================================================================================================================
24272430

24282431

include/dxc/DXIL/DxilConstants.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,8 @@ enum class OpCode : unsigned {
524524
ReservedC7 = 300, // reserved
525525
ReservedC8 = 301, // reserved
526526
ReservedC9 = 302, // reserved
527+
ReservedD0 = 309, // reserved
528+
ReservedD1 = 310, // reserved
527529

528530
// Amplification shader instructions
529531
DispatchMesh = 173, // Amplification shader intrinsic DispatchMesh
@@ -618,9 +620,10 @@ enum class OpCode : unsigned {
618620
// i32, with accumulate to i32
619621

620622
// Dot
621-
Dot2 = 54, // Two-dimensional vector dot-product
622-
Dot3 = 55, // Three-dimensional vector dot-product
623-
Dot4 = 56, // Four-dimensional vector dot-product
623+
Dot2 = 54, // Two-dimensional vector dot-product
624+
Dot3 = 55, // Three-dimensional vector dot-product
625+
Dot4 = 56, // Four-dimensional vector dot-product
626+
FDot = 311, // computes the n-dimensional vector dot-product
624627

625628
// Double precision
626629
LegacyDoubleToFloat = 132, // legacy fuction to convert double to float
@@ -1082,7 +1085,7 @@ enum class OpCode : unsigned {
10821085
NumOpCodes_Dxil_1_7 = 226,
10831086
NumOpCodes_Dxil_1_8 = 258,
10841087

1085-
NumOpCodes = 309 // exclusive last value of enumeration
1088+
NumOpCodes = 312 // exclusive last value of enumeration
10861089
};
10871090
// OPCODE-ENUM:END
10881091

@@ -1154,6 +1157,7 @@ enum class OpCodeClass : unsigned {
11541157
Dot4AddPacked,
11551158

11561159
// Dot
1160+
Dot,
11571161
Dot2,
11581162
Dot3,
11591163
Dot4,
@@ -1413,7 +1417,7 @@ enum class OpCodeClass : unsigned {
14131417
NumOpClasses_Dxil_1_7 = 153,
14141418
NumOpClasses_Dxil_1_8 = 174,
14151419

1416-
NumOpClasses = 194 // exclusive last value of enumeration
1420+
NumOpClasses = 195 // exclusive last value of enumeration
14171421
};
14181422
// OPCODECLASS-ENUM:END
14191423

include/dxc/DXIL/DxilInstructions.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10148,5 +10148,34 @@ struct DxilInst_VectorAccumulate {
1014810148
llvm::Value *get_arrayOffset() const { return Instr->getOperand(3); }
1014910149
void set_arrayOffset(llvm::Value *val) { Instr->setOperand(3, val); }
1015010150
};
10151+
10152+
/// This instruction computes the n-dimensional vector dot-product
10153+
struct DxilInst_FDot {
10154+
llvm::Instruction *Instr;
10155+
// Construction and identification
10156+
DxilInst_FDot(llvm::Instruction *pInstr) : Instr(pInstr) {}
10157+
operator bool() const {
10158+
return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::FDot);
10159+
}
10160+
// Validation support
10161+
bool isAllowed() const { return true; }
10162+
bool isArgumentListValid() const {
10163+
if (3 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands())
10164+
return false;
10165+
return true;
10166+
}
10167+
// Metadata
10168+
bool requiresUniformInputs() const { return false; }
10169+
// Operand indexes
10170+
enum OperandIdx {
10171+
arg_a = 1,
10172+
arg_b = 2,
10173+
};
10174+
// Accessors
10175+
llvm::Value *get_a() const { return Instr->getOperand(1); }
10176+
void set_a(llvm::Value *val) { Instr->setOperand(1, val); }
10177+
llvm::Value *get_b() const { return Instr->getOperand(2); }
10178+
void set_b(llvm::Value *val) { Instr->setOperand(2, val); }
10179+
};
1015110180
// INSTR-HELPER:END
1015210181
} // namespace hlsl

lib/DXIL/DxilOperations.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2686,6 +2686,33 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
26862686
1,
26872687
{{0x400}},
26882688
{{0x63}}}, // Overloads: <hfwi
2689+
2690+
{OC::ReservedD0,
2691+
"ReservedD0",
2692+
OCC::Reserved,
2693+
"reserved",
2694+
Attribute::None,
2695+
0,
2696+
{},
2697+
{}}, // Overloads: v
2698+
{OC::ReservedD1,
2699+
"ReservedD1",
2700+
OCC::Reserved,
2701+
"reserved",
2702+
Attribute::None,
2703+
0,
2704+
{},
2705+
{}}, // Overloads: v
2706+
2707+
// Dot
2708+
{OC::FDot,
2709+
"FDot",
2710+
OCC::Dot,
2711+
"dot",
2712+
Attribute::ReadNone,
2713+
1,
2714+
{{0x400}},
2715+
{{0x3}}}, // Overloads: <hf
26892716
};
26902717
// OPCODE-OLOADS:END
26912718

@@ -3792,10 +3819,12 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
37923819
Type *pI16 = Type::getInt16Ty(m_Ctx);
37933820
Type *pI32 = Type::getInt32Ty(m_Ctx);
37943821
Type *pOlTplI32 = Type::getInt32Ty(m_Ctx);
3822+
Type *pVecElt = nullptr;
37953823
if (pOverloadType->isVectorTy()) {
37963824
pOlTplI32 =
37973825
VectorType::get(pOlTplI32, pOverloadType->getVectorNumElements());
37983826
pOlTplI1 = VectorType::get(pOlTplI1, pOverloadType->getVectorNumElements());
3827+
pVecElt = pOverloadType->getVectorElementType();
37993828
}
38003829

38013830
Type *pPI32 = Type::getInt32PtrTy(m_Ctx);
@@ -5988,6 +6017,24 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
59886017
A(pRes);
59896018
A(pI32);
59906019
break;
6020+
6021+
//
6022+
case OpCode::ReservedD0:
6023+
A(pV);
6024+
A(pI32);
6025+
break;
6026+
case OpCode::ReservedD1:
6027+
A(pV);
6028+
A(pI32);
6029+
break;
6030+
6031+
// Dot
6032+
case OpCode::FDot:
6033+
A(pVecElt);
6034+
A(pI32);
6035+
A(pETy);
6036+
A(pETy);
6037+
break;
59916038
// OPCODE-OLOAD-FUNCS:END
59926039
default:
59936040
DXASSERT(false, "otherwise unhandled case");
@@ -6160,6 +6207,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
61606207
case OpCode::CreateHandleForLib:
61616208
case OpCode::WaveMatch:
61626209
case OpCode::VectorAccumulate:
6210+
case OpCode::FDot:
61636211
if (FT->getNumParams() <= 1)
61646212
return nullptr;
61656213
return FT->getParamType(1);
@@ -6276,6 +6324,8 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
62766324
case OpCode::ReservedC7:
62776325
case OpCode::ReservedC8:
62786326
case OpCode::ReservedC9:
6327+
case OpCode::ReservedD0:
6328+
case OpCode::ReservedD1:
62796329
return Type::getVoidTy(Ctx);
62806330
case OpCode::CheckAccessFullyMapped:
62816331
case OpCode::SampleIndex:

lib/HLSL/HLOperationLower.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2556,10 +2556,23 @@ Value *TranslateDot(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
25562556
hlsl::OP *hlslOP = &helper.hlslOP;
25572557
Value *arg0 = CI->getArgOperand(HLOperandIndex::kBinaryOpSrc0Idx);
25582558
Type *Ty = arg0->getType();
2559+
Type *EltTy = Ty->getScalarType();
2560+
2561+
// SM6.9 introduced a DXIL operation for vectorized dot product
2562+
if (hlslOP->GetModule()->GetHLModule().GetShaderModel()->IsSM69Plus() &&
2563+
EltTy->isFloatingPointTy()) {
2564+
Value *arg1 = CI->getArgOperand(HLOperandIndex::kBinaryOpSrc1Idx);
2565+
IRBuilder<> Builder(CI);
2566+
Constant *opArg = hlslOP->GetU32Const((unsigned)DXIL::OpCode::FDot);
2567+
Value *args[] = {opArg, arg0, arg1};
2568+
Function *dxilFunc = hlslOP->GetOpFunc(DXIL::OpCode::FDot, Ty);
2569+
return TrivialDxilVectorOperation(dxilFunc, DXIL::OpCode::FDot, args, Ty,
2570+
hlslOP, Builder);
2571+
}
2572+
25592573
unsigned vecSize = Ty->getVectorNumElements();
25602574
Value *arg1 = CI->getArgOperand(HLOperandIndex::kBinaryOpSrc1Idx);
25612575
IRBuilder<> Builder(CI);
2562-
Type *EltTy = Ty->getScalarType();
25632576
if (EltTy->isFloatingPointTy() && Ty->getVectorNumElements() <= 4)
25642577
return TranslateFDot(arg0, arg1, vecSize, hlslOP, Builder);
25652578

tools/clang/test/CodeGenDXIL/hlsl/types/longvec-intrinsics.hlsl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,16 @@ void main() {
519519
// CHECK: select <[[NUM]] x i1> [[bvec1]], <[[NUM]] x i16> [[svec2]], <[[NUM]] x i16> [[svec3]]
520520
sRes += select(sVec1, sVec2, sVec3);
521521

522+
523+
// CHECK-NOT: extractelement
524+
// CHECK-NOT: insertelement
525+
// CHECK: call float @dx.op.dot.[[FTY]](i32 311, <[[NUM]] x float> [[fvec1]], <[[NUM]] x float> [[fvec2]]) ; FDot(a,b)
526+
// One pair of extract/insert is expected for the [0]
527+
// CHECK: extractelement <[[NUM]] x float> {{%.*}}, i32 0
528+
// CHECK: insertelement <[[NUM]] x float> {{%.*}}, float {{%.*}}, i32 0
529+
float fResScalar = dot(fVec1, fVec2);
530+
fRes[0] += fResScalar;
531+
522532
// CHECK-NOT: extractelement
523533
// CHECK-NOT: insertelement
524534
buf.Store<vector<float16_t, NUM> >(0, hRes);

tools/clang/test/CodeGenDXIL/hlsl/types/longvec-scalarized-intrinsics.hlsl

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,6 @@ export void test_modf(inout vector<float, 8> vec1, vector<float, 8> vec2) {
6565
vec1 = modf(vec1, vec2);
6666
}
6767

68-
// CHECK-LABEL: test_dot
69-
// CHECK: [[el:%.*]] = extractelement <8 x float>
70-
// CHECK: [[mul:%.*]] = fmul fast float [[el]]
71-
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mul]]) ; FMad(a,b,c)
72-
// CHECK: [[pong:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[ping]]) ; FMad(a,b,c)
73-
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[pong]]) ; FMad(a,b,c)
74-
// CHECK: [[pong:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[ping]]) ; FMad(a,b,c)
75-
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[pong]]) ; FMad(a,b,c)
76-
// CHECK: [[pong:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[ping]]) ; FMad(a,b,c)
77-
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[pong]]) ; FMad(a,b,c)
78-
export void test_dot(inout vector<float, 8> vec1, vector<float, 8> vec2) {
79-
vec1 = dot(vec1, vec2);
80-
}
81-
8268
// CHECK-LABEL: test_any
8369
// CHECK: or i1
8470
// CHECK: or i1

tools/clang/test/CodeGenDXIL/passes/longvec-intrinsics.hlsl

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -156,21 +156,10 @@ void main() {
156156
// CHECK: call <13 x i1> @dx.op.isSpecialFloat.v13f32(i32 8, <13 x float> [[fvec2]]) ; IsNaN(value)
157157
uRes += isnan(fVec2);
158158

159-
// CHECK: [[el1:%.*]] = extractelement <13 x float> [[fvec1]]
160-
// CHECK: [[el2:%.*]] = extractelement <13 x float> [[fvec2]]
161-
// CHECK: [[mul:%.*]] = fmul fast float [[el2]], [[el1]]
162-
// CHECK: [[mad1:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mul]]) ; FMad(a,b,c)
163-
// CHECK: [[mad2:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad1]]) ; FMad(a,b,c)
164-
// CHECK: [[mad3:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad2]]) ; FMad(a,b,c)
165-
// CHECK: [[mad4:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad3]]) ; FMad(a,b,c)
166-
// CHECK: [[mad5:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad4]]) ; FMad(a,b,c)
167-
// CHECK: [[mad6:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad5]]) ; FMad(a,b,c)
168-
// CHECK: [[mad7:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad6]]) ; FMad(a,b,c)
169-
// CHECK: [[mad8:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad7]]) ; FMad(a,b,c)
170-
// CHECK: [[mad9:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad8]]) ; FMad(a,b,c)
171-
// CHECK: [[mad10:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad9]]) ; FMad(a,b,c)
172-
// CHECK: [[mad11:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad10]]) ; FMad(a,b,c)
173-
// CHECK: [[mad12:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mad11]]) ; FMad(a,b,c)
159+
// CHECK: [[dotres:%.*]] = call float @dx.op.dot.v13f32(i32 311, <13 x float> [[fvec1]], <13 x float> [[fvec2]]) ; FDot(a,b)
160+
// Upcast float to <13 x float>
161+
// CHECK: [[dotresvec:%.*]] = insertelement <13 x float> undef, float [[dotres]], i32 0
162+
// CHECK: shufflevector <13 x float> [[dotresvec]], <13 x float> undef, <13 x i32> zeroinitializer
174163
fRes += dot(fVec1, fVec2);
175164

176165
// CHECK: call <13 x float> @dx.op.unary.v13f32(i32 17, <13 x float> [[fvec1]]) ; Atan(value)

tools/clang/test/CodeGenDXIL/passes/longvec-intrinsics.ll

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -265,27 +265,9 @@ bb:
265265
%inres = add <7 x i32> %tmp100, %inext
266266

267267
; Dot operation.
268-
; CHECK: [[el1:%.*]] = extractelement <7 x float> [[fvec1]], i64 0
269-
; CHECK: [[el2:%.*]] = extractelement <7 x float> [[fvec2]], i64 0
270-
; CHECK: [[mul:%.*]] = fmul fast float [[el1]], [[el2]]
271-
; CHECK: [[el1:%.*]] = extractelement <7 x float> [[fvec1]], i64 1
272-
; CHECK: [[el2:%.*]] = extractelement <7 x float> [[fvec2]], i64 1
273-
; CHECK: [[mad1:%.*]] = call float @dx.op.tertiary.f32(i32 46, float [[el1]], float [[el2]], float [[mul]])
274-
; CHECK: [[el1:%.*]] = extractelement <7 x float> [[fvec1]], i64 2
275-
; CHECK: [[el2:%.*]] = extractelement <7 x float> [[fvec2]], i64 2
276-
; CHECK: [[mad2:%.*]] = call float @dx.op.tertiary.f32(i32 46, float [[el1]], float [[el2]], float [[mad1]])
277-
; CHECK: [[el1:%.*]] = extractelement <7 x float> [[fvec1]], i64 3
278-
; CHECK: [[el2:%.*]] = extractelement <7 x float> [[fvec2]], i64 3
279-
; CHECK: [[mad3:%.*]] = call float @dx.op.tertiary.f32(i32 46, float [[el1]], float [[el2]], float [[mad2]])
280-
; CHECK: [[el1:%.*]] = extractelement <7 x float> [[fvec1]], i64 4
281-
; CHECK: [[el2:%.*]] = extractelement <7 x float> [[fvec2]], i64 4
282-
; CHECK: [[mad4:%.*]] = call float @dx.op.tertiary.f32(i32 46, float [[el1]], float [[el2]], float [[mad3]])
283-
; CHECK: [[el1:%.*]] = extractelement <7 x float> [[fvec1]], i64 5
284-
; CHECK: [[el2:%.*]] = extractelement <7 x float> [[fvec2]], i64 5
285-
; CHECK: [[mad5:%.*]] = call float @dx.op.tertiary.f32(i32 46, float [[el1]], float [[el2]], float [[mad4]])
286-
; CHECK: [[el1:%.*]] = extractelement <7 x float> [[fvec1]], i64 6
287-
; CHECK: [[el2:%.*]] = extractelement <7 x float> [[fvec2]], i64 6
288-
; CHECK: call float @dx.op.tertiary.f32(i32 46, float [[el1]], float [[el2]], float [[mad5]])
268+
; CHECK: [[dotres:%.*]] = call float @dx.op.dot.v7f32(i32 311, <7 x float> [[fvec1]], <7 x float> [[fvec2]])
269+
; CHECK: [[dotresvec:%.*]] = insertelement <7 x float> undef, float [[dotres]], i32 0
270+
; CHECK: shufflevector <7 x float> [[dotresvec]], <7 x float> undef, <7 x i32> zeroinitializer
289271
%tmp103 = call float @"dx.hl.op.rn.float (i32, <7 x float>, <7 x float>)"(i32 134, <7 x float> %tmp4, <7 x float> %tmp9) ; line:152 col:11
290272
%tmp104 = insertelement <7 x float> undef, float %tmp103, i32 0 ; line:152 col:11
291273
%tmp105 = shufflevector <7 x float> %tmp104, <7 x float> undef, <7 x i32> zeroinitializer ; line:152 col:11
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; REQUIRES: dxil-1-9
2+
; RUN: not %dxv %s 2>&1 | FileCheck %s
3+
target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
4+
target triple = "dxil-ms-dx"
5+
6+
7+
%dx.types.Handle = type { i8* }
8+
%dx.types.ResBind = type { i32, i32, i32, i8 }
9+
%dx.types.ResourceProperties = type { i32, i32 }
10+
%dx.types.ResRet.v8f64 = type { <8 x double>, i32 }
11+
%struct.RWByteAddressBuffer = type { i32 }
12+
13+
define void @main() {
14+
%1 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 0, i32 0, i32 0, i8 1 }, i32 0, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex)
15+
%2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer
16+
%3 = call %dx.types.ResRet.v8f64 @dx.op.rawBufferVectorLoad.v8f64(i32 303, %dx.types.Handle %2, i32 0, i32 undef, i32 4) ; RawBufferVectorLoad(buf,index,elementOffset,alignment)
17+
%4 = extractvalue %dx.types.ResRet.v8f64 %3, 0
18+
%5 = call %dx.types.ResRet.v8f64 @dx.op.rawBufferVectorLoad.v8f64(i32 303, %dx.types.Handle %2, i32 32, i32 undef, i32 4) ; RawBufferVectorLoad(buf,index,elementOffset,alignment)
19+
%6 = extractvalue %dx.types.ResRet.v8f64 %5, 0
20+
21+
22+
; CHECK: Function: main: error: DXIL intrinsic overload must be valid.
23+
; CHECK: note: at '%7 = call double @dx.op.dot.v8f64(i32 311, <8 x double> %4, <8 x double> %6)' in block '#0' of function 'main'.
24+
%7 = call double @dx.op.dot.v8f64(i32 311, <8 x double> %4, <8 x double> %6) ; FDot(a,b)
25+
26+
27+
%8 = extractelement <8 x double> %6, i32 0
28+
%9 = fadd fast double %8, %7
29+
%10 = insertelement <8 x double> %6, double %9, i32 0
30+
call void @dx.op.rawBufferVectorStore.v8f64(i32 304, %dx.types.Handle %2, i32 0, i32 undef, <8 x double> %10, i32 4) ; RawBufferVectorStore(uav,index,elementOffset,value0,alignment)
31+
ret void
32+
}
33+
34+
; Function Attrs: nounwind readonly
35+
declare %dx.types.ResRet.v8f64 @dx.op.rawBufferVectorLoad.v8f64(i32, %dx.types.Handle, i32, i32, i32) #0
36+
37+
; Function Attrs: nounwind readnone
38+
declare double @dx.op.dot.v8f64(i32, <8 x double>, <8 x double>) #1
39+
40+
; Function Attrs: nounwind
41+
declare void @dx.op.rawBufferVectorStore.v8f64(i32, %dx.types.Handle, i32, i32, <8 x double>, i32) #2
42+
43+
; Function Attrs: nounwind readnone
44+
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
45+
46+
; Function Attrs: nounwind readnone
47+
declare %dx.types.Handle @dx.op.createHandleFromBinding(i32, %dx.types.ResBind, i32, i1) #1
48+
49+
attributes #0 = { nounwind readonly }
50+
attributes #1 = { nounwind readnone }
51+
attributes #2 = { nounwind }
52+
53+
!llvm.ident = !{!0}
54+
!dx.version = !{!1}
55+
!dx.valver = !{!1}
56+
!dx.shaderModel = !{!2}
57+
!dx.resources = !{!3}
58+
!dx.entryPoints = !{!6}
59+
60+
!0 = !{!"dxc(private) 1.8.0.15017 (main, 4e0f5364a-dirty)"}
61+
!1 = !{i32 1, i32 9}
62+
!2 = !{!"cs", i32 6, i32 9}
63+
!3 = !{null, !4, null, null}
64+
!4 = !{!5}
65+
!5 = !{i32 0, %struct.RWByteAddressBuffer* undef, !"", i32 0, i32 0, i32 1, i32 11, i1 false, i1 false, i1 false, null}
66+
!6 = !{void ()* @main, !"main", null, !3, !7}
67+
!7 = !{i32 0, i64 8598323220, i32 4, !8}
68+
!8 = !{i32 4, i32 1, i32 1}
69+

0 commit comments

Comments
 (0)