Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
27 changes: 0 additions & 27 deletions src/coreclr/jit/forwardsub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,33 +660,6 @@ bool Compiler::fgForwardSubStatement(Statement* stmt)
return false;
}

// We may sometimes lose or change a type handle. Avoid substituting if so.
//
// However, we allow free substitution of hardware SIMD types.
//
CORINFO_CLASS_HANDLE fwdHnd = gtGetStructHandleIfPresent(fwdSubNode);
CORINFO_CLASS_HANDLE useHnd = gtGetStructHandleIfPresent(fsv.GetNode());
if (fwdHnd != useHnd)
{
if ((fwdHnd == NO_CLASS_HANDLE) || (useHnd == NO_CLASS_HANDLE))
{
JITDUMP(" would add/remove struct handle (substitution)\n");
return false;
}

#ifdef FEATURE_SIMD
const bool bothHWSIMD = isHWSIMDClass(fwdHnd) && isHWSIMDClass(useHnd);
#else
const bool bothHWSIMD = false;
#endif

if (!bothHWSIMD)
{
JITDUMP(" would change struct handle (substitution)\n");
return false;
}
}

// There are implicit assumptions downstream on where/how multi-reg ops
// can appear.
//
Expand Down
11 changes: 5 additions & 6 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15423,12 +15423,11 @@ GenTree* Compiler::gtNewTempAssign(
CORINFO_CLASS_HANDLE valStructHnd = gtGetStructHandleIfPresent(val);
if (varTypeIsStruct(varDsc) && (valStructHnd == NO_CLASS_HANDLE) && !varTypeIsSIMD(valTyp))
{
// There are 2 special cases:
// 1. we have lost classHandle from a FIELD node because the parent struct has overlapping fields,
// the field was transformed as IND opr GT_LCL_FLD;
// 2. we are propagation `ASG(struct V01, 0)` to `RETURN(struct V01)`, `CNT_INT` doesn't `structHnd`;
// in these cases, we can use the type of the merge return for the assignment.
assert(val->gtEffectiveVal(true)->OperIs(GT_IND, GT_LCL_FLD, GT_CNS_INT));
// There are some cases where we do not have a struct handle on the return value:
// 1. Handle-less IND/BLK/LCL_FLD<struct> nodes.
// 2. The zero constant created by local assertion propagation.
// In these cases, we can use the type of the merge return for the assignment.
assert(val->gtEffectiveVal(true)->OperIs(GT_IND, GT_BLK, GT_LCL_FLD, GT_CNS_INT));
assert(tmp == genReturnLocal);
valStructHnd = lvaGetStruct(genReturnLocal);
assert(valStructHnd != NO_CLASS_HANDLE);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1189,7 +1189,7 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr,
else
#endif // FEATURE_HW_INTRINSICS
{
assert(src->OperIs(GT_LCL_VAR, GT_LCL_FLD, GT_FIELD, GT_IND, GT_OBJ, GT_CALL, GT_MKREFANY, GT_RET_EXPR,
assert(src->OperIs(GT_LCL_VAR, GT_LCL_FLD, GT_FIELD, GT_IND, GT_OBJ, GT_BLK, GT_CALL, GT_MKREFANY, GT_RET_EXPR,
GT_COMMA, GT_CNS_VEC) ||
((src->TypeGet() != TYP_STRUCT) && (src->OperIsSIMD() || src->OperIs(GT_BITCAST))));
}
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3645,6 +3645,7 @@ void Lowering::LowerRetStruct(GenTreeUnOp* ret)
}
break;

case GT_BLK:
case GT_OBJ:
retVal->ChangeOper(GT_IND);
FALLTHROUGH;
Expand Down