@@ -1267,13 +1267,12 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
1267
1267
unsigned simdSize = node->GetSimdSize ();
1268
1268
var_types simdBaseType = node->GetSimdBaseType ();
1269
1269
var_types simdType = Compiler::getSIMDTypeForSize (simdSize);
1270
- unsigned scale = genTypeSize (simdBaseType);
1271
- ssize_t offset = 0 ;
1272
1270
1273
1271
// We're either already loading from memory or we need to since
1274
1272
// we don't know what actual index is going to be retrieved.
1275
1273
1276
- unsigned lclNum = BAD_VAR_NUM;
1274
+ unsigned lclNum = BAD_VAR_NUM;
1275
+ unsigned lclOffs = 0 ;
1277
1276
1278
1277
if (!isContainableMemory)
1279
1278
{
@@ -1291,16 +1290,16 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
1291
1290
// We're an existing local that is loaded from memory
1292
1291
GenTreeLclVarCommon* lclVar = op1->AsLclVarCommon ();
1293
1292
1294
- lclNum = lclVar->GetLclNum ();
1295
- offset = lclVar->GetLclOffs ();
1293
+ lclNum = lclVar->GetLclNum ();
1294
+ lclOffs = lclVar->GetLclOffs ();
1296
1295
1297
1296
BlockRange ().Remove (op1);
1298
1297
}
1299
1298
1300
1299
if (lclNum != BAD_VAR_NUM)
1301
1300
{
1302
1301
// We need to get the address of the local
1303
- op1 = comp->gtNewLclVarAddrNode (lclNum, TYP_BYREF);
1302
+ op1 = comp->gtNewLclAddrNode (lclNum, lclOffs , TYP_BYREF);
1304
1303
BlockRange ().InsertBefore (node, op1);
1305
1304
LowerNode (op1);
1306
1305
}
@@ -1314,22 +1313,34 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
1314
1313
op1 = addr;
1315
1314
}
1316
1315
1317
- // Now that we have a memory op, we need to offset it by op2 * scale
1316
+ GenTree* offset;
1317
+
1318
1318
if (op2->OperIsConst ())
1319
1319
{
1320
- offset = offset + (op2->AsIntCon ()->IconValue () * scale);
1321
- scale = 0 ;
1320
+ // We have a constant index, so scale it up directly
1321
+ GenTreeIntConCommon* index = op2->AsIntCon ();
1322
+ index ->SetIconValue (index ->IconValue () * genTypeSize (simdBaseType));
1323
+ offset = index ;
1324
+ }
1325
+ else
1326
+ {
1327
+ // We have a non-constant index, so scale it up via mul
1328
+
1329
+ GenTreeIntConCommon* scale = comp->gtNewIconNode (genTypeSize (simdBaseType));
1330
+ BlockRange ().InsertBefore (node, scale);
1331
+ LowerNode (scale);
1322
1332
1323
- BlockRange ().Remove (op2);
1324
- op2 = nullptr ;
1333
+ offset = comp->gtNewOperNode (GT_MUL, op2->TypeGet (), op2, scale);
1334
+ BlockRange ().InsertBefore (node, offset);
1335
+ LowerNode (offset);
1325
1336
}
1326
1337
1327
- GenTree* addrMode = new ( comp, GT_LEA) GenTreeAddrMode ( op1->TypeGet (), op1, op2, scale , offset);
1328
- BlockRange ().InsertBefore (node, addrMode );
1329
- LowerNode (addrMode );
1338
+ GenTree* addr = comp-> gtNewOperNode (GT_ADD, op1->TypeGet (), op1, offset);
1339
+ BlockRange ().InsertBefore (node, addr );
1340
+ LowerNode (addr );
1330
1341
1331
1342
// Finally we can indirect the memory address to get the actual value
1332
- GenTreeIndir* indir = comp->gtNewIndir (simdBaseType, addrMode );
1343
+ GenTreeIndir* indir = comp->gtNewIndir (simdBaseType, addr );
1333
1344
BlockRange ().InsertBefore (node, indir);
1334
1345
1335
1346
LIR::Use use;
0 commit comments