Skip to content

Commit 4092edb

Browse files
Revert "Do not generate TYP_STRUCT LCL_FLD nodes (dotnet#66251)"
This reverts commit 2453f16.
1 parent cc3aa27 commit 4092edb

3 files changed

Lines changed: 24 additions & 70 deletions

File tree

src/coreclr/jit/gentree.cpp

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7042,9 +7042,16 @@ void Compiler::gtBlockOpInit(GenTree* result, GenTree* dst, GenTree* srcOrFillVa
70427042
GenTree* Compiler::gtNewBlkOpNode(GenTree* dst, GenTree* srcOrFillVal, bool isVolatile, bool isCopyBlock)
70437043
{
70447044
assert(dst->OperIsBlk() || dst->OperIsLocal());
7045-
7046-
if (!isCopyBlock) // InitBlk
7045+
if (isCopyBlock)
70477046
{
7047+
if (srcOrFillVal->OperIsIndir() && (srcOrFillVal->gtGetOp1()->gtOper == GT_ADDR))
7048+
{
7049+
srcOrFillVal = srcOrFillVal->gtGetOp1()->gtGetOp1();
7050+
}
7051+
}
7052+
else
7053+
{
7054+
// InitBlk
70487055
assert(varTypeIsIntegral(srcOrFillVal));
70497056
if (varTypeIsStruct(dst))
70507057
{
@@ -15750,15 +15757,8 @@ bool GenTree::IsLocalAddrExpr(Compiler* comp,
1575015757
{
1575115758
assert(!comp->compRationalIRForm);
1575215759
GenTree* addrArg = AsOp()->gtOp1;
15753-
1575415760
if (addrArg->IsLocal()) // Note that this covers "GT_LCL_FLD."
1575515761
{
15756-
FieldSeqNode* zeroOffsetFieldSeq = nullptr;
15757-
if (comp->GetZeroOffsetFieldMap()->Lookup(this, &zeroOffsetFieldSeq))
15758-
{
15759-
*pFldSeq = comp->GetFieldSeqStore()->Append(zeroOffsetFieldSeq, *pFldSeq);
15760-
}
15761-
1576215762
*pLclVarTree = addrArg->AsLclVarCommon();
1576315763
if (addrArg->OperGet() == GT_LCL_FLD)
1576415764
{
@@ -22340,17 +22340,6 @@ uint16_t GenTreeLclVarCommon::GetLclOffs() const
2234022340
}
2234122341
}
2234222342

22343-
//------------------------------------------------------------------------
22344-
// GetFieldSeq: Get the field sequence for this local node.
22345-
//
22346-
// Return Value:
22347-
// The sequence of the node for local fields, empty ("nullptr") otherwise.
22348-
//
22349-
FieldSeqNode* GenTreeLclVarCommon::GetFieldSeq() const
22350-
{
22351-
return OperIsLocalField() ? AsLclFld()->GetFieldSeq() : nullptr;
22352-
}
22353-
2235422343
#if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS)
2235522344
//------------------------------------------------------------------------
2235622345
// GetResultOpNumForFMA: check if the result is written into one of the operands.

src/coreclr/jit/gentree.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3378,8 +3378,6 @@ struct GenTreeLclVarCommon : public GenTreeUnOp
33783378
return (GetSsaNum() != SsaConfig::RESERVED_SSA_NUM);
33793379
}
33803380

3381-
FieldSeqNode* GetFieldSeq() const;
3382-
33833381
#if DEBUGGABLE_GENTREE
33843382
GenTreeLclVarCommon() : GenTreeUnOp()
33853383
{

src/coreclr/jit/morph.cpp

Lines changed: 15 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12520,8 +12520,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
1252012520
ival1 = 0;
1252112521

1252212522
// Don't remove a volatile GT_IND, even if the address points to a local variable.
12523-
// For TYP_STRUCT INDs, we do not know their size, and so will not morph as well.
12524-
if (!tree->AsIndir()->IsVolatile() && !tree->TypeIs(TYP_STRUCT))
12523+
if ((tree->gtFlags & GTF_IND_VOLATILE) == 0)
1252512524
{
1252612525
/* Try to Fold *(&X) into X */
1252712526
if (op1->gtOper == GT_ADDR)
@@ -12534,9 +12533,13 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
1253412533

1253512534
temp = op1->AsOp()->gtOp1; // X
1253612535

12537-
if (typ == temp->TypeGet())
12536+
// In the test below, if they're both TYP_STRUCT, this of course does *not* mean that
12537+
// they are the *same* struct type. In fact, they almost certainly aren't. If the
12538+
// address has an associated field sequence, that identifies this case; go through
12539+
// the "lcl_fld" path rather than this one.
12540+
FieldSeqNode* addrFieldSeq = nullptr; // This is an unused out parameter below.
12541+
if (typ == temp->TypeGet() && !GetZeroOffsetFieldMap()->Lookup(op1, &addrFieldSeq))
1253812542
{
12539-
assert(typ != TYP_STRUCT);
1254012543
foldAndReturnTemp = true;
1254112544
}
1254212545
else if (temp->OperIsLocal())
@@ -12712,17 +12715,22 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
1271212715
// out-of-bounds w.r.t. the local).
1271312716
if ((temp != nullptr) && !foldAndReturnTemp)
1271412717
{
12715-
assert(temp->OperIsLocalRead());
12718+
assert(temp->OperIsLocal());
1271612719

12717-
unsigned lclNum = temp->AsLclVarCommon()->GetLclNum();
12720+
const unsigned lclNum = temp->AsLclVarCommon()->GetLclNum();
12721+
LclVarDsc* const varDsc = lvaGetDesc(lclNum);
12722+
12723+
const var_types tempTyp = temp->TypeGet();
12724+
const bool useExactSize = varTypeIsStruct(tempTyp) || (tempTyp == TYP_BLK) || (tempTyp == TYP_LCLBLK);
12725+
const unsigned varSize = useExactSize ? varDsc->lvExactSize : genTypeSize(temp);
1271812726

1271912727
// Make sure we do not enregister this lclVar.
1272012728
lvaSetVarDoNotEnregister(lclNum DEBUGARG(DoNotEnregisterReason::LocalField));
1272112729

1272212730
// If the size of the load is greater than the size of the lclVar, we cannot fold this access into
1272312731
// a lclFld: the access represented by an lclFld node must begin at or after the start of the
1272412732
// lclVar and must not extend beyond the end of the lclVar.
12725-
if ((ival1 >= 0) && ((ival1 + genTypeSize(typ)) <= lvaLclExactSize(lclNum)))
12733+
if ((ival1 >= 0) && ((ival1 + genTypeSize(typ)) <= varSize))
1272612734
{
1272712735
GenTreeLclFld* lclFld;
1272812736

@@ -13816,47 +13824,6 @@ GenTree* Compiler::fgOptimizeAddition(GenTreeOp* add)
1381613824
return op1;
1381713825
}
1381813826

13819-
// Reduce local addresses: ADD(ADDR(LCL_VAR), OFFSET) => ADDR(LCL_FLD OFFSET).
13820-
// TODO-ADDR: do ADD(LCL_FLD/VAR_ADDR, OFFSET) => LCL_FLD_ADDR instead.
13821-
//
13822-
if (opts.OptimizationEnabled() && fgGlobalMorph && op1->OperIs(GT_ADDR) && op2->IsCnsIntOrI() &&
13823-
op1->AsUnOp()->gtGetOp1()->OperIs(GT_LCL_VAR, GT_LCL_FLD))
13824-
{
13825-
GenTreeUnOp* addrNode = op1->AsUnOp();
13826-
GenTreeLclVarCommon* lclNode = addrNode->gtGetOp1()->AsLclVarCommon();
13827-
GenTreeIntCon* offsetNode = op2->AsIntCon();
13828-
if (FitsIn<uint16_t>(offsetNode->IconValue()))
13829-
{
13830-
unsigned offset = lclNode->GetLclOffs() + static_cast<uint16_t>(offsetNode->IconValue());
13831-
13832-
// Note: the emitter does not expect out-of-bounds access for LCL_FLD_ADDR.
13833-
if (FitsIn<uint16_t>(offset) && (offset < lvaLclExactSize(lclNode->GetLclNum())))
13834-
{
13835-
// Compose the field sequence: [LCL, ADDR, OFFSET].
13836-
FieldSeqNode* fieldSeq = lclNode->GetFieldSeq();
13837-
FieldSeqNode* zeroOffsetFieldSeq = nullptr;
13838-
if (GetZeroOffsetFieldMap()->Lookup(addrNode, &zeroOffsetFieldSeq))
13839-
{
13840-
fieldSeq = GetFieldSeqStore()->Append(fieldSeq, zeroOffsetFieldSeq);
13841-
GetZeroOffsetFieldMap()->Remove(addrNode);
13842-
}
13843-
fieldSeq = GetFieldSeqStore()->Append(fieldSeq, offsetNode->gtFieldSeq);
13844-
13845-
// Types of location nodes under ADDRs do not matter. We arbitrarily choose TYP_UBYTE.
13846-
lclNode->ChangeType(TYP_UBYTE);
13847-
lclNode->SetOper(GT_LCL_FLD);
13848-
lclNode->AsLclFld()->SetLclOffs(offset);
13849-
lclNode->AsLclFld()->SetFieldSeq(fieldSeq);
13850-
lvaSetVarDoNotEnregister(lclNode->GetLclNum() DEBUGARG(DoNotEnregisterReason::LocalField));
13851-
13852-
DEBUG_DESTROY_NODE(offsetNode);
13853-
DEBUG_DESTROY_NODE(add);
13854-
13855-
return addrNode;
13856-
}
13857-
}
13858-
}
13859-
1386013827
// Note that these transformations are legal for floating-point ADDs as well.
1386113828
if (opts.OptimizationEnabled())
1386213829
{

0 commit comments

Comments
 (0)