@@ -1307,9 +1307,10 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
1307
1307
break ;
1308
1308
1309
1309
#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
1312
1312
// 2. Plane where we have 1x Vector3 and 1x float field
1313
+ // 3. Accesses of halves of larger SIMD types
1313
1314
1314
1315
case IndirTransform::GetElement:
1315
1316
{
@@ -1321,24 +1322,29 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
1321
1322
{
1322
1323
case TYP_FLOAT:
1323
1324
{
1325
+ // Handle case 1 or the float field of case 2
1324
1326
GenTree* indexNode = m_compiler->gtNewIconNode (offset / genTypeSize (elementType));
1325
1327
hwiNode = m_compiler->gtNewSimdGetElementNode (elementType, lclNode, indexNode,
1326
1328
CORINFO_TYPE_FLOAT, genTypeSize (varDsc));
1327
1329
break ;
1328
1330
}
1331
+
1329
1332
case TYP_SIMD12:
1330
1333
{
1334
+ // Handle the Vector3 field of case 2
1331
1335
assert (genTypeSize (varDsc) == 16 );
1332
1336
hwiNode = m_compiler->gtNewSimdHWIntrinsicNode (elementType, lclNode, NI_Vector128_AsVector3,
1333
1337
CORINFO_TYPE_FLOAT, 16 );
1334
1338
break ;
1335
1339
}
1340
+
1336
1341
case TYP_SIMD8:
1337
1342
#if defined(FEATURE_SIMD) && defined(TARGET_XARCH)
1338
1343
case TYP_SIMD16:
1339
1344
case TYP_SIMD32:
1340
1345
#endif
1341
1346
{
1347
+ // Handle case 3
1342
1348
assert (genTypeSize (elementType) * 2 == genTypeSize (varDsc));
1343
1349
if (offset == 0 )
1344
1350
{
@@ -1374,29 +1380,44 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
1374
1380
{
1375
1381
case TYP_FLOAT:
1376
1382
{
1383
+ // Handle case 1 or the float field of case 2
1377
1384
GenTree* indexNode = m_compiler->gtNewIconNode (offset / genTypeSize (elementType));
1378
1385
hwiNode =
1379
1386
m_compiler->gtNewSimdWithElementNode (varDsc->TypeGet (), simdLclNode, indexNode, elementNode,
1380
1387
CORINFO_TYPE_FLOAT, genTypeSize (varDsc));
1381
1388
break ;
1382
1389
}
1390
+
1383
1391
case TYP_SIMD12:
1384
1392
{
1393
+ // Handle the Vector3 field of case 2
1385
1394
assert (varDsc->TypeGet () == TYP_SIMD16);
1386
1395
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,
1391
1410
CORINFO_TYPE_FLOAT, 16 );
1392
1411
break ;
1393
1412
}
1413
+
1394
1414
case TYP_SIMD8:
1395
1415
#if defined(FEATURE_SIMD) && defined(TARGET_XARCH)
1396
1416
case TYP_SIMD16:
1397
1417
case TYP_SIMD32:
1398
1418
#endif
1399
1419
{
1420
+ // Handle case 3
1400
1421
assert (genTypeSize (elementType) * 2 == genTypeSize (varDsc));
1401
1422
if (offset == 0 )
1402
1423
{
@@ -1412,6 +1433,7 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
1412
1433
1413
1434
break ;
1414
1435
}
1436
+
1415
1437
default :
1416
1438
unreached ();
1417
1439
}
@@ -1541,7 +1563,7 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
1541
1563
if (varTypeIsSIMD (varDsc))
1542
1564
{
1543
1565
// 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
1545
1567
// 2. Plane where we have 1x Vector3 and 1x float field
1546
1568
// 3. Accesses of halves of larger SIMD types
1547
1569
0 commit comments