@@ -1049,10 +1049,9 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
10491049 return IndirTransform::None;
10501050 }
10511051
1052- if ((user == nullptr ) || !user->OperIs (GT_ASG, GT_RETURN))
1052+ if ((user == nullptr ) || !user->OperIs (GT_ASG, GT_CALL, GT_RETURN))
10531053 {
1054- // TODO-ADDR: call args require extra work because currently they must
1055- // be wrapped in OBJ nodes so we can't replace those with local nodes.
1054+ // TODO-ADDR: remove unused indirections.
10561055 return IndirTransform::None;
10571056 }
10581057
@@ -1075,7 +1074,6 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
10751074 //
10761075 enum class StructMatch
10771076 {
1078- Exact,
10791077 Compatible,
10801078 Partial
10811079 };
@@ -1084,44 +1082,44 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
10841082 assert (varDsc->GetLayout () != nullptr );
10851083
10861084 StructMatch match = StructMatch::Partial;
1087- if (val.Offset () == 0 )
1085+ if (( val.Offset () == 0 ) && ClassLayout::AreCompatible (indirLayout, varDsc-> GetLayout ()) )
10881086 {
1089- if (indirLayout->GetClassHandle () == varDsc->GetStructHnd ())
1090- {
1091- match = StructMatch::Exact;
1092- }
1093- else if (ClassLayout::AreCompatible (indirLayout, varDsc->GetLayout ()))
1094- {
1095- match = StructMatch::Compatible;
1096- }
1087+ match = StructMatch::Compatible;
10971088 }
10981089
10991090 // Current matrix of matches/users/types:
11001091 //
1101- // |------------|------|-------------|---------|
1102- // | STRUCT | CALL | ASG | RETURN |
1103- // |------------|------|-------------|---------|
1104- // | Exact | None | LCL_VAR | LCL_VAR |
1105- // | Compatible | None | LCL_VAR | LCL_VAR |
1106- // | Partial | None | OBJ/LCL_FLD | LCL_FLD |
1107- // |------------|------|-------------|---------|
1092+ // |------------|---------|-------------|---------|
1093+ // | STRUCT | CALL(*) | ASG | RETURN |
1094+ // |------------|---------|-------------|---------|
1095+ // | Compatible | LCL_VAR | LCL_VAR | LCL_VAR |
1096+ // | Partial | LCL_FLD | OBJ/LCL_FLD | LCL_FLD |
1097+ // |------------|---------|-------------|---------|
1098+ //
1099+ // * - On Windows x64 only.
11081100 //
11091101 // |------------|------|------|--------|----------|
11101102 // | SIMD | CALL | ASG | RETURN | HWI/SIMD |
11111103 // |------------|------|------|--------|----------|
1112- // | Exact | None | None | None | None |
11131104 // | Compatible | None | None | None | None |
11141105 // | Partial | None | None | None | None |
11151106 // |------------|------|------|--------|----------|
11161107 //
11171108 // TODO-ADDR: delete all the "None" entries and always
11181109 // transform local nodes into LCL_VAR or LCL_FLD.
11191110
1120- assert (indir->TypeIs (TYP_STRUCT) && user->OperIs (GT_ASG, GT_RETURN));
1111+ assert (indir->TypeIs (TYP_STRUCT) && user->OperIs (GT_ASG, GT_CALL, GT_RETURN));
11211112
11221113 *pStructLayout = indirLayout;
11231114
1124- if ((match == StructMatch::Exact) || (match == StructMatch::Compatible))
1115+ if (user->IsCall ())
1116+ {
1117+ #ifndef WINDOWS_AMD64_ABI
1118+ return IndirTransform::None;
1119+ #endif // !WINDOWS_AMD64_ABI
1120+ }
1121+
1122+ if (match == StructMatch::Compatible)
11251123 {
11261124 return IndirTransform::LclVar;
11271125 }
0 commit comments