@@ -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 }
0 commit comments