diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index e36feb309892e6..fb5932bb6e6aac 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -3270,6 +3270,18 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) makeOutArgCopy = true; } + // If the arg may go into registers (both fully or split) + // then we cannot handle passing it from an arbitrary + // source if it would require passing a 3 byte chunk. + // Placing 3 bytes into a register requires multiple loads/shifts/or. + // In theory we could more easily support it for split args + // as those load registers fully always, but currently we + // do not. + if ((arg.AbiInfo.NumRegs > 0) && ((passingSize % REGSIZE_BYTES) == 3)) + { + makeOutArgCopy = true; + } + if (structSize < TARGET_POINTER_SIZE) { makeOutArgCopy = true; @@ -3854,7 +3866,7 @@ GenTree* Compiler::fgMorphMultiregStructArg(CallArg* arg) break; #endif // (TARGET_ARM64) || (UNIX_AMD64_ABI) || (TARGET_LOONGARCH64) default: - noway_assert(!"NYI: odd sized struct in fgMorphMultiregStructArg"); + noway_assert(!"Cannot load odd sized last element from arbitrary source"); break; } } diff --git a/src/tests/JIT/Directed/StructABI/SevenByteStruct.cs b/src/tests/JIT/Directed/StructABI/SevenByteStruct.cs new file mode 100644 index 00000000000000..b8924b99bc417f --- /dev/null +++ b/src/tests/JIT/Directed/StructABI/SevenByteStruct.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +// On ARM32 the following has S0 passed in two registers, which requires passing 3 bytes in the last register. +// We cannot do that in a single load from an arbitrary source and must copy it to a local first. + +public struct S0 +{ + public byte F0; + public byte F1; + public byte F2; + public byte F3; + public byte F4; + public byte F5; + public byte F6; +} + +public class SevenByteStruct +{ + public static S0 s_4 = new S0 { F0 = 1, F1 = 2, F2 = 3, F3 = 4, F4 = 5, F5 = 6, F6 = 7 }; + public static int Main() + { + ref S0 vr0 = ref s_4; + int sum = M35(vr0); + return sum == 28 ? 100 : -1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int M35(S0 arg0) + { + return arg0.F0 + arg0.F1 + arg0.F2 + arg0.F3 + arg0.F4 + arg0.F5 + arg0.F6; + } +} diff --git a/src/tests/JIT/Directed/StructABI/SevenByteStruct.csproj b/src/tests/JIT/Directed/StructABI/SevenByteStruct.csproj new file mode 100644 index 00000000000000..9d281a449d0710 --- /dev/null +++ b/src/tests/JIT/Directed/StructABI/SevenByteStruct.csproj @@ -0,0 +1,12 @@ + + + Exe + + + PdbOnly + True + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 47fb27b300a780..0637d41ba60411 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -543,12 +543,6 @@ https://github.com/dotnet/runtime/issues/66745 - - https://github.com/dotnet/runtime/issues/70042 - - - https://github.com/dotnet/runtime/issues/70042 - @@ -678,18 +672,6 @@ https://github.com/dotnet/runtime/issues/57856 - - https://github.com/dotnet/runtime/issues/68837 - - - https://github.com/dotnet/runtime/issues/68837 - - - https://github.com/dotnet/runtime/issues/68837 - - - https://github.com/dotnet/runtime/issues/68837 - https://github.com/dotnet/runtime/issues/57875