Skip to content

Commit 5efdfd0

Browse files
authored
JIT: Use native sized indices in the backend for GetElement and WithElement (#118990)
1 parent 61b5219 commit 5efdfd0

File tree

5 files changed

+53
-0
lines changed

5 files changed

+53
-0
lines changed

src/coreclr/jit/hwintrinsiccodegenxarch.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,6 +2001,8 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
20012001
assert(genStackLevel == 0);
20022002
#endif // !FEATURE_FIXED_OUT_ARGS
20032003

2004+
assert(op2->TypeIs(TYP_I_IMPL));
2005+
20042006
regNumber indexReg = op2->GetRegNum();
20052007
regNumber valueReg = op3->GetRegNum(); // New element value to be stored
20062008

@@ -2035,6 +2037,8 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
20352037
simdType = TYP_SIMD16;
20362038
}
20372039

2040+
assert(op2->TypeIs(TYP_I_IMPL));
2041+
20382042
// Optimize the case of op1 is in memory and trying to access i'th element.
20392043
if (!op1->isUsedFromReg())
20402044
{

src/coreclr/jit/lower.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11682,6 +11682,40 @@ GenTree* Lowering::InsertNewSimdCreateScalarUnsafeNode(var_types simdType,
1168211682
}
1168311683
return result;
1168411684
}
11685+
11686+
//----------------------------------------------------------------------------------------------
11687+
// Lowering::NormalizeIndexToNativeSized:
11688+
// Prepare to use an index for address calculations by ensuring it is native sized.
11689+
//
11690+
// Arguments:
11691+
// index - The index that may be an int32
11692+
//
11693+
// Returns:
11694+
// The node itself, or a cast added on top of the node to perform normalization.
11695+
//
11696+
// Remarks:
11697+
// May insert a cast or may bash the node type in place for constants. Does
11698+
// not replace the use.
11699+
//
11700+
GenTree* Lowering::NormalizeIndexToNativeSized(GenTree* index)
11701+
{
11702+
if (genActualType(index) == TYP_I_IMPL)
11703+
{
11704+
return index;
11705+
}
11706+
11707+
if (index->OperIsConst())
11708+
{
11709+
index->gtType = TYP_I_IMPL;
11710+
return index;
11711+
}
11712+
else
11713+
{
11714+
GenTree* cast = comp->gtNewCastNode(TYP_I_IMPL, index, true, TYP_I_IMPL);
11715+
BlockRange().InsertAfter(index, cast);
11716+
return cast;
11717+
}
11718+
}
1168511719
#endif // FEATURE_HW_INTRINSICS
1168611720

1168711721
//----------------------------------------------------------------------------------------------

src/coreclr/jit/lower.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ class Lowering final : public Phase
463463
GenTree* op1,
464464
CorInfoType simdBaseJitType,
465465
unsigned simdSize);
466+
GenTree* NormalizeIndexToNativeSized(GenTree* index);
466467
#endif // FEATURE_HW_INTRINSICS
467468

468469
// Utility functions

src/coreclr/jit/lowerarmarch.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,6 +1684,9 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
16841684
GenTree* op1 = node->Op(1);
16851685
GenTree* op2 = node->Op(2);
16861686

1687+
op2 = NormalizeIndexToNativeSized(op2);
1688+
node->Op(2) = op2;
1689+
16871690
bool isContainableMemory = IsContainableMemoryOp(op1) && IsSafeToContainMem(node, op1);
16881691

16891692
if (isContainableMemory || !op2->OperIsConst())

src/coreclr/jit/lowerxarch.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4890,6 +4890,9 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node)
48904890
return LowerNode(node);
48914891
}
48924892

4893+
op2 = NormalizeIndexToNativeSized(op2);
4894+
node->Op(2) = op2;
4895+
48934896
uint32_t elemSize = genTypeSize(simdBaseType);
48944897
uint32_t count = simdSize / elemSize;
48954898

@@ -5252,6 +5255,12 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node)
52525255
{
52535256
// We specially handle float and double for more efficient codegen
52545257
resIntrinsic = NI_Vector128_GetElement;
5258+
// GetElement takes a native sized index after lowering, so change
5259+
// the type of the constant we inserted above.
5260+
// (This is generally only for the non constant index case,
5261+
// which is not the case here, but keep the index operand's
5262+
// type consistent)
5263+
op2->gtType = TYP_I_IMPL;
52555264
break;
52565265
}
52575266

@@ -5337,6 +5346,8 @@ GenTree* Lowering::LowerHWIntrinsicWithElement(GenTreeHWIntrinsic* node)
53375346

53385347
if (!op2->OperIsConst())
53395348
{
5349+
op2 = NormalizeIndexToNativeSized(op2);
5350+
node->Op(2) = op2;
53405351
// We will specially handle WithElement in codegen when op2 isn't a constant
53415352
ContainCheckHWIntrinsic(node);
53425353
return node->gtNext;

0 commit comments

Comments
 (0)