[clang] [llvm] [HLSL] implement elementwise firstbithigh hlsl builtin (PR #111082)

Justin Bogner via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 22 11:41:02 PDT 2024


================
@@ -2626,6 +2671,148 @@ Register SPIRVInstructionSelector::buildPointerToResource(
                                                  MIRBuilder);
 }
 
+bool SPIRVInstructionSelector::selectFirstBitHigh16(Register ResVReg,
+                                                    const SPIRVType *ResType,
+                                                    MachineInstr &I,
+                                                    bool IsSigned) const {
+  unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
+  // zero or sign extend
+  Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
+  bool Result =
+      selectUnOpWithSrc(ExtReg, ResType, I, I.getOperand(2).getReg(), Opcode);
+  return Result & selectFirstBitHigh32(ResVReg, ResType, I, ExtReg, IsSigned);
+}
+
+bool SPIRVInstructionSelector::selectFirstBitHigh32(Register ResVReg,
+                                                    const SPIRVType *ResType,
+                                                    MachineInstr &I,
+                                                    Register SrcReg,
+                                                    bool IsSigned) const {
+  unsigned Opcode = IsSigned ? GL::FindSMsb : GL::FindUMsb;
+  return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst))
+      .addDef(ResVReg)
+      .addUse(GR.getSPIRVTypeID(ResType))
+      .addImm(static_cast<uint32_t>(SPIRV::InstructionSet::GLSL_std_450))
+      .addImm(Opcode)
+      .addUse(SrcReg)
+      .constrainAllUses(TII, TRI, RBI);
+}
+
+bool SPIRVInstructionSelector::selectFirstBitHigh64(Register ResVReg,
+                                                    const SPIRVType *ResType,
+                                                    MachineInstr &I,
+                                                    bool IsSigned) const {
+  Register OpReg = I.getOperand(2).getReg();
+  // 1. split our int64 into 2 pieces using a bitcast
+  unsigned count = GR.getScalarOrVectorComponentCount(ResType);
+  SPIRVType *baseType = GR.retrieveScalarOrVectorIntType(ResType);
+  MachineIRBuilder MIRBuilder(I);
+  SPIRVType *postCastT =
+      GR.getOrCreateSPIRVVectorType(baseType, 2 * count, MIRBuilder);
+  Register bitcastReg = MRI->createVirtualRegister(GR.getRegClass(postCastT));
+  bool Result =
+      selectUnOpWithSrc(bitcastReg, postCastT, I, OpReg, SPIRV::OpBitcast);
+
+  // 2. call firstbithigh
+  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;
+  bool isScalarRes = ResType->getOpcode() != SPIRV::OpTypeVector;
+  if (isScalarRes)
+    VResType = GR.getOrCreateSPIRVVectorType(ResType, count, MIRBuilder);
+  // count should be one.
+
+  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 i;
+  for (i = 0; i < count * 2; i += 2) {
+    MIB.addImm(i);
+  }
----------------
bogner wrote:

Better to declare the variable in the for-loop scope so it's clear we aren't planning on using it again later. Also it's a bit confusing to have two variables named `i` and `I` in scope here - might be best to rename the `MachineInstr` to `MI` and/or to use some other placeholder like `J` here.


https://github.com/llvm/llvm-project/pull/111082


More information about the cfe-commits mailing list