Repository navigation
Conversation
PackedSpanHelpers was gated on Sse2 only, so WASM fell back to the non-packed Vector128 search. PackedSimd.ConvertNarrowingSaturateUnsigned (i8x16.narrow_i16x8_u) has the same saturation semantics as Sse2.PackUnsignedSaturate, so the same CanUsePackedIndexOf restrictions apply. - Enable PackedIndexOfIsSupported for PackedSimd and pack with ConvertNarrowingSaturateUnsigned. - Add CompExactlyDependsOn(PackedSimd) to the packed helpers and the Any*CharPacked SearchValues so crossgen still compiles them for wasm. - Use the packed path in string.Split's MakeSeparatorListVectorized. - SingleStringSearchValuesPackedThreeChars is selected via PackedIndexOfIsSupported, so add a PackedSimd packing path there too (previously it would have fallen through to AdvSimd.Arm64.UnzipEven). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a42c1090-4687-4af7-92e0-1aa50cdd1826
Replace the nested ternary in SingleStringSearchValuesPackedThreeChars.LoadPacked128 and the two-way ternary in PackedSpanHelpers.PackSources with if/else-if chains that recheck each IsSupported and end in ThrowUnreachableException, matching TeddyHelper.LoadAndPack16AsciiChars. ILLink then removes the dead branches: the nested ternary previously kept AdvSimd.Arm64.UnzipEven in trimmed wasm IL when PackedSimd.IsSupported is not substituted (CoreCLR apps). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a42c1090-4687-4af7-92e0-1aa50cdd1826
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @dotnet/area-system-buffers |
This was referenced Oct 16, 2026
This was referenced Oct 16, 2026
BrzVlad
reviewed
Oct 16, 2026
All callers are already behind PackedIndexOfIsSupported, and ILLink folds a two-way IsSupported ternary correctly, so the explicit if/else-if chain with an unreachable throw added nothing here. Restore the Debug.Assert. The explicit chain stays in LoadPacked128, where the nested three-way ternary left the dead AdvSimd branch in trimmed CoreCLR wasm IL. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a42c1090-4687-4af7-92e0-1aa50cdd1826
Reverts d92832c. Sse2.IsSupported isn't substituted for CoreCLR apps targeting x86/x64, so the two-way ternary left the dead PackedSimd call in trimmed x64 IL; with the chain, PackedSimd.IsSupported (substituted false off wasm) lets ILLink remove it. Matches the "explicitly recheck each IsSupported" pattern used elsewhere in CoreLib. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a42c1090-4687-4af7-92e0-1aa50cdd1826
lewing
marked this pull request as ready for review
October 16, 2026 21:29
This was referenced Oct 17, 2026
Open
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PackedSpanHelpersnarrows twoVector128<ushort>into oneVector128<byte>to search 16 chars per compare, but was gated onSse2only, so WebAssembly always took the non-packed path.PackedSimd.ConvertNarrowingSaturateUnsigned(i8x16.narrow_i16x8_u) has the same saturation semantics asSse2.PackUnsignedSaturate, so the existingCanUsePackedIndexOfrules apply unchanged.PackedIndexOfIsSupportedbecomesSse2 || PackedSimd;PackSources/LoadPacked128narrow withPackedSimd, using explicitIsSupportedchains so ILLink removes dead branches.string.SplitandSingleStringSearchValuesPackedThreeCharsuse the packed path on wasm.[CompExactlyDependsOn(typeof(PackedSimd))]lets CoreCLR wasm R2R precompile these methods.This applies to Mono (interpreter and AOT) and CoreCLR R2R; the CoreCLR interpreter reports
PackedSimd.IsSupported == false.span.IndexOf(char)span.IndexOfAny(c0, c1, c2)SearchValues<string>Short inputs cost about 1–2 ns per call on Arm hosts, where V8 and Cranelift lower the narrow and bitmask to multi-instruction sequences; on x64 they map to
packuswb/pmovmskb(not measured).Full benchmark table and Arm details
Apple M-series host under Node/V8, five interleaved rounds per build, medians; ratio = new / baseline.
span.IndexOf(char)span.IndexOfAny(c0, c1)span.IndexOfAny(c0, c1, c2)span.IndexOfAnyExcept(char)span.Contains(char)string.IndexOf(char, OrdinalIgnoreCase)SearchValues<char>(3 values)SearchValues<string>(1 value)string.Split(3 separators, dense)string.Replace(string, string)(1-char old value, dense)Mono browser-wasm shows the same shape: AOT 0.66–0.80 at len=1024 and 1.09–1.27 at len=16; the interpreter 0.65–0.85 at most sizes. Results break even around 64–96 chars.
On aarch64, V8 (
d8 --print-wasm-code) and Cranelift loweri8x16.narrow_i16x8_uto a dependentsqxtun/sqxtun2pair andi8x16.bitmaskto a two-pmull+trn2sequence;i16x8.bitmaskneeds onepmull. A possible follow-up keeps the packedany_trueloop but computes the match index from the unpacked 16-bit vectors, asMakeSeparatorListVectorizeddoes.Related: #135869 (other
CompExactlyDependsOn(PackedSimd)gaps), #135892 (crossgen2 doesn't foldbox T; isinst X).Note
This PR description was drafted with GitHub Copilot assistance.