Skip to content

Commit 5f8a2ee

Browse files
SwapnilGaikwadkunalspathakfanyang-mono
authored
Rename StoreVectorMxNAndZip to StoreVectorAndZip (#103638)
* Arm AdvSimd: Rename StoreVectorMxNAndZip to StoreVectorAndZip * Mono: Rename StoreVectorMxNAndZip to StoreVectorAndZip * Use a single entry of StoreVectorAndZip instead of its NxM variants in hwintrinsiclistarm64.h * Wrap code in #ifdef DEBUG * Refactor StoreSelectedScalar to match VectorTableLookup * Fix the way that mono emits intrinsics of SN_StoreVectorAndZip --------- Co-authored-by: Kunal Pathak <[email protected]> Co-authored-by: fanyang-mono <[email protected]>
1 parent 2fc073f commit 5f8a2ee

File tree

15 files changed

+397
-345
lines changed

15 files changed

+397
-345
lines changed

src/coreclr/jit/hwintrinsicarm64.cpp

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -389,13 +389,7 @@ void HWIntrinsicInfo::lookupImmBounds(
389389
case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3:
390390
case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4:
391391
case NI_AdvSimd_StoreSelectedScalar:
392-
case NI_AdvSimd_StoreSelectedScalarVector64x2:
393-
case NI_AdvSimd_StoreSelectedScalarVector64x3:
394-
case NI_AdvSimd_StoreSelectedScalarVector64x4:
395392
case NI_AdvSimd_Arm64_StoreSelectedScalar:
396-
case NI_AdvSimd_Arm64_StoreSelectedScalarVector128x2:
397-
case NI_AdvSimd_Arm64_StoreSelectedScalarVector128x3:
398-
case NI_AdvSimd_Arm64_StoreSelectedScalarVector128x4:
399393
case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128:
400394
case NI_AdvSimd_Arm64_InsertSelectedScalar:
401395
case NI_Sve_FusedMultiplyAddBySelectedScalar:
@@ -2042,12 +2036,50 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
20422036
break;
20432037
}
20442038

2045-
case NI_AdvSimd_StoreVector64x2AndZip:
2046-
case NI_AdvSimd_StoreVector64x3AndZip:
2047-
case NI_AdvSimd_StoreVector64x4AndZip:
2048-
case NI_AdvSimd_Arm64_StoreVector128x2AndZip:
2049-
case NI_AdvSimd_Arm64_StoreVector128x3AndZip:
2050-
case NI_AdvSimd_Arm64_StoreVector128x4AndZip:
2039+
case NI_AdvSimd_StoreVectorAndZip:
2040+
case NI_AdvSimd_Arm64_StoreVectorAndZip:
2041+
{
2042+
assert(sig->numArgs == 2);
2043+
assert(retType == TYP_VOID);
2044+
2045+
CORINFO_ARG_LIST_HANDLE arg1 = sig->args;
2046+
CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1);
2047+
var_types argType = TYP_UNKNOWN;
2048+
CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE;
2049+
2050+
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
2051+
op2 = impPopStack().val;
2052+
unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(argClass);
2053+
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass)));
2054+
op1 = getArgForHWIntrinsic(argType, argClass);
2055+
2056+
assert(op2->TypeGet() == TYP_STRUCT);
2057+
if (op1->OperIs(GT_CAST))
2058+
{
2059+
// Although the API specifies a pointer, if what we have is a BYREF, that's what
2060+
// we really want, so throw away the cast.
2061+
if (op1->gtGetOp1()->TypeGet() == TYP_BYREF)
2062+
{
2063+
op1 = op1->gtGetOp1();
2064+
}
2065+
}
2066+
2067+
if (!op2->OperIs(GT_LCL_VAR))
2068+
{
2069+
unsigned tmp = lvaGrabTemp(true DEBUGARG("StoreVectorNx2 temp tree"));
2070+
2071+
impStoreToTemp(tmp, op2, CHECK_SPILL_NONE);
2072+
op2 = gtNewLclvNode(tmp, argType);
2073+
}
2074+
op2 = gtConvertTableOpToFieldList(op2, fieldCount);
2075+
2076+
intrinsic = simdSize == 8 ? NI_AdvSimd_StoreVectorAndZip : NI_AdvSimd_Arm64_StoreVectorAndZip;
2077+
2078+
info.compNeedsConsecutiveRegisters = true;
2079+
retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize);
2080+
break;
2081+
}
2082+
20512083
case NI_AdvSimd_StoreVector64x2:
20522084
case NI_AdvSimd_StoreVector64x3:
20532085
case NI_AdvSimd_StoreVector64x4:
@@ -2123,23 +2155,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
21232155
if (op2->TypeGet() == TYP_STRUCT)
21242156
{
21252157
info.compNeedsConsecutiveRegisters = true;
2126-
switch (fieldCount)
2127-
{
2128-
case 2:
2129-
intrinsic = simdSize == 8 ? NI_AdvSimd_StoreSelectedScalarVector64x2
2130-
: NI_AdvSimd_Arm64_StoreSelectedScalarVector128x2;
2131-
break;
2132-
case 3:
2133-
intrinsic = simdSize == 8 ? NI_AdvSimd_StoreSelectedScalarVector64x3
2134-
: NI_AdvSimd_Arm64_StoreSelectedScalarVector128x3;
2135-
break;
2136-
case 4:
2137-
intrinsic = simdSize == 8 ? NI_AdvSimd_StoreSelectedScalarVector64x4
2138-
: NI_AdvSimd_Arm64_StoreSelectedScalarVector128x4;
2139-
break;
2140-
default:
2141-
assert("unsupported");
2142-
}
2158+
intrinsic = simdSize == 8 ? NI_AdvSimd_StoreSelectedScalar : NI_AdvSimd_Arm64_StoreSelectedScalar;
21432159

21442160
if (!op2->OperIs(GT_LCL_VAR))
21452161
{

src/coreclr/jit/hwintrinsiccodegenarm64.cpp

Lines changed: 84 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,37 +1223,52 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
12231223
GetEmitter()->emitIns_R_R_R(ins, emitTypeSize(intrin.baseType), op2Reg, op3Reg, op1Reg);
12241224
break;
12251225

1226-
case NI_AdvSimd_StoreSelectedScalarVector64x2:
1227-
case NI_AdvSimd_StoreSelectedScalarVector64x3:
1228-
case NI_AdvSimd_StoreSelectedScalarVector64x4:
1229-
case NI_AdvSimd_Arm64_StoreSelectedScalarVector128x2:
1230-
case NI_AdvSimd_Arm64_StoreSelectedScalarVector128x3:
1231-
case NI_AdvSimd_Arm64_StoreSelectedScalarVector128x4:
1226+
case NI_AdvSimd_StoreSelectedScalar:
1227+
case NI_AdvSimd_Arm64_StoreSelectedScalar:
12321228
{
1233-
assert(intrin.op2->OperIsFieldList());
1234-
GenTreeFieldList* fieldList = intrin.op2->AsFieldList();
1235-
GenTree* firstField = fieldList->Uses().GetHead()->GetNode();
1236-
op2Reg = firstField->GetRegNum();
1229+
unsigned regCount = 0;
1230+
if (intrin.op2->OperIsFieldList())
1231+
{
1232+
GenTreeFieldList* fieldList = intrin.op2->AsFieldList();
1233+
GenTree* firstField = fieldList->Uses().GetHead()->GetNode();
1234+
op2Reg = firstField->GetRegNum();
12371235

1236+
regNumber argReg = op2Reg;
1237+
for (GenTreeFieldList::Use& use : fieldList->Uses())
1238+
{
1239+
regCount++;
12381240
#ifdef DEBUG
1239-
unsigned regCount = 0;
1240-
regNumber argReg = op2Reg;
1241-
for (GenTreeFieldList::Use& use : fieldList->Uses())
1241+
GenTree* argNode = use.GetNode();
1242+
assert(argReg == argNode->GetRegNum());
1243+
argReg = getNextSIMDRegWithWraparound(argReg);
1244+
#endif
1245+
}
1246+
}
1247+
else
12421248
{
1243-
regCount++;
1249+
regCount = 1;
1250+
}
12441251

1245-
GenTree* argNode = use.GetNode();
1246-
assert(argReg == argNode->GetRegNum());
1247-
argReg = getNextSIMDRegWithWraparound(argReg);
1252+
switch (regCount)
1253+
{
1254+
case 2:
1255+
ins = INS_st2;
1256+
break;
1257+
1258+
case 3:
1259+
ins = INS_st3;
1260+
break;
1261+
1262+
case 4:
1263+
ins = INS_st4;
1264+
break;
1265+
1266+
default:
1267+
assert(regCount == 1);
1268+
ins = INS_st1;
1269+
break;
12481270
}
1249-
assert((ins == INS_st2 && regCount == 2) || (ins == INS_st3 && regCount == 3) ||
1250-
(ins == INS_st4 && regCount == 4));
1251-
#endif
1252-
FALLTHROUGH;
1253-
}
1254-
case NI_AdvSimd_StoreSelectedScalar:
1255-
case NI_AdvSimd_Arm64_StoreSelectedScalar:
1256-
{
1271+
12571272
HWIntrinsicImmOpHelper helper(this, intrin.op3, node);
12581273

12591274
for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd())
@@ -1265,12 +1280,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
12651280
break;
12661281
}
12671282

1268-
case NI_AdvSimd_StoreVector64x2AndZip:
1269-
case NI_AdvSimd_StoreVector64x3AndZip:
1270-
case NI_AdvSimd_StoreVector64x4AndZip:
1271-
case NI_AdvSimd_Arm64_StoreVector128x2AndZip:
1272-
case NI_AdvSimd_Arm64_StoreVector128x3AndZip:
1273-
case NI_AdvSimd_Arm64_StoreVector128x4AndZip:
12741283
case NI_AdvSimd_StoreVector64x2:
12751284
case NI_AdvSimd_StoreVector64x3:
12761285
case NI_AdvSimd_StoreVector64x4:
@@ -1305,6 +1314,50 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
13051314
break;
13061315
}
13071316

1317+
case NI_AdvSimd_StoreVectorAndZip:
1318+
case NI_AdvSimd_Arm64_StoreVectorAndZip:
1319+
{
1320+
unsigned regCount = 0;
1321+
1322+
assert(intrin.op2->OperIsFieldList());
1323+
1324+
GenTreeFieldList* fieldList = intrin.op2->AsFieldList();
1325+
GenTree* firstField = fieldList->Uses().GetHead()->GetNode();
1326+
op2Reg = firstField->GetRegNum();
1327+
1328+
regNumber argReg = op2Reg;
1329+
for (GenTreeFieldList::Use& use : fieldList->Uses())
1330+
{
1331+
regCount++;
1332+
#ifdef DEBUG
1333+
GenTree* argNode = use.GetNode();
1334+
assert(argReg == argNode->GetRegNum());
1335+
argReg = getNextSIMDRegWithWraparound(argReg);
1336+
#endif
1337+
}
1338+
1339+
switch (regCount)
1340+
{
1341+
case 2:
1342+
ins = INS_st2;
1343+
break;
1344+
1345+
case 3:
1346+
ins = INS_st3;
1347+
break;
1348+
1349+
case 4:
1350+
ins = INS_st4;
1351+
break;
1352+
1353+
default:
1354+
unreached();
1355+
}
1356+
1357+
GetEmitter()->emitIns_R_R(ins, emitSize, op2Reg, op1Reg, opt);
1358+
break;
1359+
}
1360+
13081361
case NI_Vector64_CreateScalarUnsafe:
13091362
case NI_Vector128_CreateScalarUnsafe:
13101363
if (intrin.op1->isContainedFltOrDblImmed())

0 commit comments

Comments
 (0)