Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
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).
  • Loading branch information
SingleAccretion authored and github-actions committed Aug 24, 2022
commit e64061b31a3c43da5b0a80d6e2a42bad0ad4bcdf
17 changes: 12 additions & 5 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,7 @@ GenTree* Lowering::LowerFloatArg(GenTree** pArg, CallArg* callArg)
break;
}
GenTree* node = use.GetNode();
if (varTypeIsFloating(node))
if (varTypeUsesFloatReg(node))
{
GenTree* intNode = LowerFloatArgReg(node, currRegNumber);
assert(intNode != nullptr);
Expand All @@ -1447,7 +1447,7 @@ GenTree* Lowering::LowerFloatArg(GenTree** pArg, CallArg* callArg)
// List fields were replaced in place.
return arg;
}
else if (varTypeIsFloating(arg))
else if (varTypeUsesFloatReg(arg))
{
GenTree* intNode = LowerFloatArgReg(arg, callArg->AbiInfo.GetRegNum());
assert(intNode != nullptr);
Expand All @@ -1470,11 +1470,13 @@ GenTree* Lowering::LowerFloatArg(GenTree** pArg, CallArg* callArg)
//
GenTree* Lowering::LowerFloatArgReg(GenTree* arg, regNumber regNum)
{
assert(varTypeUsesFloatReg(arg));

var_types floatType = arg->TypeGet();
assert(varTypeIsFloating(floatType));
var_types intType = (floatType == TYP_DOUBLE) ? TYP_LONG : TYP_INT;
GenTree* intArg = comp->gtNewBitCastNode(intType, arg);
var_types intType = (floatType == TYP_FLOAT) ? TYP_INT : TYP_LONG;
GenTree* intArg = comp->gtNewBitCastNode(intType, arg);
intArg->SetRegNum(regNum);

#ifdef TARGET_ARM
if (floatType == TYP_DOUBLE)
{
Expand Down Expand Up @@ -3819,6 +3821,11 @@ void Lowering::LowerCallStruct(GenTreeCall* call)
assert(user->TypeIs(origType) || (returnType == user->TypeGet()));
break;

case GT_CALL:
// Argument lowering will deal with register file mismatches if needed.
assert(varTypeIsSIMD(origType));
break;

case GT_STOREIND:
#ifdef FEATURE_SIMD
if (varTypeIsSIMD(user))
Expand Down