@@ -807,8 +807,10 @@ GenTree* Compiler::impStoreStruct(GenTree* store,
807807 WellKnownArg wellKnownArgType =
808808 srcCall->ShouldHaveRetBufArg() ? WellKnownArg::RetBuffer : WellKnownArg::None;
809809
810- GenTree* destAddr = impGetStructAddr(store, CHECK_SPILL_ALL, /* willDeref */ true);
811- NewCallArg newArg = NewCallArg::Primitive(destAddr).WellKnown(wellKnownArgType);
810+ // TODO-Bug?: verify if flags matter here
811+ GenTreeFlags indirFlags = GTF_EMPTY;
812+ GenTree* destAddr = impGetNodeAddr(store, CHECK_SPILL_ALL, &indirFlags);
813+ NewCallArg newArg = NewCallArg::Primitive(destAddr).WellKnown(wellKnownArgType);
812814
813815#if !defined(TARGET_ARM)
814816 // Unmanaged instance methods on Windows or Unix X86 need the retbuf arg after the first (this) parameter
@@ -909,7 +911,9 @@ GenTree* Compiler::impStoreStruct(GenTree* store,
909911 if (call->ShouldHaveRetBufArg())
910912 {
911913 // insert the return value buffer into the argument list as first byref parameter after 'this'
912- GenTree* destAddr = impGetStructAddr(store, CHECK_SPILL_ALL, /* willDeref */ true);
914+ // TODO-Bug?: verify if flags matter here
915+ GenTreeFlags indirFlags = GTF_EMPTY;
916+ GenTree* destAddr = impGetNodeAddr(store, CHECK_SPILL_ALL, &indirFlags);
913917 call->gtArgs.InsertAfterThisOrFirst(this,
914918 NewCallArg::Primitive(destAddr).WellKnown(WellKnownArg::RetBuffer));
915919
@@ -926,16 +930,17 @@ GenTree* Compiler::impStoreStruct(GenTree* store,
926930 {
927931 // Since we are assigning the result of a GT_MKREFANY, "destAddr" must point to a refany.
928932 // TODO-CQ: we can do this without address-exposing the local on the LHS.
929- GenTree* destAddr = impGetStructAddr(store, CHECK_SPILL_ALL, /* willDeref */ true);
930- GenTree* destAddrClone;
933+ GenTreeFlags indirFlags = GTF_EMPTY;
934+ GenTree* destAddr = impGetNodeAddr(store, CHECK_SPILL_ALL, &indirFlags);
935+ GenTree* destAddrClone;
931936 destAddr = impCloneExpr(destAddr, &destAddrClone, curLevel, pAfterStmt DEBUGARG("MKREFANY assignment"));
932937
933938 assert(OFFSETOF__CORINFO_TypedReference__dataPtr == 0);
934939 assert(destAddr->gtType == TYP_I_IMPL || destAddr->gtType == TYP_BYREF);
935940
936941 // Append the store of the pointer value.
937942 // TODO-Bug: the pointer value can be a byref. Use its actual type here instead of TYP_I_IMPL.
938- GenTree* ptrFieldStore = gtNewStoreIndNode(TYP_I_IMPL, destAddr, src->AsOp()->gtOp1);
943+ GenTree* ptrFieldStore = gtNewStoreIndNode(TYP_I_IMPL, destAddr, src->AsOp()->gtOp1, indirFlags );
939944 if (pAfterStmt)
940945 {
941946 Statement* newStmt = gtNewStmt(ptrFieldStore, usedDI);
@@ -1020,51 +1025,59 @@ GenTree* Compiler::impStoreStructPtr(GenTree* destAddr, GenTree* value, unsigned
10201025}
10211026
10221027//------------------------------------------------------------------------
1023- // impGetStructAddr : Get the address of a struct value / location .
1028+ // impGetNodeAddr : Get the address of a value.
10241029//
10251030// Arguments:
1026- // structVal - The value in question
1027- // curLevel - Stack level for spilling
1028- // willDeref - Whether the caller will dereference the address
1031+ // val - The value in question
1032+ // curLevel - Stack level for spilling
1033+ // pDerefFlags - Flags to be used on dereference, nullptr when
1034+ // the address won't be dereferenced. Returned flags
1035+ // are included in the GTF_IND_COPYABLE_FLAGS mask.
10291036//
10301037// Return Value:
1031- // In case "structVal" can represent locations (is an indirection/local),
1038+ // In case "val" represents a location (is an indirection/local),
10321039// will return its address. Otherwise, address of a temporary assigned
1033- // the value of "structVal " will be returned.
1040+ // the value of "val " will be returned.
10341041//
1035- GenTree* Compiler::impGetStructAddr (GenTree* structVal , unsigned curLevel, bool willDeref )
1042+ GenTree* Compiler::impGetNodeAddr (GenTree* val , unsigned curLevel, GenTreeFlags* pDerefFlags )
10361043{
1037- assert(varTypeIsStruct(structVal));
1038- switch (structVal->OperGet())
1044+ if (pDerefFlags != nullptr)
1045+ {
1046+ *pDerefFlags = GTF_EMPTY;
1047+ }
1048+ switch (val->OperGet())
10391049 {
10401050 case GT_BLK:
10411051 case GT_IND:
10421052 case GT_STOREIND:
10431053 case GT_STORE_BLK:
1044- if (willDeref )
1054+ if (pDerefFlags != nullptr )
10451055 {
1046- return structVal->AsIndir()->Addr();
1056+ *pDerefFlags = val->gtFlags & GTF_IND_COPYABLE_FLAGS;
1057+ return val->AsIndir()->Addr();
10471058 }
10481059 break;
10491060
10501061 case GT_LCL_VAR:
10511062 case GT_STORE_LCL_VAR:
1052- return gtNewLclVarAddrNode(structVal->AsLclVar()->GetLclNum(), TYP_BYREF);
1063+ val->gtFlags |= GTF_VAR_MOREUSES;
1064+ return gtNewLclVarAddrNode(val->AsLclVar()->GetLclNum(), TYP_BYREF);
10531065
10541066 case GT_LCL_FLD:
10551067 case GT_STORE_LCL_FLD:
1056- return gtNewLclAddrNode(structVal->AsLclFld()->GetLclNum(), structVal->AsLclFld()->GetLclOffs(), TYP_BYREF);
1068+ val->gtFlags |= GTF_VAR_MOREUSES;
1069+ return gtNewLclAddrNode(val->AsLclFld()->GetLclNum(), val->AsLclFld()->GetLclOffs(), TYP_BYREF);
10571070
10581071 case GT_COMMA:
1059- impAppendTree(structVal ->AsOp()->gtGetOp1(), curLevel, impCurStmtDI);
1060- return impGetStructAddr(structVal ->AsOp()->gtGetOp2(), curLevel, willDeref );
1072+ impAppendTree(val ->AsOp()->gtGetOp1(), curLevel, impCurStmtDI);
1073+ return impGetNodeAddr(val ->AsOp()->gtGetOp2(), curLevel, pDerefFlags );
10611074
10621075 default:
10631076 break;
10641077 }
10651078
10661079 unsigned lclNum = lvaGrabTemp(true DEBUGARG("location for address-of(RValue)"));
1067- impStoreTemp(lclNum, structVal , curLevel);
1080+ impStoreTemp(lclNum, val , curLevel);
10681081
10691082 // The 'return value' is now address of the temp itself.
10701083 return gtNewLclVarAddrNode(lclNum, TYP_BYREF);
@@ -3000,7 +3013,9 @@ int Compiler::impBoxPatternMatch(CORINFO_RESOLVED_TOKEN* pResolvedToken,
30003013 GenTree* objToBox = impPopStack().val;
30013014
30023015 // Spill struct to get its address (to access hasValue field)
3003- objToBox = impGetStructAddr(objToBox, CHECK_SPILL_ALL, true);
3016+ // TODO-Bug?: verify if flags matter here
3017+ GenTreeFlags indirFlags = GTF_EMPTY;
3018+ objToBox = impGetNodeAddr(objToBox, CHECK_SPILL_ALL, &indirFlags);
30043019
30053020 static_assert_no_msg(OFFSETOF__CORINFO_NullableOfT__hasValue == 0);
30063021 impPushOnStack(gtNewIndir(TYP_BOOL, objToBox), typeInfo(TYP_INT));
@@ -3348,7 +3363,9 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken)
33483363 return;
33493364 }
33503365
3351- op1 = gtNewHelperCallNode(boxHelper, TYP_REF, op2, impGetStructAddr(exprToBox, CHECK_SPILL_ALL, true));
3366+ // TODO-Bug?: verify if flags matter here
3367+ GenTreeFlags indirFlags = GTF_EMPTY;
3368+ op1 = gtNewHelperCallNode(boxHelper, TYP_REF, op2, impGetNodeAddr(exprToBox, CHECK_SPILL_ALL, &indirFlags));
33523369 }
33533370
33543371 /* Push the result back on the stack, */
@@ -7968,7 +7985,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
79687985 }
79697986 else
79707987 {
7971- op1 = impGetStructAddr (op1, CHECK_SPILL_ALL, false );
7988+ op1 = impGetNodeAddr (op1, CHECK_SPILL_ALL, nullptr );
79727989 }
79737990
79747991 JITDUMP("\n ... optimized to ...\n");
@@ -8908,7 +8925,9 @@ void Compiler::impImportBlockCode(BasicBlock* block)
89088925 BADCODE3("Unexpected opcode (has to be LDFLD)", ": %02X", (int)opcode);
89098926 }
89108927
8911- obj = impGetStructAddr(obj, CHECK_SPILL_ALL, true);
8928+ // TODO-Bug?: verify if flags matter here
8929+ GenTreeFlags indirFlags = GTF_EMPTY;
8930+ obj = impGetNodeAddr(obj, CHECK_SPILL_ALL, &indirFlags);
89128931 }
89138932
89148933 op1 = gtNewFieldAddrNode(resolvedToken.hField, obj, fieldInfo.offset);
@@ -9661,12 +9680,13 @@ void Compiler::impImportBlockCode(BasicBlock* block)
96619680 else
96629681 {
96639682 // Get the address of the refany
9664- op1 = impGetStructAddr(op1, CHECK_SPILL_ALL, /* willDeref */ true);
9683+ GenTreeFlags indirFlags = GTF_EMPTY;
9684+ op1 = impGetNodeAddr(op1, CHECK_SPILL_ALL, &indirFlags);
96659685
96669686 // Fetch the type from the correct slot
96679687 op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1,
96689688 gtNewIconNode(OFFSETOF__CORINFO_TypedReference__type, TYP_I_IMPL));
9669- op1 = gtNewIndir(TYP_BYREF, op1);
9689+ op1 = gtNewIndir(TYP_BYREF, op1, indirFlags );
96709690 }
96719691
96729692 // Convert native TypeHandle to RuntimeTypeHandle.
0 commit comments