Fix unsigned "less than zero" comparison

From the SPIR-V spec:
  OpSMod's result is the remainder r of Operand 1 divided by Operand 2
  where if r != 0, the sign of r is the same as the sign of Operand 2.

The less than comparison here was trying to correct the cases where C's
modulo had a different sign than SPIR-V's modulo. We can solve this by
directly comparing the sign of the C modulo against Operand 2's sign.

Bug chromium:973848

Change-Id: I27c88b7aaed35db5ba4df2cc0aac6061098f32c4
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/32868
Tested-by: Sean Risser <srisser@google.com>
Presubmit-Ready: Sean Risser <srisser@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 05e1623..4a8c890 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -6103,10 +6103,10 @@
 			case spv::OpSMod:
 				if (r == 0) r = UINT32_MAX;
 				if (l == static_cast<uint32_t>(INT32_MIN)) l = UINT32_MAX;
-				if (l * r < 0)
-					v = static_cast<int32_t>(l) % static_cast<int32_t>(r) + r;
-				else
-					v = static_cast<int32_t>(l) % static_cast<int32_t>(r);
+				// Test if a signed-multiply would be negative.
+				v = static_cast<int32_t>(l) % static_cast<int32_t>(r);
+				if ((v & 0x80000000) != (r & 0x80000000))
+					v += r;
 				break;
 			case spv::OpShiftRightLogical:
 				v = l >> r;