[libc] Always use __builtin_wasm_memory_fill in memset - #27656
Merged
Conversation
sbc100
added a commit
to sbc100/emscripten
that referenced
this pull request
Sep 2, 2026
Followup to emscripten-core#27653 and emscripten-core#27656. Replace Musl's `memset.c` and the `-Oz` logic in `emscripten_memset.c` with `__builtin_wasm_memory_fill`. Under ASan, keep `__attribute__((no_sanitize("address")))` on the naive scalar loop because ASan's shadow memory poisoner calls `REAL(memset)` directly on shadow memory itself, which would otherwise trigger an immediate shadow-on-shadow fault. Microbenchmark results (100k iterations across sizes 1B to 16KB): Aligned sets (sizes 1B to 16KB): - V8: 30.36ms vs 70.52ms (56.9% faster, 2.3x) - SpiderMonkey: 31.91ms vs 67.01ms (52.4% faster, 2.1x) - JavaScriptCore: 26.70ms vs 70.44ms (62.1% faster, 2.6x) Unaligned sets (offsets 1..3 across sizes 1B to 16KB): - V8: 30.61ms vs 65.28ms (53.1% faster, 2.1x) - SpiderMonkey: 32.94ms vs 64.28ms (48.8% faster, 2.0x) - JavaScriptCore: 26.90ms vs 63.24ms (57.5% faster, 2.4x)
sbc100
force-pushed
the
always-bulkmem-memset
branch
from
September 2, 2026 23:16
5821f95 to
b9bbec3
Compare
sbc100
added a commit
to sbc100/emscripten
that referenced
this pull request
Sep 2, 2026
Followup to emscripten-core#27653 and emscripten-core#27656. Replace Musl's `memset.c` and the `-Oz` logic in `emscripten_memset.c` with `__builtin_wasm_memory_fill`. Under ASan, keep `__attribute__((no_sanitize("address")))` on the naive scalar loop because ASan's shadow memory poisoner calls `REAL(memset)` directly on shadow memory itself, which would otherwise trigger an immediate shadow-on-shadow fault. Microbenchmark results (100k iterations across sizes 1B to 16KB): Aligned sets (sizes 1B to 16KB): - V8: 30.36ms vs 70.52ms (56.9% faster, 2.3x) - SpiderMonkey: 31.91ms vs 67.01ms (52.4% faster, 2.1x) - JavaScriptCore: 26.70ms vs 70.44ms (62.1% faster, 2.6x) Unaligned sets (offsets 1..3 across sizes 1B to 16KB): - V8: 30.61ms vs 65.28ms (53.1% faster, 2.1x) - SpiderMonkey: 32.94ms vs 64.28ms (48.8% faster, 2.0x) - JavaScriptCore: 26.90ms vs 63.24ms (57.5% faster, 2.4x)
sbc100
force-pushed
the
always-bulkmem-memset
branch
from
September 2, 2026 23:21
b9bbec3 to
28cc785
Compare
dschuff
approved these changes
Sep 2, 2026
sbc100
added a commit
to sbc100/emscripten
that referenced
this pull request
Sep 3, 2026
Followup to emscripten-core#27653 and emscripten-core#27656. Replace Musl's `memset.c` and the `-Oz` logic in `emscripten_memset.c` with `__builtin_wasm_memory_fill`. Under ASan, keep `__attribute__((no_sanitize("address")))` on the naive scalar loop because ASan's shadow memory poisoner calls `REAL(memset)` directly on shadow memory itself, which would otherwise trigger an immediate shadow-on-shadow fault. Microbenchmark results (100k iterations across sizes 1B to 16KB): Aligned sets (sizes 1B to 16KB): - V8: 30.36ms vs 70.52ms (56.9% faster, 2.3x) - SpiderMonkey: 31.91ms vs 67.01ms (52.4% faster, 2.1x) - JavaScriptCore: 26.70ms vs 70.44ms (62.1% faster, 2.6x) Unaligned sets (offsets 1..3 across sizes 1B to 16KB): - V8: 30.61ms vs 65.28ms (53.1% faster, 2.1x) - SpiderMonkey: 32.94ms vs 64.28ms (48.8% faster, 2.0x) - JavaScriptCore: 26.90ms vs 63.24ms (57.5% faster, 2.4x)
sbc100
force-pushed
the
always-bulkmem-memset
branch
from
September 3, 2026 00:15
28cc785 to
cc09756
Compare
sbc100
force-pushed
the
always-bulkmem-memmove
branch
from
September 3, 2026 00:17
0ebd33c to
d18ee60
Compare
Member
|
I would once again like to see the benchmark, if it's not too much trouble... |
Followup to emscripten-core#27653 and emscripten-core#27656. Replace Musl's `memset.c` and the `-Oz` logic in `emscripten_memset.c` with `__builtin_wasm_memory_fill`. Under ASan, keep `__attribute__((no_sanitize("address")))` on the naive scalar loop because ASan's shadow memory poisoner calls `REAL(memset)` directly on shadow memory itself, which would otherwise trigger an immediate shadow-on-shadow fault. Microbenchmark results (100k iterations across sizes 1B to 16KB): Aligned sets (sizes 1B to 16KB): - V8: 30.36ms vs 70.52ms (56.9% faster, 2.3x) - SpiderMonkey: 31.91ms vs 67.01ms (52.4% faster, 2.1x) - JavaScriptCore: 26.70ms vs 70.44ms (62.1% faster, 2.6x) Unaligned sets (offsets 1..3 across sizes 1B to 16KB): - V8: 30.61ms vs 65.28ms (53.1% faster, 2.1x) - SpiderMonkey: 32.94ms vs 64.28ms (48.8% faster, 2.0x) - JavaScriptCore: 26.90ms vs 63.24ms (57.5% faster, 2.4x)
Collaborator
Author
AI-Generated: memset Benchmark Details & WorkloadsHere is the microbenchmark used to measure Source Code (
|
sbc100
force-pushed
the
always-bulkmem-memset
branch
from
September 3, 2026 17:58
cc09756 to
a36be01
Compare
Member
|
Thanks! Interesting, inlining does not matter here. I guess this is pretty optimal regardless. |
kripken
approved these changes
Sep 4, 2026
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.
Followup to #27653 and #27656.
Replace Musl's
memset.cand the-Ozlogic inemscripten_memset.cwith__builtin_wasm_memory_fill.Under ASan, keep
__attribute__((no_sanitize("address")))on the naive scalar loop because ASan's shadow memory poisoner callsREAL(memset)directly on shadow memory itself, which would otherwise trigger an immediate shadow-on-shadow fault.Microbenchmark results (100k iterations across sizes 1B to 16KB):
Aligned sets (sizes 1B to 16KB):
Unaligned sets (offsets 1..3 across sizes 1B to 16KB):