Skip to content

Commit 1d904dc

Browse files
committed
Create a valid addr mode for Arm64
1 parent a6a4b0e commit 1d904dc

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

src/coreclr/jit/lowerarmarch.cpp

+26-15
Original file line numberDiff line numberDiff line change
@@ -1267,13 +1267,12 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
12671267
unsigned simdSize = node->GetSimdSize();
12681268
var_types simdBaseType = node->GetSimdBaseType();
12691269
var_types simdType = Compiler::getSIMDTypeForSize(simdSize);
1270-
unsigned scale = genTypeSize(simdBaseType);
1271-
ssize_t offset = 0;
12721270

12731271
// We're either already loading from memory or we need to since
12741272
// we don't know what actual index is going to be retrieved.
12751273

1276-
unsigned lclNum = BAD_VAR_NUM;
1274+
unsigned lclNum = BAD_VAR_NUM;
1275+
unsigned lclOffs = 0;
12771276

12781277
if (!isContainableMemory)
12791278
{
@@ -1291,16 +1290,16 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
12911290
// We're an existing local that is loaded from memory
12921291
GenTreeLclVarCommon* lclVar = op1->AsLclVarCommon();
12931292

1294-
lclNum = lclVar->GetLclNum();
1295-
offset = lclVar->GetLclOffs();
1293+
lclNum = lclVar->GetLclNum();
1294+
lclOffs = lclVar->GetLclOffs();
12961295

12971296
BlockRange().Remove(op1);
12981297
}
12991298

13001299
if (lclNum != BAD_VAR_NUM)
13011300
{
13021301
// We need to get the address of the local
1303-
op1 = comp->gtNewLclVarAddrNode(lclNum, TYP_BYREF);
1302+
op1 = comp->gtNewLclAddrNode(lclNum, lclOffs, TYP_BYREF);
13041303
BlockRange().InsertBefore(node, op1);
13051304
LowerNode(op1);
13061305
}
@@ -1314,22 +1313,34 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
13141313
op1 = addr;
13151314
}
13161315

1317-
// Now that we have a memory op, we need to offset it by op2 * scale
1316+
GenTree* offset;
1317+
13181318
if (op2->OperIsConst())
13191319
{
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);
13221332

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);
13251336
}
13261337

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);
13301341

13311342
// 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);
13331344
BlockRange().InsertBefore(node, indir);
13341345

13351346
LIR::Use use;

0 commit comments

Comments
 (0)