Commit e89296dc by Ben Clayton

SpirvShader: Fix SIMD::Pointer::hasSequentialOffsets()

This wasn't considering that the offsets are bytes and not whole words. Another bug that wasn't caught by dEQP (this would only affect atomic load / stores). Bug: b/131224163 Change-Id: I6356da3ecb86cdbb7a25667fe617f650019950e2 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/33168Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent ea3cd1b6
...@@ -306,7 +306,7 @@ namespace sw ...@@ -306,7 +306,7 @@ namespace sw
auto offset = Extract(offsets, 0); auto offset = Extract(offsets, 0);
out = T(rr::Load(rr::Pointer<EL>(&ptr.base[offset]), sizeof(float), atomic, order)); out = T(rr::Load(rr::Pointer<EL>(&ptr.base[offset]), sizeof(float), atomic, order));
} }
Else If(ptr.hasSequentialOffsets() && !anyLanesDisabled) Else If(ptr.hasSequentialOffsets(sizeof(float)) && !anyLanesDisabled)
{ {
// Load all elements in a single SIMD instruction. // Load all elements in a single SIMD instruction.
auto offset = Extract(offsets, 0); auto offset = Extract(offsets, 0);
...@@ -343,7 +343,7 @@ namespace sw ...@@ -343,7 +343,7 @@ namespace sw
else else
{ {
auto anyLanesDisabled = AnyFalse(mask); auto anyLanesDisabled = AnyFalse(mask);
If(ptr.hasSequentialOffsets() && !anyLanesDisabled) If(ptr.hasSequentialOffsets(sizeof(float)) && !anyLanesDisabled)
{ {
// Store all elements in a single SIMD instruction. // Store all elements in a single SIMD instruction.
auto offset = Extract(offsets, 0); auto offset = Extract(offsets, 0);
......
...@@ -166,24 +166,33 @@ namespace sw ...@@ -166,24 +166,33 @@ namespace sw
return dynamicLimit + staticLimit; return dynamicLimit + staticLimit;
} }
// Returns true if all offsets are sequential (N+0, N+1, N+2, N+3) // Returns true if all offsets are sequential
inline rr::Bool hasSequentialOffsets() const // (N+0*step, N+1*step, N+2*step, N+3*step)
inline rr::Bool hasSequentialOffsets(unsigned int step) const
{ {
if (hasDynamicOffsets) if (hasDynamicOffsets)
{ {
auto o = offsets(); auto o = offsets();
static_assert(SIMD::Width == 4, "Expects SIMD::Width to be 4"); static_assert(SIMD::Width == 4, "Expects SIMD::Width to be 4");
return rr::SignMask(~CmpEQ(o.yzww, o + SIMD::Int(1, 2, 3, 0))) == 0; return rr::SignMask(~CmpEQ(o.yzww, o + SIMD::Int(1*step, 2*step, 3*step, 0))) == 0;
} }
else return hasStaticSequentialOffsets(step);
}
// Returns true if all offsets are are compile-time static and
// sequential (N+0*step, N+1*step, N+2*step, N+3*step)
inline bool hasStaticSequentialOffsets(unsigned int step) const
{
if (hasDynamicOffsets)
{ {
return false;
}
for (int i = 1; i < SIMD::Width; i++) for (int i = 1; i < SIMD::Width; i++)
{ {
if (staticOffsets[i-1] + 1 != staticOffsets[i]) { return false; } if (staticOffsets[i-1] + int32_t(step) != staticOffsets[i]) { return false; }
} }
return true; return true;
} }
}
// Returns true if all offsets are equal (N, N, N, N) // Returns true if all offsets are equal (N, N, N, N)
inline rr::Bool hasEqualOffsets() const inline rr::Bool hasEqualOffsets() const
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment