[clang] [llvm] [HLSL][SPIRV][DXIL] Implement `dot4add_i8packed` intrinsic (PR #113623)
Steven Perron via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 29 10:17:50 PDT 2024
================
@@ -1694,6 +1698,84 @@ bool SPIRVInstructionSelector::selectIntegerDot(Register ResVReg,
return Result;
}
+// Since pre-1.6 SPIRV has no DotProductInput4x8BitPacked implementation,
+// extract the elements of the packed inputs, multiply them and add the result
+// to the accumulator.
+template <bool Signed>
+bool SPIRVInstructionSelector::selectDot4AddPacked(Register ResVReg,
+ const SPIRVType *ResType,
+ MachineInstr &I) const {
+ assert(I.getNumOperands() == 5);
+ assert(I.getOperand(2).isReg());
+ assert(I.getOperand(3).isReg());
+ assert(I.getOperand(4).isReg());
+ MachineBasicBlock &BB = *I.getParent();
+
+ bool Result = false;
+
+ // Acc = C
+ Register Acc = I.getOperand(4).getReg();
+ SPIRVType *EltType = GR.getOrCreateSPIRVIntegerType(8, I, TII);
+ auto ExtractOp =
+ Signed ? SPIRV::OpBitFieldSExtract : SPIRV::OpBitFieldUExtract;
+
+ // Extract the i8 element, multiply and add it to the accumulator
+ for (unsigned i = 0; i < 4; i++) {
+ // A[i]
+ Register AElt = MRI->createVirtualRegister(&SPIRV::IDRegClass);
+ Result |= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
+ .addDef(AElt)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(2).getReg())
+ .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII))
+ .addImm(8)
+ .constrainAllUses(TII, TRI, RBI);
+
+ // B[i]
+ Register BElt = MRI->createVirtualRegister(&SPIRV::IDRegClass);
+ Result |= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
+ .addDef(BElt)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(3).getReg())
+ .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII))
+ .addImm(8)
----------------
s-perron wrote:
I think you need to use `GR.getOrCreateConstInt(..)`. The [OpBitFieldSExtract](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpBitFieldSExtract) opcodes takes the `count` as an id, not an immediate. This means the spir-v should have
```
%uint_8 = OpConstant %int 8
%f = OpBitFieldSExtract %int_32 %base %uint_0 %uint_8
```
https://github.com/llvm/llvm-project/pull/113623
More information about the cfe-commits
mailing list