Skip to content

Commit 04ff9bd

Browse files
author
Sergey Andreenko
authored
Fix stress apple arm64 assertion '(thisFieldOffset + EA_SIZE_IN_BYTES(attr)) <= areaSize' (#48936)
* Fix a stress Arm64 apple issue. * fix issue.
1 parent 7e658d7 commit 04ff9bd

File tree

5 files changed

+63
-20
lines changed

5 files changed

+63
-20
lines changed

src/coreclr/jit/codegenarm64.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4821,14 +4821,7 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode)
48214821
// Need an additional integer register to extract upper 4 bytes from data.
48224822
regNumber tmpReg = lclVar->GetSingleTempReg();
48234823

4824-
// store lower 8 bytes
4825-
GetEmitter()->emitIns_S_R(INS_str, EA_8BYTE, operandReg, varNum, offs);
4826-
4827-
// Extract upper 4-bytes from data
4828-
GetEmitter()->emitIns_R_R_I(INS_mov, EA_4BYTE, tmpReg, operandReg, 2);
4829-
4830-
// 4-byte write
4831-
GetEmitter()->emitIns_S_R(INS_str, EA_4BYTE, tmpReg, varNum, offs + 8);
4824+
GetEmitter()->emitStoreSIMD12ToLclOffset(varNum, offs, operandReg, tmpReg);
48324825
}
48334826

48344827
#endif // FEATURE_SIMD

src/coreclr/jit/codegenlinear.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,20 +1841,33 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArg
18411841

18421842
// Evaluate each of the GT_FIELD_LIST items into their register
18431843
// and store their register into the outgoing argument area.
1844-
unsigned argOffset = putArgStk->getArgOffset();
1844+
const unsigned argOffset = putArgStk->getArgOffset();
18451845
for (GenTreeFieldList::Use& use : putArgStk->gtOp1->AsFieldList()->Uses())
18461846
{
18471847
GenTree* nextArgNode = use.GetNode();
18481848
genConsumeReg(nextArgNode);
18491849

1850-
regNumber reg = nextArgNode->GetRegNum();
1851-
var_types type = nextArgNode->TypeGet();
1852-
emitAttr attr = emitTypeSize(type);
1850+
regNumber reg = nextArgNode->GetRegNum();
1851+
var_types type = use.GetType();
1852+
unsigned thisFieldOffset = argOffset + use.GetOffset();
18531853

1854-
// Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing
1855-
// argument area.
1856-
unsigned thisFieldOffset = argOffset + use.GetOffset();
1857-
GetEmitter()->emitIns_S_R(ins_Store(type), attr, reg, outArgVarNum, thisFieldOffset);
1854+
// Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing
1855+
// argument area.
1856+
1857+
#if defined(FEATURE_SIMD) && defined(OSX_ARM64_ABI)
1858+
// storing of TYP_SIMD12 (i.e. Vector3) argument.
1859+
if (type == TYP_SIMD12)
1860+
{
1861+
// Need an additional integer register to extract upper 4 bytes from data.
1862+
regNumber tmpReg = nextArgNode->GetSingleTempReg();
1863+
GetEmitter()->emitStoreSIMD12ToLclOffset(outArgVarNum, thisFieldOffset, reg, tmpReg);
1864+
}
1865+
else
1866+
#endif // FEATURE_SIMD && OSX_ARM64_ABI
1867+
{
1868+
emitAttr attr = emitTypeSize(type);
1869+
GetEmitter()->emitIns_S_R(ins_Store(type), attr, reg, outArgVarNum, thisFieldOffset);
1870+
}
18581871

18591872
// We can't write beyond the arg area unless this is a tail call, in which case we use
18601873
// the first stack arg as the base of the incoming arg area.
@@ -1867,7 +1880,7 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArg
18671880
}
18681881
#endif
18691882

1870-
assert((thisFieldOffset + EA_SIZE_IN_BYTES(attr)) <= areaSize);
1883+
assert((thisFieldOffset + genTypeSize(type)) <= areaSize);
18711884
#endif
18721885
}
18731886
}

src/coreclr/jit/emitarm64.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,4 +935,30 @@ inline bool emitIsLoadConstant(instrDesc* jmp)
935935
(jmp->idInsFmt() == IF_LARGELDC));
936936
}
937937

938+
#if defined(FEATURE_SIMD)
939+
//-----------------------------------------------------------------------------------
940+
// emitStoreSIMD12ToLclOffset: store SIMD12 value from opReg to varNum+offset.
941+
//
942+
// Arguments:
943+
// varNum - the variable on the stack to use as a base;
944+
// offset - the offset from the varNum;
945+
// opReg - the src reg with SIMD12 value;
946+
// tmpReg - a tmp reg to use for the write, can be general or float.
947+
//
948+
void emitStoreSIMD12ToLclOffset(unsigned varNum, unsigned offset, regNumber opReg, regNumber tmpReg)
949+
{
950+
assert(varNum != BAD_VAR_NUM);
951+
assert(isVectorRegister(opReg));
952+
953+
// store lower 8 bytes
954+
emitIns_S_R(INS_str, EA_8BYTE, opReg, varNum, offset);
955+
956+
// Extract upper 4-bytes from data
957+
emitIns_R_R_I(INS_mov, EA_4BYTE, tmpReg, opReg, 2);
958+
959+
// 4-byte write
960+
emitIns_S_R(INS_str, EA_4BYTE, tmpReg, varNum, offset + 8);
961+
}
962+
#endif // FEATURE_SIMD
963+
938964
#endif // TARGET_ARM64

src/coreclr/jit/lsraarmarch.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,18 +398,28 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode)
398398
int srcCount = 0;
399399

400400
// Do we have a TYP_STRUCT argument (or a GT_FIELD_LIST), if so it must be a multireg pass-by-value struct
401-
if ((putArgChild->TypeGet() == TYP_STRUCT) || (putArgChild->OperGet() == GT_FIELD_LIST))
401+
if (putArgChild->TypeIs(TYP_STRUCT) || putArgChild->OperIs(GT_FIELD_LIST))
402402
{
403403
// We will use store instructions that each write a register sized value
404404

405-
if (putArgChild->OperGet() == GT_FIELD_LIST)
405+
if (putArgChild->OperIs(GT_FIELD_LIST))
406406
{
407407
assert(putArgChild->isContained());
408408
// We consume all of the items in the GT_FIELD_LIST
409409
for (GenTreeFieldList::Use& use : putArgChild->AsFieldList()->Uses())
410410
{
411411
BuildUse(use.GetNode());
412412
srcCount++;
413+
414+
#if defined(FEATURE_SIMD) && defined(OSX_ARM64_ABI)
415+
if (use.GetType() == TYP_SIMD12)
416+
{
417+
// Vector3 is read/written as two reads/writes: 8 byte and 4 byte.
418+
// To assemble the vector properly we would need an additional int register.
419+
// The other platforms can write it as 16-byte using 1 write.
420+
buildInternalIntRegisterDefForNode(use.GetNode());
421+
}
422+
#endif // FEATURE_SIMD && OSX_ARM64_ABI
413423
}
414424
}
415425
else

src/coreclr/jit/lsrabuild.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3342,7 +3342,8 @@ int LinearScan::BuildStoreLoc(GenTreeLclVarCommon* storeLoc)
33423342
RefPosition* internalFloatDef = nullptr;
33433343
if (varTypeIsSIMD(storeLoc) && !op1->IsCnsIntOrI() && (storeLoc->TypeGet() == TYP_SIMD12))
33443344
{
3345-
// Need an additional register to extract upper 4 bytes of Vector3.
3345+
// Need an additional register to extract upper 4 bytes of Vector3,
3346+
// it has to be float for x86.
33463347
internalFloatDef = buildInternalFloatRegisterDefForNode(storeLoc, allSIMDRegs());
33473348
}
33483349
#endif // FEATURE_SIMD

0 commit comments

Comments
 (0)