SpirvShader: Implement GLSLstd450Modf

Bug: b/126873455
Tests: dEQP-VK.glsl.builtin.function.common.modf.*

Change-Id: Icefc1f7241aa1b3ef253b9f5775c38a424afec77
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28569
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 4dff390..0c3835b 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -3034,7 +3034,7 @@
 		{
 			auto p0 = GenericValue(this, routine, insn.word(5));
 			auto p1 = GenericValue(this, routine, insn.word(6));
-			auto p0Type = getType(getObject(insn.word(5)).type);
+			auto p0Type = getType(p0.type);
 
 			// sqrt(dot(p0-p1, p0-p1))
 			SIMD::Float d = (p0.Float(0) - p1.Float(0)) * (p0.Float(0) - p1.Float(0));
@@ -3047,6 +3047,34 @@
 			dst.move(0, Sqrt(d));
 			break;
 		}
+		case GLSLstd450Modf:
+		{
+			auto val = GenericValue(this, routine, insn.word(5));
+			auto ptrId = Object::ID(insn.word(6));
+			auto ptrTy = getType(getObject(ptrId).type);
+			auto ptr = GetPointerToData(ptrId, 0, routine);
+			bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass);
+
+			for (auto i = 0u; i < type.sizeInComponents; i++)
+			{
+				auto whole = Floor(val.Float(i));
+				auto frac = Frac(val.Float(i));
+
+				dst.move(i, frac);
+
+				// TODO: Refactor and consolidate with EmitStore.
+				for (int j = 0; j < SIMD::Width; j++)
+				{
+					If(Extract(state->activeLaneMask(), j) != 0)
+					{
+						Int offset = Int(i) + Extract(ptr.offset, j);
+						if (interleavedByLane) { offset = offset * SIMD::Width + j; }
+						Store(Extract(whole, j), &ptr.base[offset], sizeof(float), false, std::memory_order_relaxed);
+					}
+				}
+			}
+			break;
+		}
 		default:
 			UNIMPLEMENTED("Unhandled ExtInst %d", extInstIndex);
 		}