-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Labels
JitUntriagedCLR JIT issues needing additional triageCLR JIT issues needing additional triagearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additionsoptimization
Milestone
Description
I've got code similar to the following repro:
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
public class C
{
public static void Main() => new C().TryFormat(new char[4], out _);
public bool TryFormat(Span<char> dst, out int charsWritten)
{
if (dst.Length >= 4)
{
dst[0] = 't';
dst[1] = 'r';
dst[2] = 'u';
dst[3] = 'e';
charsWritten = 4;
return true;
}
charsWritten = 0;
return false;
}
}I was hoping/expecting the bounds checks on each of those four writes to dst to be eliminated, but they’re not:
G_M404_IG02:
488B02 mov rax, bword ptr [rdx]
8B5208 mov edx, dword ptr [rdx+8]
83FA04 cmp edx, 4
7C3C jl SHORT G_M404_IG04
83FA00 cmp edx, 0
7641 jbe SHORT G_M404_IG06
66C7007400 mov word ptr [rax], 116
83FA01 cmp edx, 1
7637 jbe SHORT G_M404_IG06
66C740027200 mov word ptr [rax+2], 114
83FA02 cmp edx, 2
762C jbe SHORT G_M404_IG06
66C740047500 mov word ptr [rax+4], 117
83FA03 cmp edx, 3
7621 jbe SHORT G_M404_IG06
66C740066500 mov word ptr [rax+6], 101
41C70004000000 mov dword ptr [r8], 4
B801000000 mov eax, 1
To work around that, I can use Unsafe.Add and MemoryMarshal.GetReference, e.g.
public bool TryFormat(Span<char> dst, out int charsWritten)
{
if (dst.Length >= 4)
{
ref char c = ref MemoryMarshal.GetReference(dst);
c = 't';
Unsafe.Add(ref c, 1) = 'r';
Unsafe.Add(ref c, 2) = 'u';
Unsafe.Add(ref c, 3) = 'e';
charsWritten = 4;
return true;
}
charsWritten = 0;
return false;
}in which case I get the better:
G_M408_IG02:
837A0804 cmp dword ptr [rdx+8], 4
7C27 jl SHORT G_M408_IG04
488B02 mov rax, bword ptr [rdx]
66C7007400 mov word ptr [rax], 116
66C740027200 mov word ptr [rax+2], 114
66C740047500 mov word ptr [rax+4], 117
66C740066500 mov word ptr [rax+6], 101
41C70004000000 mov dword ptr [r8], 4
B801000000 mov eax, 1
but it’d be nice not to have to use Unsafe for cases like this.
cc: @AndyAyersMS
Related: https://github.com/dotnet/coreclr/issues/12639
category:cq
theme:range-check
skill-level:intermediate
cost:medium
Metadata
Metadata
Assignees
Labels
JitUntriagedCLR JIT issues needing additional triageCLR JIT issues needing additional triagearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additionsoptimization