[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)
Farzon Lotfi via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 30 11:20:46 PDT 2024
================
@@ -2717,82 +2717,82 @@ bool SPIRVInstructionSelector::selectFirstBitHigh64(Register ResVReg,
Register FBHReg = MRI->createVirtualRegister(GR.getRegClass(postCastT));
Result &= selectFirstBitHigh32(FBHReg, postCastT, I, bitcastReg, IsSigned);
- // 3. check if result of each top 32 bits is == -1
- // split result vector into vector of high bits and vector of low bits
- // get high bits
- // if ResType is a scalar we need a vector anyways because our code
- // operates on vectors, even vectors of length one.
- SPIRVType *VResType = ResType;
+ // 3. split result vector into high bits and low bits
+ Register HighReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
+ Register LowReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
+
+ bool ZeroAsNull = STI.isOpenCLEnv();
bool isScalarRes = ResType->getOpcode() != SPIRV::OpTypeVector;
- if (isScalarRes)
- VResType = GR.getOrCreateSPIRVVectorType(ResType, count, MIRBuilder);
- // count should be one.
+ if (isScalarRes) {
+ // if scalar do a vector extract
+ Result &= selectNAryOpWithSrcs(
+ HighReg, ResType, I,
+ {FBHReg, GR.getOrCreateConstInt(0, I, ResType, TII, ZeroAsNull)},
+ SPIRV::OpVectorExtractDynamic);
+ Result &= selectNAryOpWithSrcs(
+ LowReg, ResType, I,
+ {FBHReg, GR.getOrCreateConstInt(1, I, ResType, TII, ZeroAsNull)},
+ SPIRV::OpVectorExtractDynamic);
+ } else { // vector case do a shufflevector
+ auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpVectorShuffle))
+ .addDef(HighReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(FBHReg)
+ .addUse(FBHReg);
+ // ^^ this vector will not be selected from; could be empty
+ unsigned j;
+ for (j = 0; j < count * 2; j += 2) {
+ MIB.addImm(j);
+ }
+ Result &= MIB.constrainAllUses(TII, TRI, RBI);
+
+ // get low bits
+ MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpVectorShuffle))
+ .addDef(LowReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(FBHReg)
+ .addUse(FBHReg);
+ // ^^ this vector will not be selected from; could be empty
+ for (j = 1; j < count * 2; j += 2) {
+ MIB.addImm(j);
+ }
+ Result &= MIB.constrainAllUses(TII, TRI, RBI);
+ }
+
+ // 4. check if result of each top 32 bits is == -1
+ SPIRVType *BoolType = GR.getOrCreateSPIRVBoolType(I, TII);
+ if (!isScalarRes)
+ BoolType = GR.getOrCreateSPIRVVectorType(BoolType, count, MIRBuilder);
- Register HighReg = MRI->createVirtualRegister(GR.getRegClass(VResType));
- auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(SPIRV::OpVectorShuffle))
- .addDef(HighReg)
- .addUse(GR.getSPIRVTypeID(VResType))
- .addUse(FBHReg)
- .addUse(FBHReg);
- // ^^ this vector will not be selected from; could be empty
- unsigned j;
- for (j = 0; j < count * 2; j += 2) {
- MIB.addImm(j);
- }
- Result &= MIB.constrainAllUses(TII, TRI, RBI);
-
- // get low bits
- Register LowReg = MRI->createVirtualRegister(GR.getRegClass(VResType));
- MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(SPIRV::OpVectorShuffle))
- .addDef(LowReg)
- .addUse(GR.getSPIRVTypeID(VResType))
- .addUse(FBHReg)
- .addUse(FBHReg);
- // ^^ this vector will not be selected from; could be empty
- for (j = 1; j < count * 2; j += 2) {
- MIB.addImm(j);
- }
- Result &= MIB.constrainAllUses(TII, TRI, RBI);
-
- SPIRVType *BoolType = GR.getOrCreateSPIRVVectorType(
- GR.getOrCreateSPIRVBoolType(I, TII), count, MIRBuilder);
// check if the high bits are == -1;
- Register NegOneReg = GR.getOrCreateConstVector(-1, I, VResType, TII);
+ Register NegOneReg =
+ GR.getOrCreateConstScalarOrVector(-1, I, ResType, TII, ZeroAsNull);
----------------
farzonl wrote:
I can see the potential readability benefits. That said so much of the spirv backend is splitting scalar vs vector behaviors into their own little playgrounds that it feels like we are going against the grain here. Thats why we have `OpSelectSISCond` and `OpSelectVIVCond` when the SPIRV spec makes no function difference in the opcode.
https://github.com/llvm/llvm-project/pull/111082
More information about the cfe-commits
mailing list