Commit 49d2c139 by Ben Clayton

SpirvShader: Fix int DBZ failures by masking away zeros.

The Vulkan spec says: "division by zero produces an unspecified result but must not lead to Vulkan interruption or termination". Tests: dEQP-VK.glsl.operator.binary_operator.mod.* Tests: dEQP-VK.glsl.operator.binary_operator.div.* Bug: b/127962486 Change-Id: I62e7c29a6e944512db7a8a96b0bb87488aa7be73 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27171Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 9b62c5ea
...@@ -1537,16 +1537,23 @@ namespace sw ...@@ -1537,16 +1537,23 @@ namespace sw
dst.emplace(i, lhs.Int(i) * rhs.Int(i)); dst.emplace(i, lhs.Int(i) * rhs.Int(i));
break; break;
case spv::OpSDiv: case spv::OpSDiv:
dst.emplace(i, lhs.Int(i) / rhs.Int(i)); {
auto zeroMask = CmpEQ(rhs.Int(i), SIMD::Int(0));
dst.emplace(i, lhs.Int(i) / (rhs.Int(i) | zeroMask));
break; break;
}
case spv::OpUDiv: case spv::OpUDiv:
dst.emplace(i, lhs.UInt(i) / rhs.UInt(i)); {
auto zeroMask = As<SIMD::UInt>(CmpEQ(rhs.Int(i), SIMD::Int(0)));
dst.emplace(i, lhs.UInt(i) / (rhs.UInt(i) | zeroMask));
break; break;
}
case spv::OpSMod: case spv::OpSMod:
{ {
auto a = lhs.Int(i); auto a = lhs.Int(i);
auto b = rhs.Int(i); auto b = rhs.Int(i);
auto mod = a % b; auto zeroMask = CmpEQ(b, SIMD::Int(0));
auto mod = a % (b | zeroMask);
// If a and b have opposite signs, the remainder operation takes // If a and b have opposite signs, the remainder operation takes
// the sign from a but OpSMod is supposed to take the sign of b. // the sign from a but OpSMod is supposed to take the sign of b.
// Adding b will ensure that the result has the correct sign and // Adding b will ensure that the result has the correct sign and
......
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