From 3f007c4d547314102616902478cea80cfa98e586 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Wed, 10 Apr 2019 14:54:23 -0400 Subject: [PATCH] SpirvShader: Implement GLSLstd450FindILsb Bug: b/126873455 Tests: dEQP-VK.glsl.builtin.function.integer.findlsb.* Change-Id: I46671fe6b64814a5c9cbc8dd9fe4cc449a328f42 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28789 Tested-by: Ben Clayton Presubmit-Ready: Ben Clayton Reviewed-by: Nicolas Capens Reviewed-by: Chris Forbes Kokoro-Presubmit: kokoro --- src/Pipeline/SpirvShader.cpp | 7 ++++++- src/Reactor/LLVMReactor.cpp | 9 +++++++++ src/Reactor/Reactor.hpp | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp index 8dc93c6037b2a..8578389908dcb 100644 --- a/src/Pipeline/SpirvShader.cpp +++ b/src/Pipeline/SpirvShader.cpp @@ -3605,7 +3605,12 @@ namespace sw } case GLSLstd450FindILsb: { - UNIMPLEMENTED("GLSLstd450FindILsb"); + auto val = GenericValue(this, routine, insn.word(5)); + for (auto i = 0u; i < type.sizeInComponents; i++) + { + auto v = val.UInt(i); + dst.move(i, Cttz(v, true) | CmpEQ(v, SIMD::UInt(0))); + } break; } case GLSLstd450FindSMsb: diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp index 250850843155f..468acc47d7c9e 100644 --- a/src/Reactor/LLVMReactor.cpp +++ b/src/Reactor/LLVMReactor.cpp @@ -3219,6 +3219,15 @@ namespace rr }))); } + RValue Cttz(RValue v, bool isZeroUndef) + { + auto func = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::cttz, { T(UInt4::getType()), T(Bool::getType()) } ); + return RValue(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 69a73baee3b6b..1d2b2b06e71ff 100644 --- a/src/Reactor/Reactor.hpp +++ b/src/Reactor/Reactor.hpp @@ -2238,6 +2238,11 @@ namespace rr // Returns an undefined value when: !isZeroUndef && x == 0. RValue Ctlz(RValue x, bool isZeroUndef); + // Count trailing zeros. + // Returns 32 when: isZeroUndef && x == 0. + // Returns an undefined value when: !isZeroUndef && x == 0. + RValue Cttz(RValue x, bool isZeroUndef); + template class Pointer : public LValue> {