[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)
Sarah Spall via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 30 11:12:36 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);
----------------
spall wrote:
Sure If I do that I can probably delete the helper function I added in SPIRVGlobalRegistry. I thought this style would be less ugly than a big block.
https://github.com/llvm/llvm-project/pull/111082
More information about the cfe-commits
mailing list