@@ -7839,21 +7839,29 @@ static bool GetStoreCoalescingData(Compiler* comp, GenTreeStoreInd* ind, StoreCo
78397839 return false ;
78407840 }
78417841
7842+ auto isNodeInvariant = [](Compiler* comp, GenTree* node, bool allowNull) {
7843+ if (node == nullptr )
7844+ {
7845+ return allowNull;
7846+ }
7847+ // We can allow bigger sideeffect-free trees here, but it's not clear if it's worth it.
7848+ return node->OperIs (GT_LCL_VAR) && !comp->lvaVarAddrExposed (node->AsLclVar ()->GetLclNum ());
7849+ };
7850+
78427851 data->targetType = ind->TypeGet ();
78437852 data->value = ind->Data ();
78447853 if (ind->Addr ()->OperIs (GT_LEA))
78457854 {
78467855 GenTree* base = ind->Addr ()->AsAddrMode ()->Base ();
78477856 GenTree* index = ind->Addr ()->AsAddrMode ()->Index ();
7848- if ((base == nullptr ) || !base-> OperIs (GT_LCL_VAR) || comp-> lvaVarAddrExposed ( base-> AsLclVar ()-> GetLclNum () ))
7857+ if (! isNodeInvariant ( comp, base, false ))
78497858 {
78507859 // Base must be a local. It's possible for it to be nullptr when index is not null,
78517860 // but let's ignore such cases.
78527861 return false ;
78537862 }
78547863
7855- if ((index != nullptr ) &&
7856- (!index->OperIs (GT_LCL_VAR) || comp->lvaVarAddrExposed (index->AsLclVar ()->GetLclNum ())))
7864+ if (!isNodeInvariant (comp, index, true ))
78577865 {
78587866 // Index should be either nullptr or a local.
78597867 return false ;
@@ -7864,7 +7872,7 @@ static bool GetStoreCoalescingData(Compiler* comp, GenTreeStoreInd* ind, StoreCo
78647872 data->scale = ind->Addr ()->AsAddrMode ()->GetScale ();
78657873 data->offset = ind->Addr ()->AsAddrMode ()->Offset ();
78667874 }
7867- else if (ind-> Addr ()-> OperIs (GT_LCL_VAR) && ! comp-> lvaVarAddrExposed ( ind->Addr ()-> AsLclVar ()-> GetLclNum () ))
7875+ else if (isNodeInvariant ( comp, ind->Addr (), true ))
78687876 {
78697877 // Address is just a local, no offset, scale is 1
78707878 data->baseAddr = ind->Addr ();
@@ -8077,8 +8085,6 @@ void Lowering::LowerStoreIndirCoalescing(GenTreeStoreInd* ind)
80778085#if defined(TARGET_AMD64) && defined(FEATURE_HW_INTRINSICS)
80788086 if (varTypeIsSIMD (oldType))
80798087 {
8080- assert (prevData.value ->IsVectorConst () && currData.value ->IsVectorConst ());
8081-
80828088 int8_t * lowerCns = prevData.value ->AsVecCon ()->gtSimdVal .i8 ;
80838089 int8_t * upperCns = currData.value ->AsVecCon ()->gtSimdVal .i8 ;
80848090
@@ -8088,21 +8094,18 @@ void Lowering::LowerStoreIndirCoalescing(GenTreeStoreInd* ind)
80888094 std::swap (lowerCns, upperCns);
80898095 }
80908096
8091- simd_t newCns = {0 };
8097+ simd_t newCns = {};
80928098 uint32_t oldWidth = genTypeSize (oldType);
80938099 memcpy (newCns.i8 , lowerCns, oldWidth);
80948100 memcpy (newCns.i8 + oldWidth, upperCns, oldWidth);
80958101
8096- ind->Data ()->ClearContained ();
80978102 ind->Data ()->AsVecCon ()->gtSimdVal = newCns;
8103+ ind->Data ()->ClearContained ();
80988104 ind->gtFlags |= GTF_IND_UNALIGNED;
80998105 continue ;
81008106 }
81018107#endif
81028108
8103- // We currently only support these constants for val
8104- assert (prevData.value ->IsCnsIntOrI () && currData.value ->IsCnsIntOrI ());
8105-
81068109 size_t lowerCns = (size_t )prevData.value ->AsIntCon ()->IconValue ();
81078110 size_t upperCns = (size_t )currData.value ->AsIntCon ()->IconValue ();
81088111
0 commit comments