================ @@ -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); ---------------- s-perron wrote:
I'll double check, but I don't think this is necessary for `FindILsb`. The [documentation](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html) says: > FindILsb > Integer least-significant bit. > Results in the bit number of the least-significant 1-bit in the binary > representation of Value. If Value is 0, the result is -1. > Result Type and the type of Value must both be integer scalar or integer > vector types. Result Type and operand types must have the same number of > components with the same component width. Results are computed per component. In particular, it does not contain the line that `FindMsb` has: > This instruction is currently limited to 32-bit width components. 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