@@ -689,69 +689,43 @@ bool Compiler::areArgumentsContiguous(GenTree* op1, GenTree* op2)
689689GenTree* Compiler::CreateAddressNodeForSimdHWIntrinsicCreate (GenTree* tree, var_types simdBaseType, unsigned simdSize)
690690{
691691 assert (tree->OperIs (GT_IND));
692- GenTree* addr = tree->AsIndir ()->Addr ();
693- GenTree* byrefNode = nullptr ;
694- unsigned offset = 0 ;
695- var_types baseType = tree->gtType ;
692+ GenTree* addr = tree->AsIndir ()->Addr ();
696693
697694 if (addr->OperIs (GT_FIELD_ADDR))
698695 {
699696 assert (addr->AsFieldAddr ()->IsInstance ());
700697
698+ // If the field is directly from a struct, then in this case, we should set this
699+ // struct's lvUsedInSIMDIntrinsic as true, so that this sturct won't be promoted.
701700 GenTree* objRef = addr->AsFieldAddr ()->GetFldObj ();
702- if (objRef->IsLclVarAddr ())
701+ if (objRef->IsLclVarAddr () && varTypeIsSIMD ( lvaGetDesc (objRef-> AsLclFld ())) )
703702 {
704- // If the field is directly from a struct, then in this case,
705- // we should set this struct's lvUsedInSIMDIntrinsic as true,
706- // so that this sturct won't be promoted.
707- // e.g. s.x x is a field, and s is a struct, then we should set the s's lvUsedInSIMDIntrinsic as true.
708- // so that s won't be promoted.
709- // Notice that if we have a case like s1.s2.x. s1 s2 are struct, and x is a field, then it is possible that
710- // s1 can be promoted, so that s2 can be promoted. The reason for that is if we don't allow s1 to be
711- // promoted, then this will affect the other optimizations which are depend on s1's struct promotion.
712- // TODO-CQ:
713- // In future, we should optimize this case so that if there is a nested field like s1.s2.x and s1.s2.x's
714- // address is used for initializing the vector, then s1 can be promoted but s2 can't.
715- if (varTypeIsSIMD (lvaGetDesc (objRef->AsLclFld ())))
716- {
717- setLclRelatedToSIMDIntrinsic (objRef);
718- }
703+ setLclRelatedToSIMDIntrinsic (objRef);
719704 }
720705
721- // TODO-FIELD: this seems unnecessary. Simply "return addr;"?
722- byrefNode = gtCloneExpr (objRef);
723- assert (byrefNode != nullptr );
724- offset = addr->AsFieldAddr ()->gtFldOffset ;
725- }
726- else
727- {
728- GenTree* arrayRef = addr->AsIndexAddr ()->Arr ();
729- GenTree* index = addr->AsIndexAddr ()->Index ();
730- assert (index->IsCnsIntOrI ());
731-
732- GenTree* checkIndexExpr = nullptr ;
733- unsigned indexVal = (unsigned )index->AsIntCon ()->gtIconVal ;
734- offset = indexVal * genTypeSize (tree->TypeGet ());
735-
736- // Generate the boundary check exception.
737- // The length for boundary check should be the maximum index number which should be
738- // (first argument's index number) + (how many array arguments we have) - 1
739- // = indexVal + arrayElementsCount - 1
740- unsigned arrayElementsCount = simdSize / genTypeSize (simdBaseType);
741- checkIndexExpr = gtNewIconNode (indexVal + arrayElementsCount - 1 );
742- GenTreeArrLen* arrLen = gtNewArrLen (TYP_INT, arrayRef, (int )OFFSETOF__CORINFO_Array__length, compCurBB);
743- GenTreeBoundsChk* arrBndsChk =
744- new (this , GT_BOUNDS_CHECK) GenTreeBoundsChk (checkIndexExpr, arrLen, SCK_ARG_RNG_EXCPN);
745-
746- offset += OFFSETOF__CORINFO_Array__data;
747- byrefNode = gtNewOperNode (GT_COMMA, arrayRef->TypeGet (), arrBndsChk, gtCloneExpr (arrayRef));
706+ return addr;
748707 }
749708
750- GenTree* address = byrefNode;
751- if (offset != 0 )
752- {
753- address = gtNewOperNode (GT_ADD, TYP_BYREF, address, gtNewIconNode (offset, TYP_I_IMPL));
754- }
709+ GenTree* arrayRef = addr->AsIndexAddr ()->Arr ();
710+ GenTree* index = addr->AsIndexAddr ()->Index ();
711+ assert (index->IsCnsIntOrI ());
712+
713+ unsigned indexVal = (unsigned )index->AsIntCon ()->gtIconVal ;
714+ unsigned offset = indexVal * genTypeSize (tree->TypeGet ());
715+
716+ // Generate the boundary check exception.
717+ // The length for boundary check should be the maximum index number which should be
718+ // (first argument's index number) + (how many array arguments we have) - 1 = indexVal + arrayElementsCount - 1
719+ //
720+ unsigned arrayElementsCount = simdSize / genTypeSize (simdBaseType);
721+ GenTree* checkIndexExpr = gtNewIconNode (indexVal + arrayElementsCount - 1 );
722+ GenTreeArrLen* arrLen = gtNewArrLen (TYP_INT, arrayRef, (int )OFFSETOF__CORINFO_Array__length, compCurBB);
723+ GenTreeBoundsChk* arrBndsChk =
724+ new (this , GT_BOUNDS_CHECK) GenTreeBoundsChk (checkIndexExpr, arrLen, SCK_ARG_RNG_EXCPN);
725+
726+ offset += OFFSETOF__CORINFO_Array__data;
727+ GenTree* address = gtNewOperNode (GT_COMMA, arrayRef->TypeGet (), arrBndsChk, gtCloneExpr (arrayRef));
728+ address = gtNewOperNode (GT_ADD, TYP_BYREF, address, gtNewIconNode (offset, TYP_I_IMPL));
755729
756730 return address;
757731}
0 commit comments