diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp
index 6a2ea012d1966b..f1426fc23487b8 100644
--- a/src/coreclr/jit/codegenarmarch.cpp
+++ b/src/coreclr/jit/codegenarmarch.cpp
@@ -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);
@@ -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;
}
}
@@ -1146,7 +1147,6 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
assert(argOffsetOut <= argOffsetMax); // We can't write beyond the outgoing arg area
structOffset += moveSize;
- nextIndex++;
}
}
}
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 5bae35e0fad877..ffaaecc97dd10b 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -99,11 +99,6 @@
-
-
-
-
-
diff --git a/src/tests/JIT/Directed/StructABI/MisSizedStructs.cs b/src/tests/JIT/Directed/StructABI/MisSizedStructs.cs
new file mode 100644
index 00000000000000..3fb55a909960f6
--- /dev/null
+++ b/src/tests/JIT/Directed/StructABI/MisSizedStructs.cs
@@ -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];
+ }
+}
diff --git a/src/tests/JIT/Directed/StructABI/MisSizedStructs.csproj b/src/tests/JIT/Directed/StructABI/MisSizedStructs.csproj
new file mode 100644
index 00000000000000..de62e29fa3e187
--- /dev/null
+++ b/src/tests/JIT/Directed/StructABI/MisSizedStructs.csproj
@@ -0,0 +1,13 @@
+
+
+ Exe
+ true
+
+
+ PdbOnly
+ True
+
+
+
+
+