Skip to content

Commit 88d75e9

Browse files
Enable TYP_STRUCT LCL_VAR/LCL_FLD call args on ARM (#71598)
* ARM: local morph * ARM: morph * Jit dumps: print '(AX)' and others for LCL_FLD nodes * Delete invalid assert * Work around emitter limitations
1 parent 4358bab commit 88d75e9

File tree

4 files changed

+9
-56
lines changed

4 files changed

+9
-56
lines changed

src/coreclr/jit/codegenarmarch.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,9 +1235,6 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
12351235
assert(baseReg != addrReg);
12361236
}
12371237

1238-
// We don't split HFAs.
1239-
assert(!compiler->IsHfa(layout->GetClassHandle()));
1240-
12411238
// Put on stack first
12421239
unsigned structOffset = treeNode->gtNumRegs * TARGET_POINTER_SIZE;
12431240
unsigned remainingSize = layout->GetSize() - structOffset;

src/coreclr/jit/gentree.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10558,7 +10558,7 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, _In_ _In_opt_
1055810558
}
1055910559
}
1056010560

10561-
if (tree->gtOper == GT_LCL_VAR || tree->gtOper == GT_STORE_LCL_VAR)
10561+
if (tree->OperIsLocal())
1056210562
{
1056310563
LclVarDsc* varDsc = lvaGetDesc(tree->AsLclVarCommon());
1056410564
if (varDsc->IsAddressExposed())

src/coreclr/jit/lclmorph.cpp

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -715,11 +715,11 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
715715
unsigned indirSize = GetIndirSize(node, user);
716716
bool isWide;
717717

718-
if ((indirSize == 0) || (val.Offset() > UINT16_MAX))
718+
if ((indirSize == 0) || ((val.Offset() + indirSize) > UINT16_MAX))
719719
{
720720
// If we can't figure out the indirection size then treat it as a wide indirection.
721-
// Likewise if we won't be able to tranform this indirection into a local node due
722-
// the large offset.
721+
// Additionally, treat indirections with large offsets as wide: local field nodes
722+
// and the emitter do not support them.
723723
isWide = true;
724724
}
725725
else
@@ -1035,56 +1035,12 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
10351035
indirLayout = indir->AsBlk()->GetLayout();
10361036
}
10371037

1038-
// How does the "indir" match the underlying location?
1039-
//
1040-
enum class StructMatch
1041-
{
1042-
Compatible,
1043-
Partial
1044-
};
1045-
1046-
// We're only processing TYP_STRUCT variables now.
1047-
assert(varDsc->GetLayout() != nullptr);
1048-
1049-
StructMatch match = StructMatch::Partial;
1050-
if ((val.Offset() == 0) && ClassLayout::AreCompatible(indirLayout, varDsc->GetLayout()))
1051-
{
1052-
match = StructMatch::Compatible;
1053-
}
1054-
1055-
// Current matrix of matches/users/types:
1056-
//
1057-
// |------------|---------|---------|---------|
1058-
// | STRUCT | CALL(*) | ASG | RETURN |
1059-
// |------------|---------|---------|---------|
1060-
// | Compatible | LCL_VAR | LCL_VAR | LCL_VAR |
1061-
// | Partial | LCL_FLD | LCL_FLD | LCL_FLD |
1062-
// |------------|---------|---------|---------|
1063-
//
1064-
// * - On XArch/Arm64/LA only.
1065-
//
1066-
// |------------|------|------|--------|----------|
1067-
// | SIMD | CALL | ASG | RETURN | HWI/SIMD |
1068-
// |------------|------|------|--------|----------|
1069-
// | Compatible | None | None | None | None |
1070-
// | Partial | None | None | None | None |
1071-
// |------------|------|------|--------|----------|
1072-
//
1073-
// TODO-ADDR: delete all the "None" entries and always
1074-
// transform local nodes into LCL_VAR or LCL_FLD.
1075-
1076-
assert(indir->TypeIs(TYP_STRUCT) && user->OperIs(GT_ASG, GT_CALL, GT_RETURN));
1077-
10781038
*pStructLayout = indirLayout;
10791039

1080-
if (user->IsCall())
1081-
{
1082-
#ifdef TARGET_ARM
1083-
return IndirTransform::None;
1084-
#endif // TARGET_ARM
1085-
}
1040+
// We're only processing TYP_STRUCT uses and variables now.
1041+
assert(indir->TypeIs(TYP_STRUCT) && (varDsc->GetLayout() != nullptr));
10861042

1087-
if (match == StructMatch::Compatible)
1043+
if ((val.Offset() == 0) && ClassLayout::AreCompatible(indirLayout, varDsc->GetLayout()))
10881044
{
10891045
return IndirTransform::LclVar;
10901046
}

src/coreclr/jit/morph.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3127,8 +3127,8 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call)
31273127
// - For ARM and ARM64 it must also be a non-HFA struct, or have a single field.
31283128
// - This is irrelevant for X86, since structs are always passed by value on the stack.
31293129

3130-
GenTree* lclVar = fgIsIndirOfAddrOfLocal(argObj);
3131-
bool argIsLocal = (lclVar != nullptr) || argObj->OperIsLocalRead();
3130+
GenTree* lclVar = argObj->OperIs(GT_LCL_VAR) ? argObj : fgIsIndirOfAddrOfLocal(argObj);
3131+
bool argIsLocal = (lclVar != nullptr) || argObj->OperIs(GT_LCL_FLD);
31323132
bool canTransform = false;
31333133

31343134
if (structBaseType != TYP_STRUCT)

0 commit comments

Comments
 (0)