zero in jit
struct example
using System;
unsafe struct S1
{
    public fixed byte a[10];
    public int b;
    public fixed byte c[23];
    public fixed byte d[24];
    public fixed byte e[25];
} //88个字节
unsafe struct S2
{
    public fixed short a[10];
    public int b;
    public fixed short c[23];
    public fixed short d[24];
    public fixed short e[25];
} //168个字节
class C
{
    public S1 X1()
    {
        S1 s = default;
        return s;
    }
    public S2 X2()
    {
        S2 s = default;
        return s;
    }
}
class Program
{
    static void Main()
    {
        C c = new C();
        S1 result1 = c.X1();
//        Console.WriteLine($"Size of S1: {sizeof(S1)} bytes");
        S2 result2 = c.X2();
//        Console.WriteLine($"Size of S2: {sizeof(S2)} bytes");
    }
}COMPlus_JitHWIntrinsic=0:
未开启SIMD清0
X1的assembly
       xor      edx, edx
       mov      qword ptr [rbp-0x60], rdx
       mov      qword ptr [rbp-0x58], rdx
       mov      qword ptr [rbp-0x50], rdx
       mov      qword ptr [rbp-0x48], rdx
       mov      qword ptr [rbp-0x40], rdx
       mov      qword ptr [rbp-0x38], rdx
       mov      qword ptr [rbp-0x30], rdx
       mov      qword ptr [rbp-0x28], rdx
       mov      qword ptr [rbp-0x20], rdx
       mov      qword ptr [rbp-0x18], rdx
       mov      qword ptr [rbp-0x10], rdxX2的assembly
       xor      esi, esi
       lea      rdi, bword ptr [rbp-0xB0]
       mov      edx, 168
       call     CORINFO_HELP_MEMSET  //调用系统库的memset
       mov      rdi, bword ptr [rbp-0xD8]如何调用memset [https://github.com/dotnet/runtime/blob/main/src/coreclr/vm/amd64/crthelpers.S]
LEAF_ENTRY JIT_MemSet, _TEXT
        test    rdx, rdx                // check if count is zero
        jz      Exit_MemSet             // if zero, no bytes to set
        cmp     byte ptr [rdi], 0       // check dest for null
        jmp     C_PLTFUNC(memset)       // forward to the CRT implementation
Exit_MemSet:
        ret
LEAF_END_MARKED JIT_MemSet, _TEXTCOMPlus_JitHWIntrinsic=1:
开启SIMD
X1的assembly
       vxorps   ymm0, ymm0, ymm0
       vmovdqu  ymmword ptr [rbp-0x60], ymm0
       vmovdqu  ymmword ptr [rbp-0x40], ymm0
       vmovdqu  ymmword ptr [rbp-0x28], ymm0X2的assembly
       vxorps   ymm0, ymm0, ymm0
       vmovdqu  ymmword ptr [rbp-0xB0], ymm0
       vmovdqu  ymmword ptr [rbp-0x90], ymm0
       vmovdqu  ymmword ptr [rbp-0x70], ymm0
       vmovdqu  ymmword ptr [rbp-0x50], ymm0
       vmovdqu  ymmword ptr [rbp-0x30], ymm0
       vmovdqu  xmmword ptr [rbp-0x18], xmm0如果cpu支持AVX512 会使用zmm0
针对GT_STOREBLK的变换 [https://github.com/dotnet/runtime/blob/main/src/coreclr/jit/codegenxarch.cpp]
void CodeGen::genCodeForStoreBlk(GenTreeBlk* storeBlkNode)
{
    assert(storeBlkNode->OperIs(GT_STORE_DYN_BLK, GT_STORE_BLK));
    bool isCopyBlk = storeBlkNode->OperIsCopyBlkOp();
    switch (storeBlkNode->gtBlkOpKind)
    {
        case GenTreeBlk::BlkOpKindCpObjRepInstr:
        case GenTreeBlk::BlkOpKindCpObjUnroll:
#ifndef JIT32_GCENCODER
            assert(!storeBlkNode->gtBlkOpGcUnsafe);
#endif
            genCodeForCpObj(storeBlkNode->AsBlk());
            break;
#ifdef TARGET_AMD64
        case GenTreeBlk::BlkOpKindHelper:
            assert(!storeBlkNode->gtBlkOpGcUnsafe);
            if (isCopyBlk)
            {
                genCodeForCpBlkHelper(storeBlkNode);
            }
            else
            {
                genCodeForInitBlkHelper(storeBlkNode);
            }
            break;
#endif // TARGET_AMD64
        case GenTreeBlk::BlkOpKindRepInstr:
#ifndef JIT32_GCENCODER
            assert(!storeBlkNode->gtBlkOpGcUnsafe);
#endif
            if (isCopyBlk)
            {
                genCodeForCpBlkRepMovs(storeBlkNode);
            }
            else
            {
                genCodeForInitBlkRepStos(storeBlkNode);
            }
            break;
        case GenTreeBlk::BlkOpKindUnrollMemmove:
        case GenTreeBlk::BlkOpKindUnroll:
            if (isCopyBlk)
            {
#ifndef JIT32_GCENCODER
                if (storeBlkNode->gtBlkOpGcUnsafe)
                {
                    GetEmitter()->emitDisableGC();
                }
#endif
                if (storeBlkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindUnroll)
                {
                    genCodeForCpBlkUnroll(storeBlkNode);
                }
                else
                {
                    assert(storeBlkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindUnrollMemmove);
                    genCodeForMemmove(storeBlkNode);
                }
#ifndef JIT32_GCENCODER
                if (storeBlkNode->gtBlkOpGcUnsafe)
                {
                    GetEmitter()->emitEnableGC();
                }
#endif
            }
            else
            {
#ifndef JIT32_GCENCODER
                assert(!storeBlkNode->gtBlkOpGcUnsafe);
#endif
                genCodeForInitBlkUnroll(storeBlkNode);
            }
            break;
        default:
            unreached();
    }
}stackalloc example
using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Diagnosers;
using System.Linq;
using System.Runtime.CompilerServices;
[DisassemblyDiagnoser(printInstructionAddresses: true, syntax: DisassemblySyntax.Masm)]
public class MyBenchmark
{
    [Benchmark]
    public void Constant256() => Use(stackalloc byte[256]);
    [Benchmark]
    public void Constant1024() => Use(stackalloc byte[1024]);
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Use(Span<byte> span)
    {
       // Console.WriteLine("Hello");
        // Do something with the span, or leave it empty for a baseline measurement
    }
}
class Program
{
    public static void Main(string[] args)
    {
        var summary = BenchmarkRunner.Run<MyBenchmark>();
    }
}