Skip to content

Commit

Permalink
[RISC-V][LoongArch64] New passing info for floating-point structs (#1…
Browse files Browse the repository at this point in the history
…03945)

* Replace StructFloatFieldInfoFlags with FpStructInRegistersInfo which carries also exact field sizes and offsets

* Replace StructFloatFieldInfoFlags with FpStruct::Flags in profiler

* Remove FpStructInRegistersInfo::FromOldFlags()

* Fix duplicating types in HandleInlineArray

* Remove signedness from FpStruct::IntKind because most probably we won't need it

* Remove old StructFloatFieldInfoFlags calculating routine

* Typo in TARGET_LOONGARCH64

* Remove m_returnedFpFieldOffsets from ArgIterator

* Add missing ENREGISTERED_PARAMTYPE_MAXSIZE condition to C# version of FpStruct info calculation

* Rename RISCV64PassStructInRegister to match settled casing for RiscV in class names

* Update hardcoded flags for float and double in ArgIteratorTemplate::ComputeReturnFlags()

This fixes JIT/HardwareIntrinsics/General/Vector* tests.

* Fix build on other platforms

* Update LoongArch to use FpStructInRegistersInfo

* Remove unused old flag masks

* LoongArch64 typo

Co-authored-by: Qiao Pengcheng <[email protected]>

* Missing FpStruct namespace

Co-authored-by: Qiao Pengcheng <[email protected]>

* Missing FpStruct namespace

Co-authored-by: Qiao Pengcheng <[email protected]>

* Missing FpStruct namespace

Co-authored-by: Qiao Pengcheng <[email protected]>

* Use FpStruct namespace everywhere in JIT

* JIT review

* Update StructFloatFieldInfoFlags description

* Revert to hitherto instruction set order as it's not the point of this PR

* Unify get{LoongArch,RiscV}64PassFpStructInRegistersInfo JIT interfaces

* Use JIT_TO_EE_TRANSITION instead of _LEAF because MethodTable::GetFpStructInRegistersInfo may throw

* Remove FpStruct::IntKind, we should have similar info in ClassLayout in JIT

* Change JIT interface to return a struct similar to CORINFO_SWIFT_LOWERING to facilitate code unification in the future

* Change JIT to use new Swift-like getFpStructLowering

* Cache CORINFO_FPSTRUCT_LOWERING

* Update LoongArch classifier to use CORINFO_FPSTRUCT_LOWERING

* Update StructFloatInfoFlags doc comment on C#

* Move StructFloatFieldInfoFlags and FpStructInRegistersInfo out of the JIT interface

* Merge LoongArch and RISC-V AOT calculation of FpStructInRegistersInfo because they were identical. Move it to Common\Internal/Runtime because it's no longer exposed in JIT interface.

* Don't zero-initialize CORINFO_FPSTRUCT_LOWERING

* Add note for CORINFO_FPSTRUCT_LOWERING::loweredElements type

---------

Co-authored-by: Qiao Pengcheng <[email protected]>
  • Loading branch information
tomeksowi and shushanhf authored Jul 26, 2024
1 parent 8ed5625 commit 7d64842
Show file tree
Hide file tree
Showing 45 changed files with 1,135 additions and 965 deletions.
61 changes: 20 additions & 41 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,45 +307,6 @@ struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR
}
};

// StructFloadFieldInfoFlags: used on LoongArch64 architecture by `getLoongArch64PassStructInRegisterFlags` and
// `getRISCV64PassStructInRegisterFlags` API to convey struct argument passing information.
//
// `STRUCT_NO_FLOAT_FIELD` means structs are not passed using the float register(s).
//
// Otherwise, and only for structs with no more than two fields and a total struct size no larger
// than two pointers:
//
// The lowest four bits denote the floating-point info:
// bit 0: `1` means there is only one float or double field within the struct.
// bit 1: `1` means only the first field is floating-point type.
// bit 2: `1` means only the second field is floating-point type.
// bit 3: `1` means the two fields are both floating-point type.
// The bits[5:4] denoting whether the field size is 8-bytes:
// bit 4: `1` means the first field's size is 8.
// bit 5: `1` means the second field's size is 8.
//
// Note that bit 0 and 3 cannot both be set.
enum StructFloatFieldInfoFlags
{
STRUCT_NO_FLOAT_FIELD = 0x0,
STRUCT_FLOAT_FIELD_ONLY_ONE = 0x1,
STRUCT_FLOAT_FIELD_ONLY_TWO = 0x8,
STRUCT_FLOAT_FIELD_FIRST = 0x2,
STRUCT_FLOAT_FIELD_SECOND = 0x4,
STRUCT_FIRST_FIELD_SIZE_IS8 = 0x10,
STRUCT_SECOND_FIELD_SIZE_IS8 = 0x20,

STRUCT_FIRST_FIELD_DOUBLE = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FIRST_FIELD_SIZE_IS8),
STRUCT_SECOND_FIELD_DOUBLE = (STRUCT_FLOAT_FIELD_SECOND | STRUCT_SECOND_FIELD_SIZE_IS8),
STRUCT_FIELD_TWO_DOUBLES = (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8 | STRUCT_FLOAT_FIELD_ONLY_TWO),

STRUCT_MERGE_FIRST_SECOND = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO),
STRUCT_MERGE_FIRST_SECOND_8 = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_SECOND_FIELD_SIZE_IS8),

STRUCT_HAS_FLOAT_FIELDS_MASK = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_SECOND | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_FLOAT_FIELD_ONLY_ONE),
STRUCT_HAS_8BYTES_FIELDS_MASK = (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8),
};

#include "corinfoinstructionset.h"

// CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn())
Expand Down Expand Up @@ -1940,6 +1901,23 @@ struct CORINFO_SWIFT_LOWERING
size_t numLoweredElements;
};

#define MAX_FPSTRUCT_LOWERED_ELEMENTS 2

// Lowering information on fields of a struct passed by hardware floating-point calling convention on RISC-V and LoongArch
struct CORINFO_FPSTRUCT_LOWERING
{
// Whether the struct should be passed by integer calling convention (cannot be passed by FP calling convention).
bool byIntegerCallConv;
// Types of lowered struct fields.
// Note: the integer field is denoted with a signed type reflecting size only so e.g. ushort is reported
// as CORINFO_TYPE_SHORT and object or string is reported as CORINFO_TYPE_LONG.
CorInfoType loweredElements[MAX_FPSTRUCT_LOWERED_ELEMENTS];
// Offsets of lowered struct fields.
uint32_t offsets[MAX_FPSTRUCT_LOWERED_ELEMENTS];
// Number of lowered struct fields.
size_t numLoweredElements;
};

#define SIZEOF__CORINFO_Object TARGET_POINTER_SIZE /* methTable */

#define CORINFO_Array_MaxLength 0x7FFFFFC7
Expand Down Expand Up @@ -3065,8 +3043,9 @@ class ICorStaticInfo
// Classifies a swift structure into primitives or an implicit byref for ABI purposes.
virtual void getSwiftLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_SWIFT_LOWERING* pLowering) = 0;

virtual uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) = 0;
virtual uint32_t getRISCV64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) = 0;
// Returns lowering info for fields of a RISC-V/LoongArch struct passed in registers according to
// hardware floating-point calling convention.
virtual void getFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering) = 0;
};

/*****************************************************************************
Expand Down
8 changes: 3 additions & 5 deletions src/coreclr/inc/icorjitinfoimpl_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,11 +520,9 @@ void getSwiftLowering(
CORINFO_CLASS_HANDLE structHnd,
CORINFO_SWIFT_LOWERING* pLowering) override;

uint32_t getLoongArch64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd) override;

uint32_t getRISCV64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd) override;
void getFpStructLowering(
CORINFO_CLASS_HANDLE structHnd,
CORINFO_FPSTRUCT_LOWERING* pLowering) override;

uint32_t getThreadTLSIndex(
void** ppIndirection) override;
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
#define GUID_DEFINED
#endif // !GUID_DEFINED

constexpr GUID JITEEVersionIdentifier = { /* 488a17ce-26c9-4ad0-a7b7-79bf320ea4d1 */
0x488a17ce,
0x26c9,
0x4ad0,
{0xa7, 0xb7, 0x79, 0xbf, 0x32, 0x0e, 0xa4, 0xd1}
constexpr GUID JITEEVersionIdentifier = { /* e770e8ad-50d5-4511-a435-a3ed3a847a47 */
0xe770e8ad,
0x50d5,
0x4511,
{0xa4, 0x35, 0xa3, 0xed, 0x3a, 0x84, 0x7a, 0x47}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/jit/ICorJitInfo_names_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ DEF_CLR_API(getMethodNameFromMetadata)
DEF_CLR_API(getMethodHash)
DEF_CLR_API(getSystemVAmd64PassStructInRegisterDescriptor)
DEF_CLR_API(getSwiftLowering)
DEF_CLR_API(getLoongArch64PassStructInRegisterFlags)
DEF_CLR_API(getRISCV64PassStructInRegisterFlags)
DEF_CLR_API(getFpStructLowering)
DEF_CLR_API(getThreadTLSIndex)
DEF_CLR_API(getAddrOfCaptureThreadGlobal)
DEF_CLR_API(getHelperFtn)
Expand Down
21 changes: 6 additions & 15 deletions src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1238,22 +1238,13 @@ void WrapICorJitInfo::getSwiftLowering(
API_LEAVE(getSwiftLowering);
}

uint32_t WrapICorJitInfo::getLoongArch64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd)
{
API_ENTER(getLoongArch64PassStructInRegisterFlags);
uint32_t temp = wrapHnd->getLoongArch64PassStructInRegisterFlags(structHnd);
API_LEAVE(getLoongArch64PassStructInRegisterFlags);
return temp;
}

uint32_t WrapICorJitInfo::getRISCV64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd)
void WrapICorJitInfo::getFpStructLowering(
CORINFO_CLASS_HANDLE structHnd,
CORINFO_FPSTRUCT_LOWERING* pLowering)
{
API_ENTER(getRISCV64PassStructInRegisterFlags);
uint32_t temp = wrapHnd->getRISCV64PassStructInRegisterFlags(structHnd);
API_LEAVE(getRISCV64PassStructInRegisterFlags);
return temp;
API_ENTER(getFpStructLowering);
wrapHnd->getFpStructLowering(structHnd, pLowering);
API_LEAVE(getFpStructLowering);
}

uint32_t WrapICorJitInfo::getThreadTLSIndex(
Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/jit/buildstring.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#define STRINGIFY(L) #L
#define MAKESTRING(M, L) M(L)
#define STRINGIZE(X) MAKESTRING(STRINGIFY, X)
#include "utils.h"

#if defined(__clang__)
#define BUILD_COMPILER \
"Clang " STRINGIZE(__clang_major__) "." STRINGIZE(__clang_minor__) "." STRINGIZE(__clang_patchlevel__)
"Clang " STRINGIFY(__clang_major__) "." STRINGIFY(__clang_minor__) "." STRINGIFY(__clang_patchlevel__)
#elif defined(_MSC_VER)
#define BUILD_COMPILER "MSVC " STRINGIZE(_MSC_FULL_VER)
#define BUILD_COMPILER "MSVC " STRINGIFY(_MSC_FULL_VER)
#elif defined(__GNUC__)
#define BUILD_COMPILER "GCC " STRINGIZE(__GNUC__) "." STRINGIZE(__GNUC_MINOR__) "." STRINGIZE(__GNUC_PATCHLEVEL__)
#define BUILD_COMPILER "GCC " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__) "." STRINGIFY(__GNUC_PATCHLEVEL__)
#else
#define BUILD_COMPILER "Unknown"
#endif
Expand All @@ -26,6 +24,8 @@
#define TARGET_ARCH_STRING "arm64"
#elif defined(TARGET_LOONGARCH64)
#define TARGET_ARCH_STRING "loongarch64"
#elif defined(TARGET_RISCV64)
#define TARGET_ARCH_STRING "riscv64"
#else
#define TARGET_ARCH_STRING "Unknown"
#endif
Expand Down
93 changes: 65 additions & 28 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,37 +927,24 @@ var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
howToReturnStruct = SPK_ByReference;
useType = TYP_UNKNOWN;
}
#elif defined(TARGET_LOONGARCH64)
#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
if (structSize <= (TARGET_POINTER_SIZE * 2))
{
uint32_t floatFieldFlags = info.compCompHnd->getLoongArch64PassStructInRegisterFlags(clsHnd);

if ((floatFieldFlags & STRUCT_FLOAT_FIELD_ONLY_ONE) != 0)
{
howToReturnStruct = SPK_PrimitiveType;
useType = (structSize > 4) ? TYP_DOUBLE : TYP_FLOAT;
}
else if (floatFieldFlags & (STRUCT_HAS_FLOAT_FIELDS_MASK ^ STRUCT_FLOAT_FIELD_ONLY_ONE))
{
howToReturnStruct = SPK_ByValue;
useType = TYP_STRUCT;
}
}

#elif defined(TARGET_RISCV64)
if (structSize <= (TARGET_POINTER_SIZE * 2))
{
uint32_t floatFieldFlags = info.compCompHnd->getRISCV64PassStructInRegisterFlags(clsHnd);

if ((floatFieldFlags & STRUCT_FLOAT_FIELD_ONLY_ONE) != 0)
{
howToReturnStruct = SPK_PrimitiveType;
useType = (structSize > 4) ? TYP_DOUBLE : TYP_FLOAT;
}
else if (floatFieldFlags & (STRUCT_HAS_FLOAT_FIELDS_MASK ^ STRUCT_FLOAT_FIELD_ONLY_ONE))
const CORINFO_FPSTRUCT_LOWERING* lowering = GetFpStructLowering(clsHnd);
if (!lowering->byIntegerCallConv)
{
howToReturnStruct = SPK_ByValue;
useType = TYP_STRUCT;
if (lowering->numLoweredElements == 1)
{
useType = JITtype2varType(lowering->loweredElements[0]);
assert(varTypeIsFloating(useType));
howToReturnStruct = SPK_PrimitiveType;
}
else
{
assert(lowering->numLoweredElements == 2);
howToReturnStruct = SPK_ByValue;
useType = TYP_STRUCT;
}
}
}

Expand Down Expand Up @@ -1998,6 +1985,9 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
#ifdef SWIFT_SUPPORT
m_swiftLoweringCache = nullptr;
#endif
#if defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
m_fpStructLoweringCache = nullptr;
#endif

// check that HelperCallProperties are initialized

Expand Down Expand Up @@ -8301,6 +8291,53 @@ void Compiler::GetStructTypeOffset(
GetStructTypeOffset(structDesc, type0, type1, offset0, offset1);
}

#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
//------------------------------------------------------------------------
// GetFpStructLowering: Gets the information on passing of a struct according to hardware floating-point
// calling convention, i.e. the types and offsets of struct fields lowered for passing.
//
// Arguments:
// structHandle - type handle
//
// Return value:
// Lowering info for the struct fields
const CORINFO_FPSTRUCT_LOWERING* Compiler::GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle)
{
if (m_fpStructLoweringCache == nullptr)
m_fpStructLoweringCache = new (this, CMK_CallArgs) FpStructLoweringMap(getAllocator(CMK_CallArgs));

CORINFO_FPSTRUCT_LOWERING* lowering;
if (!m_fpStructLoweringCache->Lookup(structHandle, &lowering))
{
lowering = new (this, CMK_CallArgs) CORINFO_FPSTRUCT_LOWERING;
info.compCompHnd->getFpStructLowering(structHandle, lowering);
m_fpStructLoweringCache->Set(structHandle, lowering);
#ifdef DEBUG
if (verbose)
{
printf("**** getFpStructInRegistersInfo(0x%x (%s, %u bytes)) =>\n", dspPtr(structHandle),
eeGetClassName(structHandle), info.compCompHnd->getClassSize(structHandle));

if (lowering->byIntegerCallConv)
{
printf(" pass by integer calling convention\n");
}
else
{
printf(" may be passed by floating-point calling convention (%zu fields):\n",
lowering->numLoweredElements);
for (size_t i = 0; i < lowering->numLoweredElements; ++i)
{
const char* type = varTypeName(JITtype2varType(lowering->loweredElements[i]));
printf(" * field[%zu]: type %s at offset %u\n", i, type, lowering->offsets[i]);
}
}
}
#endif // DEBUG
}
return lowering;
}

#endif // defined(UNIX_AMD64_ABI)

/*****************************************************************************/
Expand Down
19 changes: 8 additions & 11 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -561,17 +561,9 @@ class LclVarDsc
unsigned char lvIsLastUseCopyOmissionCandidate : 1;
#endif // FEATURE_IMPLICIT_BYREFS

#if defined(TARGET_LOONGARCH64)
unsigned char lvIs4Field1 : 1; // Set if the 1st field is int or float within struct for LA-ABI64.
unsigned char lvIs4Field2 : 1; // Set if the 2nd field is int or float within struct for LA-ABI64.
unsigned char lvIsSplit : 1; // Set if the argument is splited.
#endif // defined(TARGET_LOONGARCH64)

#if defined(TARGET_RISCV64)
unsigned char lvIs4Field1 : 1; // Set if the 1st field is int or float within struct for RISCV64.
unsigned char lvIs4Field2 : 1; // Set if the 2nd field is int or float within struct for RISCV64.
unsigned char lvIsSplit : 1; // Set if the argument is splited.
#endif // defined(TARGET_RISCV64)
#if defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
unsigned char lvIsSplit : 1; // Set if the argument is split across last integer register and stack.
#endif // defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)

unsigned char lvSingleDef : 1; // variable has a single def. Used to identify ref type locals that can get type
// updates
Expand Down Expand Up @@ -11496,6 +11488,11 @@ class Compiler
void GetStructTypeOffset(
CORINFO_CLASS_HANDLE typeHnd, var_types* type0, var_types* type1, uint8_t* offset0, uint8_t* offset1);

#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
typedef JitHashTable<CORINFO_CLASS_HANDLE, JitPtrKeyFuncs<struct CORINFO_CLASS_STRUCT_>, CORINFO_FPSTRUCT_LOWERING*>
FpStructLoweringMap;
FpStructLoweringMap* m_fpStructLoweringCache;
const CORINFO_FPSTRUCT_LOWERING* GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle);
#endif // defined(UNIX_AMD64_ABI)

void fgMorphMultiregStructArgs(GenTreeCall* call);
Expand Down
46 changes: 19 additions & 27 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29544,37 +29544,29 @@ void ReturnTypeDesc::InitializeStructReturnType(Compiler* comp,

#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
assert((structSize >= TARGET_POINTER_SIZE) && (structSize <= (2 * TARGET_POINTER_SIZE)));

#ifdef TARGET_LOONGARCH64
uint32_t floatFieldFlags = comp->info.compCompHnd->getLoongArch64PassStructInRegisterFlags(retClsHnd);
#else
uint32_t floatFieldFlags = comp->info.compCompHnd->getRISCV64PassStructInRegisterFlags(retClsHnd);
#endif
BYTE gcPtrs[2] = {TYPE_GC_NONE, TYPE_GC_NONE};
comp->info.compCompHnd->getClassGClayout(retClsHnd, &gcPtrs[0]);

if (floatFieldFlags & STRUCT_FLOAT_FIELD_ONLY_TWO)
{
comp->compFloatingPointUsed = true;
assert((structSize > 8) == ((floatFieldFlags & STRUCT_HAS_8BYTES_FIELDS_MASK) > 0));
m_regType[0] = (floatFieldFlags & STRUCT_FIRST_FIELD_SIZE_IS8) ? TYP_DOUBLE : TYP_FLOAT;
m_regType[1] = (floatFieldFlags & STRUCT_SECOND_FIELD_SIZE_IS8) ? TYP_DOUBLE : TYP_FLOAT;
}
else if (floatFieldFlags & STRUCT_FLOAT_FIELD_FIRST)
{
comp->compFloatingPointUsed = true;
assert((structSize > 8) == ((floatFieldFlags & STRUCT_HAS_8BYTES_FIELDS_MASK) > 0));
m_regType[0] = (floatFieldFlags & STRUCT_FIRST_FIELD_SIZE_IS8) ? TYP_DOUBLE : TYP_FLOAT;
m_regType[1] =
(floatFieldFlags & STRUCT_SECOND_FIELD_SIZE_IS8) ? comp->getJitGCType(gcPtrs[1]) : TYP_INT;
}
else if (floatFieldFlags & STRUCT_FLOAT_FIELD_SECOND)
const CORINFO_FPSTRUCT_LOWERING* lowering = comp->GetFpStructLowering(retClsHnd);
if (!lowering->byIntegerCallConv)
{
comp->compFloatingPointUsed = true;
assert((structSize > 8) == ((floatFieldFlags & STRUCT_HAS_8BYTES_FIELDS_MASK) > 0));
m_regType[0] =
(floatFieldFlags & STRUCT_FIRST_FIELD_SIZE_IS8) ? comp->getJitGCType(gcPtrs[0]) : TYP_INT;
m_regType[1] = (floatFieldFlags & STRUCT_SECOND_FIELD_SIZE_IS8) ? TYP_DOUBLE : TYP_FLOAT;
assert(lowering->numLoweredElements == MAX_RET_REG_COUNT);
var_types types[MAX_RET_REG_COUNT] = {JITtype2varType(lowering->loweredElements[0]),
JITtype2varType(lowering->loweredElements[1])};
assert(varTypeIsFloating(types[0]) || varTypeIsFloating(types[1]));
assert((structSize > 8) == ((genTypeSize(types[0]) == 8) || (genTypeSize(types[1]) == 8)));
for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)
{
if (varTypeIsFloating(types[i]))
{
m_regType[i] = types[i];
}
else
{
assert(varTypeIsIntegralOrI(types[i]));
m_regType[i] = (genTypeSize(types[i]) == 8) ? comp->getJitGCType(gcPtrs[i]) : TYP_INT;
}
}
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -4544,7 +4544,7 @@ struct CallArgABIInformation
SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR StructDesc;
#endif // UNIX_AMD64_ABI
#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
// For LoongArch64's ABI, the struct which has float field(s) and no more than two fields
// For LoongArch64's and RISC-V 64's ABI, the struct which has float field(s) and no more than two fields
// may be passed by float register(s).
// e.g `struct {int a; float b;}` passed by an integer register and a float register.
var_types StructFloatFieldType[2];
Expand Down
Loading

0 comments on commit 7d64842

Please sign in to comment.