Skip to content

Commit

Permalink
Handle mis-sized structs in ARM/64 PUTARG_STK codegen (#69905)
Browse files Browse the repository at this point in the history
* Handle mis-sized structs for PUTARG_STK on ARM/64

We will now generate a series of small loads as necessary
to handle "remainderSize"s of 3, 5, 6 and 7.

* Add tests

* Re-enable tests for 60705
  • Loading branch information
SingleAccretion authored May 28, 2022
1 parent 9a185a7 commit 120e2f5
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 12 deletions.
14 changes: 7 additions & 7 deletions src/coreclr/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1095,8 +1095,9 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)

while (remainingSize > 0)
{
var_types type;
nextIndex = structOffset / TARGET_POINTER_SIZE;

var_types type;
if (remainingSize >= TARGET_POINTER_SIZE)
{
type = layout->GetGCPtrType(nextIndex);
Expand All @@ -1106,18 +1107,18 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
// the left over size is smaller than a pointer and thus can never be a GC type
assert(!layout->IsGCPtr(nextIndex));

if (remainingSize == 1)
if (remainingSize >= 4)
{
type = TYP_UBYTE;
type = TYP_INT;
}
else if (remainingSize == 2)
else if (remainingSize >= 2)
{
type = TYP_USHORT;
}
else
{
assert(remainingSize == 4);
type = TYP_UINT;
assert(remainingSize == 1);
type = TYP_UBYTE;
}
}

Expand Down Expand Up @@ -1146,7 +1147,6 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
assert(argOffsetOut <= argOffsetMax); // We can't write beyond the outgoing arg area

structOffset += moveSize;
nextIndex++;
}
}
}
Expand Down
5 changes: 0 additions & 5 deletions src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,6 @@
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices\tests\LibraryImportGenerator.Tests\LibraryImportGenerator.Tests.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetArchitecture)' == 'arm'">
<!-- Issue: https://github.com/dotnet/runtime/issues/60705 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices\tests\LibraryImportGenerator.UnitTests\LibraryImportGenerator.Unit.Tests.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'FreeBSD'">
<!-- LibraryImportGenerator runtime tests build depends pulling down a pre-built nethost binary, which is not available for FreeBSD. -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices\tests\LibraryImportGenerator.Tests\LibraryImportGenerator.Tests.csproj" />
Expand Down
196 changes: 196 additions & 0 deletions src/tests/JIT/Directed/StructABI/MisSizedStructs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

public unsafe class MisSizedStructs
{
public const byte ByteValue = 0xC1;

public static int Main()
{
const int BytesSize = 256;
var bytes = stackalloc byte[BytesSize];
Unsafe.InitBlock(bytes, ByteValue, BytesSize);

if (ProblemWithStructWithThreeBytes(bytes))
{
return 101;
}

if (ProblemWithStructWithFiveBytes(bytes))
{
return 102;
}

if (ProblemWithStructWithSixBytes(bytes))
{
return 103;
}

if (ProblemWithStructWithSevenBytes(bytes))
{
return 104;
}

if (ProblemWithStructWithElevenBytes(bytes))
{
return 105;
}

if (ProblemWithStructWithThirteenBytes(bytes))
{
return 106;
}

if (ProblemWithStructWithFourteenBytes(bytes))
{
return 107;
}

if (ProblemWithStructWithFifteenBytes(bytes))
{
return 108;
}

if (ProblemWithStructWithNineteenBytes(bytes))
{
return 109;
}

return 100;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool ProblemWithStructWithThreeBytes(byte* bytes)
{
return CallForStructWithThreeBytes(default, *(StructWithThreeBytes*)bytes) != ByteValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool ProblemWithStructWithFiveBytes(byte* bytes)
{
return CallForStructWithFiveBytes(default, *(StructWithFiveBytes*)bytes) != ByteValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool ProblemWithStructWithSixBytes(byte* bytes)
{
return CallForStructWithSixBytes(default, *(StructWithSixBytes*)bytes) != ByteValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool ProblemWithStructWithSevenBytes(byte* bytes)
{
return CallForStructWithSevenBytes(default, *(StructWithSevenBytes*)bytes) != ByteValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool ProblemWithStructWithElevenBytes(byte* bytes)
{
return CallForStructWithElevenBytes(default, *(StructWithElevenBytes*)bytes) != ByteValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool ProblemWithStructWithThirteenBytes(byte* bytes)
{
return CallForStructWithThirteenBytes(default, *(StructWithThirteenBytes*)bytes) != ByteValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool ProblemWithStructWithFourteenBytes(byte* bytes)
{
return CallForStructWithFourteenBytes(default, *(StructWithFourteenBytes*)bytes) != ByteValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool ProblemWithStructWithFifteenBytes(byte* bytes)
{
return CallForStructWithFifteenBytes(default, *(StructWithFifteenBytes*)bytes) != ByteValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool ProblemWithStructWithNineteenBytes(byte* bytes)
{
return CallForStructWithNineteenBytes(default, *(StructWithNineteenBytes*)bytes) != ByteValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static byte CallForStructWithThreeBytes(ForceStackUsage fs, StructWithThreeBytes value) => value.Bytes[2];

[MethodImpl(MethodImplOptions.NoInlining)]
private static byte CallForStructWithFiveBytes(ForceStackUsage fs, StructWithFiveBytes value) => value.Bytes[4];

[MethodImpl(MethodImplOptions.NoInlining)]
private static byte CallForStructWithSixBytes(ForceStackUsage fs, StructWithSixBytes value) => value.Bytes[5];

[MethodImpl(MethodImplOptions.NoInlining)]
private static byte CallForStructWithSevenBytes(ForceStackUsage fs, StructWithSevenBytes value) => value.Bytes[6];

[MethodImpl(MethodImplOptions.NoInlining)]
private static byte CallForStructWithElevenBytes(ForceStackUsage fs, StructWithElevenBytes value) => value.Bytes[10];

[MethodImpl(MethodImplOptions.NoInlining)]
private static byte CallForStructWithThirteenBytes(ForceStackUsage fs, StructWithThirteenBytes value) => value.Bytes[12];

[MethodImpl(MethodImplOptions.NoInlining)]
private static byte CallForStructWithFourteenBytes(ForceStackUsage fs, StructWithFourteenBytes value) => value.Bytes[13];

[MethodImpl(MethodImplOptions.NoInlining)]
private static byte CallForStructWithFifteenBytes(ForceStackUsage fs, StructWithFifteenBytes value) => value.Bytes[14];

[MethodImpl(MethodImplOptions.NoInlining)]
private static byte CallForStructWithNineteenBytes(ForceStackUsage fs, StructWithNineteenBytes value) => value.Bytes[18];

struct ForceStackUsage
{
public fixed byte Bytes[40];
}

struct StructWithThreeBytes
{
public fixed byte Bytes[3];
}

struct StructWithFiveBytes
{
public fixed byte Bytes[5];
}

struct StructWithSixBytes
{
public fixed byte Bytes[6];
}

struct StructWithSevenBytes
{
public fixed byte Bytes[7];
}

struct StructWithElevenBytes
{
public fixed byte Bytes[11];
}

struct StructWithThirteenBytes
{
public fixed byte Bytes[13];
}

struct StructWithFourteenBytes
{
public fixed byte Bytes[14];
}

struct StructWithFifteenBytes
{
public fixed byte Bytes[15];
}

struct StructWithNineteenBytes
{
public fixed byte Bytes[19];
}
}
13 changes: 13 additions & 0 deletions src/tests/JIT/Directed/StructABI/MisSizedStructs.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<DebugType>PdbOnly</DebugType>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>

0 comments on commit 120e2f5

Please sign in to comment.