MemoryExtensions.Replace(Span<T>, T, T) implemented (#76337)
* Defined API
* Tests
* Scalar implementation
* Use EqualityComparer<T>.Default instead
* Delegation to SpanHelpers.Replace
* ReplaceValueType implemented
* Use ushort instead of short, as it doesn't sign-extend for broadcast and in the scalar loop
* Forward string.Replace(char, char) to SpanHelpers.ReplaceValueType
* Process remainder vectorized only when not done already and with max width available
* Split into inlineable scalar path and non-inlineable vectorized path
* Replaced open coded loops with Replace
* Don't use EqualityComparer<T>.Default
Cf. https://github.com/dotnet/runtime/pull/76337#discussion_r982886319
* Remove guards for remainder
Cf. https://github.com/dotnet/runtime/pull/76337#discussion_r983448480
* Don't split method into scalar and vectorized and don't force inlining of scalar-part
* Fixed assert
ReplaceValueType is called from string.Replace(char, char) so the Debug.Assert was on wrong position, as at entry to method non accelerated platforms are allowed to call it.
* Better handling of remainder from the vectorized loop(s)
Intentionally leave one iteration off, as the remaining elements are done vectorized anyway. This eliminates the less probable case (cf. https://github.com/dotnet/runtime/pull/76337#discussion_r983448480) that the last vector is done twice.
* PR feedback