================ @@ -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); + } ---------------- spall wrote:
It is actually re-used in the for-loop below this one. I will rename one of them. https://github.com/llvm/llvm-project/pull/111082 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits