================ @@ -3158,6 +3172,166 @@ bool SPIRVInstructionSelector::selectFirstBitHigh(Register ResVReg, } } +bool SPIRVInstructionSelector::selectFirstBitLow16(Register ResVReg, + const SPIRVType *ResType, + MachineInstr &I) const { + // OpUConvert treats the operand bits as an unsigned i16 and zero extends it + // to an unsigned i32. As this leaves all the least significant bits unchanged + // the first set bit from the LSB side doesn't change. + Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(ResType)); + bool Result = selectNAryOpWithSrcs( + ExtReg, ResType, I, {I.getOperand(2).getReg()}, SPIRV::OpUConvert); + return Result && selectFirstBitLow32(ResVReg, ResType, I, ExtReg); +} + +bool SPIRVInstructionSelector::selectFirstBitLow32(Register ResVReg, + const SPIRVType *ResType, + MachineInstr &I, + Register SrcReg) const { + 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(GL::FindILsb) + .addUse(SrcReg) + .constrainAllUses(TII, TRI, RBI); +} + +bool SPIRVInstructionSelector::selectFirstBitLow64(Register ResVReg, + const SPIRVType *ResType, + MachineInstr &I) const { + Register OpReg = I.getOperand(2).getReg(); + + // 1. Split int64 into 2 pieces using a bitcast + unsigned ComponentCount = GR.getScalarOrVectorComponentCount(ResType); + SPIRVType *BaseType = GR.retrieveScalarOrVectorIntType(ResType); + MachineIRBuilder MIRBuilder(I); + SPIRVType *PostCastType = + GR.getOrCreateSPIRVVectorType(BaseType, 2 * ComponentCount, MIRBuilder); ---------------- spall wrote:
You mean there is a maximum length? https://github.com/llvm/llvm-project/pull/116858 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits