Skip to content

Commit

Permalink
Fix passing too small args for PUTARG_STK on macOS arm64 ABI (#68113)
Browse files Browse the repository at this point in the history
Backport of #68108
  • Loading branch information
jakobbotsch authored May 5, 2022
1 parent 3199160 commit 39dbeee
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 15 deletions.
29 changes: 14 additions & 15 deletions src/coreclr/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -681,12 +681,6 @@ void CodeGen::genIntrinsic(GenTree* treeNode)
void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
{
assert(treeNode->OperIs(GT_PUTARG_STK));
GenTree* source = treeNode->gtOp1;
#if !defined(OSX_ARM64_ABI)
var_types targetType = genActualType(source->TypeGet());
#else
var_types targetType = source->TypeGet();
#endif
emitter* emit = GetEmitter();

// This is the varNum for our store operations,
Expand Down Expand Up @@ -730,11 +724,13 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
argOffsetMax = compiler->lvaOutgoingArgSpaceSize;
}

bool isStruct = (targetType == TYP_STRUCT) || (source->OperGet() == GT_FIELD_LIST);
GenTree* source = treeNode->gtGetOp1();

bool isStruct = source->TypeIs(TYP_STRUCT) || (source->OperGet() == GT_FIELD_LIST);

if (!isStruct) // a normal non-Struct argument
{
if (varTypeIsSIMD(targetType))
if (varTypeIsSIMD(source->TypeGet()))
{
assert(!source->isContained());

Expand All @@ -753,31 +749,34 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
else
#endif // OSX_ARM64_ABI
{
emitAttr storeAttr = emitTypeSize(targetType);
emitAttr storeAttr = emitTypeSize(source->TypeGet());
emit->emitIns_S_R(INS_str, storeAttr, srcReg, varNumOut, argOffsetOut);
argOffsetOut += EA_SIZE_IN_BYTES(storeAttr);
}
assert(argOffsetOut <= argOffsetMax); // We can't write beyond the outgoing arg area
return;
}

#if defined(OSX_ARM64_ABI)
var_types slotType = genActualType(source);
#ifdef OSX_ARM64_ABI
// Small typed args do not get their own full stack slots, so make
// sure we do not overwrite adjacent arguments.
switch (treeNode->GetStackByteSize())
{
case 1:
targetType = TYP_BYTE;
slotType = TYP_BYTE;
break;
case 2:
targetType = TYP_SHORT;
slotType = TYP_SHORT;
break;
default:
assert(treeNode->GetStackByteSize() >= 4);
break;
}
#endif

instruction storeIns = ins_Store(targetType);
emitAttr storeAttr = emitTypeSize(targetType);
instruction storeIns = ins_Store(slotType);
emitAttr storeAttr = emitTypeSize(slotType);

// If it is contained then source must be the integer constant zero
if (source->isContained())
Expand All @@ -797,7 +796,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
genConsumeReg(source);
emit->emitIns_S_R(storeIns, storeAttr, source->GetRegNum(), varNumOut, argOffsetOut);
#ifdef TARGET_ARM
if (targetType == TYP_LONG)
if (source->TypeIs(TYP_LONG))
{
// This case currently only occurs for double types that are passed as TYP_LONG;
// actual long types would have been decomposed by now.
Expand Down
29 changes: 29 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_66720/Runtime_66720.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// 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;

public class Runtime_66720
{
public static int Main()
{
return Test(0);
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static int Test(in short zero)
{
// Fill arg stack slot with all ones
LastArg(0, 0, 0, 0, 0, 0, 0, 0, -1);
// Bug was that the last arg passed here would write only 16 bits
// instead of 32 bits
int last = LastArg(0, 0, 0, 0, 0, 0, 0, 0, zero);
return last == 0 ? 100 : -1;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static int LastArg(int a, int b, int c, int d, int e, int f, int g, int h, int i)
{
return i;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>

0 comments on commit 39dbeee

Please sign in to comment.