@@ -1307,9 +1307,10 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
13071307                break ;
13081308
13091309#ifdef  FEATURE_HW_INTRINSICS
1310-                 //  We have two  cases we want to handle:
1311-                 //  1. Vector2/3/4 and Quaternion where we have 4x float fields
1310+                 //  We have three  cases we want to handle:
1311+                 //  1. Vector2/3/4 and Quaternion where we have 2- 4x float fields
13121312                //  2. Plane where we have 1x Vector3 and 1x float field
1313+                 //  3. Accesses of halves of larger SIMD types
13131314
13141315            case  IndirTransform::GetElement:
13151316            {
@@ -1321,24 +1322,29 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
13211322                {
13221323                    case  TYP_FLOAT:
13231324                    {
1325+                         //  Handle case 1 or the float field of case 2
13241326                        GenTree* indexNode = m_compiler->gtNewIconNode (offset / genTypeSize (elementType));
13251327                        hwiNode            = m_compiler->gtNewSimdGetElementNode (elementType, lclNode, indexNode,
13261328                                                                                 CORINFO_TYPE_FLOAT, genTypeSize (varDsc));
13271329                        break ;
13281330                    }
1331+ 
13291332                    case  TYP_SIMD12:
13301333                    {
1334+                         //  Handle the Vector3 field of case 2
13311335                        assert (genTypeSize (varDsc) == 16 );
13321336                        hwiNode = m_compiler->gtNewSimdHWIntrinsicNode (elementType, lclNode, NI_Vector128_AsVector3,
13331337                                                                       CORINFO_TYPE_FLOAT, 16 );
13341338                        break ;
13351339                    }
1340+ 
13361341                    case  TYP_SIMD8:
13371342#if  defined(FEATURE_SIMD) && defined(TARGET_XARCH)
13381343                    case  TYP_SIMD16:
13391344                    case  TYP_SIMD32:
13401345#endif 
13411346                    {
1347+                         //  Handle case 3
13421348                        assert (genTypeSize (elementType) * 2  == genTypeSize (varDsc));
13431349                        if  (offset == 0 )
13441350                        {
@@ -1374,29 +1380,44 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
13741380                {
13751381                    case  TYP_FLOAT:
13761382                    {
1383+                         //  Handle case 1 or the float field of case 2
13771384                        GenTree* indexNode = m_compiler->gtNewIconNode (offset / genTypeSize (elementType));
13781385                        hwiNode =
13791386                            m_compiler->gtNewSimdWithElementNode (varDsc->TypeGet (), simdLclNode, indexNode, elementNode,
13801387                                                                 CORINFO_TYPE_FLOAT, genTypeSize (varDsc));
13811388                        break ;
13821389                    }
1390+ 
13831391                    case  TYP_SIMD12:
13841392                    {
1393+                         //  Handle the Vector3 field of case 2
13851394                        assert (varDsc->TypeGet () == TYP_SIMD16);
13861395
1387-                         //  We inverse the operands here and take elementNode as the main value and simdLclNode[3] as the
1388-                         //  new value. This gives us a new TYP_SIMD16 with all elements in the right spots
1389-                         GenTree* indexNode = m_compiler->gtNewIconNode (3 , TYP_INT);
1390-                         hwiNode = m_compiler->gtNewSimdWithElementNode (TYP_SIMD16, elementNode, indexNode, simdLclNode,
1396+                         //  We effectively inverse the operands here and take elementNode as the main value and
1397+                         //  simdLclNode[3] as the new value. This gives us a new TYP_SIMD16 with all elements in the
1398+                         //  right spots
1399+ 
1400+                         elementNode = m_compiler->gtNewSimdHWIntrinsicNode (TYP_SIMD16, elementNode,
1401+                                                                            NI_Vector128_AsVector128Unsafe,
1402+                                                                            CORINFO_TYPE_FLOAT, 12 );
1403+ 
1404+                         GenTree* indexNode1 = m_compiler->gtNewIconNode (3 , TYP_INT);
1405+                         simdLclNode         = m_compiler->gtNewSimdGetElementNode (TYP_FLOAT, simdLclNode, indexNode1,
1406+                                                                                   CORINFO_TYPE_FLOAT, 16 );
1407+ 
1408+                         GenTree* indexNode2 = m_compiler->gtNewIconNode (3 , TYP_INT);
1409+                         hwiNode = m_compiler->gtNewSimdWithElementNode (TYP_SIMD16, elementNode, indexNode2, simdLclNode,
13911410                                                                       CORINFO_TYPE_FLOAT, 16 );
13921411                        break ;
13931412                    }
1413+ 
13941414                    case  TYP_SIMD8:
13951415#if  defined(FEATURE_SIMD) && defined(TARGET_XARCH)
13961416                    case  TYP_SIMD16:
13971417                    case  TYP_SIMD32:
13981418#endif 
13991419                    {
1420+                         //  Handle case 3
14001421                        assert (genTypeSize (elementType) * 2  == genTypeSize (varDsc));
14011422                        if  (offset == 0 )
14021423                        {
@@ -1412,6 +1433,7 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
14121433
14131434                        break ;
14141435                    }
1436+ 
14151437                    default :
14161438                        unreached ();
14171439                }
@@ -1541,7 +1563,7 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
15411563            if  (varTypeIsSIMD (varDsc))
15421564            {
15431565                //  We have three cases we want to handle:
1544-                 //  1. Vector2/3/4 and Quaternion where we have 4x float fields
1566+                 //  1. Vector2/3/4 and Quaternion where we have 2- 4x float fields
15451567                //  2. Plane where we have 1x Vector3 and 1x float field
15461568                //  3. Accesses of halves of larger SIMD types
15471569
0 commit comments