Skip to content

Commit f91c6ab

Browse files
Allow SIMD-returning calls as arguments
As of this change we handle all relevant ABI scenarios. 1) Windows x64: - SIMD8: returned and passed as "TYP_LONG", fine. - SIMD12 / SIMD16 / SIMD32: returned and passed via a return buffer, fine. 2) Unix x64: - SIMD8: returned and passed in one FP register, fine. - SIMD12 / SIMD16, Vector4: returned and passed in two FP registers, fine. - SIMD16, Vector128 / SIMD32: returned and passed via a return buffer, fine. 3) x86: - SIMD8: can be returned via two registers or a return buffer (and is always passed on stack), both are fine. - SIMD12/SIMD16/SIMD32: returned via a return buffer, passed on stack, fine. 4) ARM64: - SIMD8, Vector2: returned in two FP registers (and passed as such or "TYP_LONG" under Windows varargs), fine. - SIMD8, Vector64: returned in one FP register, can be passed as such or as "TYP_LONG" under Windows varargs. The latter case is now handled correctly in "Lowering::LowerArg". - SIMD12: returned in three FP registers, passed as such or in two integer registers under Windows varargs, fine. - SIMD16, Vector4: returned in four FP registers, passed as such, or in two integer registers under Windows varargs, fine. - SIMD16, Vector128: returned in one FP register, passed as such, or in two integer registers under Windows varargs, fine (morph will decompose the varargs case into a `FIELD_LIST` via a temp).
1 parent ace56a3 commit f91c6ab

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

src/coreclr/jit/lower.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ GenTree* Lowering::LowerFloatArg(GenTree** pArg, CallArg* callArg)
14191419
break;
14201420
}
14211421
GenTree* node = use.GetNode();
1422-
if (varTypeIsFloating(node))
1422+
if (varTypeUsesFloatReg(node))
14231423
{
14241424
GenTree* intNode = LowerFloatArgReg(node, currRegNumber);
14251425
assert(intNode != nullptr);
@@ -1441,7 +1441,7 @@ GenTree* Lowering::LowerFloatArg(GenTree** pArg, CallArg* callArg)
14411441
// List fields were replaced in place.
14421442
return arg;
14431443
}
1444-
else if (varTypeIsFloating(arg))
1444+
else if (varTypeUsesFloatReg(arg))
14451445
{
14461446
GenTree* intNode = LowerFloatArgReg(arg, callArg->AbiInfo.GetRegNum());
14471447
assert(intNode != nullptr);
@@ -1464,11 +1464,13 @@ GenTree* Lowering::LowerFloatArg(GenTree** pArg, CallArg* callArg)
14641464
//
14651465
GenTree* Lowering::LowerFloatArgReg(GenTree* arg, regNumber regNum)
14661466
{
1467+
assert(varTypeUsesFloatReg(arg));
1468+
14671469
var_types floatType = arg->TypeGet();
1468-
assert(varTypeIsFloating(floatType));
1469-
var_types intType = (floatType == TYP_DOUBLE) ? TYP_LONG : TYP_INT;
1470-
GenTree* intArg = comp->gtNewBitCastNode(intType, arg);
1470+
var_types intType = (floatType == TYP_FLOAT) ? TYP_INT : TYP_LONG;
1471+
GenTree* intArg = comp->gtNewBitCastNode(intType, arg);
14711472
intArg->SetRegNum(regNum);
1473+
14721474
#ifdef TARGET_ARM
14731475
if (floatType == TYP_DOUBLE)
14741476
{
@@ -3828,6 +3830,11 @@ void Lowering::LowerCallStruct(GenTreeCall* call)
38283830
assert(user->TypeIs(origType) || (returnType == user->TypeGet()));
38293831
break;
38303832

3833+
case GT_CALL:
3834+
// Argument lowering will deal with register file mismatches if needed.
3835+
assert(varTypeIsSIMD(origType));
3836+
break;
3837+
38313838
case GT_STOREIND:
38323839
#ifdef FEATURE_SIMD
38333840
if (varTypeIsSIMD(user))

0 commit comments

Comments
 (0)