@@ -715,11 +715,11 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
715
715
unsigned indirSize = GetIndirSize (node, user);
716
716
bool isWide;
717
717
718
- if ((indirSize == 0 ) || (val.Offset () > UINT16_MAX))
718
+ if ((indirSize == 0 ) || (( val.Offset () + indirSize ) > UINT16_MAX))
719
719
{
720
720
// 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 .
723
723
isWide = true ;
724
724
}
725
725
else
@@ -1035,56 +1035,12 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
1035
1035
indirLayout = indir->AsBlk ()->GetLayout ();
1036
1036
}
1037
1037
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
-
1078
1038
*pStructLayout = indirLayout;
1079
1039
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 ));
1086
1042
1087
- if (match == StructMatch::Compatible )
1043
+ if ((val. Offset () == 0 ) && ClassLayout::AreCompatible (indirLayout, varDsc-> GetLayout ()) )
1088
1044
{
1089
1045
return IndirTransform::LclVar;
1090
1046
}
0 commit comments