SpirvShader: Implement GLSLstd450Find[U,S]Msb Bug: b/126873455 Tests: dEQP-VK.glsl.builtin.function.integer.findMSB.* Change-Id: I6337998f725334c31d8adeae05fc441bb3895908 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28788 Tested-by: Ben Clayton <bclayton@google.com> Presubmit-Ready: Ben Clayton <bclayton@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com> Reviewed-by: Chris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp index e79fa94..8dc93c6 100644 --- a/src/Pipeline/SpirvShader.cpp +++ b/src/Pipeline/SpirvShader.cpp
@@ -3610,12 +3610,21 @@ } case GLSLstd450FindSMsb: { - UNIMPLEMENTED("GLSLstd450FindSMsb"); + auto val = GenericValue(this, routine, insn.word(5)); + for (auto i = 0u; i < type.sizeInComponents; i++) + { + auto v = val.UInt(i) ^ As<SIMD::UInt>(CmpLT(val.Int(i), SIMD::Int(0))); + dst.move(i, SIMD::UInt(31) - Ctlz(v, false)); + } break; } case GLSLstd450FindUMsb: { - UNIMPLEMENTED("GLSLstd450FindUMsb"); + auto val = GenericValue(this, routine, insn.word(5)); + for (auto i = 0u; i < type.sizeInComponents; i++) + { + dst.move(i, SIMD::UInt(31) - Ctlz(val.UInt(i), false)); + } break; } case GLSLstd450InterpolateAtCentroid:
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp index 8b3be66..2508508 100644 --- a/src/Reactor/LLVMReactor.cpp +++ b/src/Reactor/LLVMReactor.cpp
@@ -3210,6 +3210,15 @@ return RValue<Float4>(V(::builder->CreateCall(func, { V(v.value) }))); } + RValue<UInt4> Ctlz(RValue<UInt4> v, bool isZeroUndef) + { + auto func = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::ctlz, { T(UInt4::getType()), T(Bool::getType()) } ); + return RValue<UInt4>(V(::builder->CreateCall(func, { + V(v.value), + isZeroUndef ? ::llvm::ConstantInt::getTrue(*::context) : ::llvm::ConstantInt::getFalse(*::context) + }))); + } + Type *Float4::getType() { return T(llvm::VectorType::get(T(Float::getType()), 4));
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp index 4e74812..69a73ba 100644 --- a/src/Reactor/Reactor.hpp +++ b/src/Reactor/Reactor.hpp
@@ -2230,6 +2230,14 @@ RValue<Float4> Exp2(RValue<Float4> x); RValue<Float4> Log2(RValue<Float4> x); + // Bit Manipulation functions. + // TODO: Currentlhy unimplemented for Subzero. + + // Count leading zeros. + // Returns 32 when: isZeroUndef && x == 0. + // Returns an undefined value when: !isZeroUndef && x == 0. + RValue<UInt4> Ctlz(RValue<UInt4> x, bool isZeroUndef); + template<class T> class Pointer : public LValue<Pointer<T>> {