Skip to content

Commit 1151a7b

Browse files
authored
JIT: Use native sized indices in the backend for GetElement and WithElement (#118990) (#119172)
1 parent 718b1a9 commit 1151a7b

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
@@ -2027,6 +2027,8 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
20272027
assert(genStackLevel == 0);
20282028
#endif // !FEATURE_FIXED_OUT_ARGS
20292029

2030+
assert(op2->TypeIs(TYP_I_IMPL));
2031+
20302032
regNumber indexReg = op2->GetRegNum();
20312033
regNumber valueReg = op3->GetRegNum(); // New element value to be stored
20322034

@@ -2061,6 +2063,8 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
20612063
simdType = TYP_SIMD16;
20622064
}
20632065

2066+
assert(op2->TypeIs(TYP_I_IMPL));
2067+
20642068
// Optimize the case of op1 is in memory and trying to access i'th element.
20652069
if (!op1->isUsedFromReg())
20662070
{

src/coreclr/jit/lower.cpp

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

1168611720
//----------------------------------------------------------------------------------------------

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
@@ -5173,6 +5173,9 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node)
51735173
return LowerNode(node);
51745174
}
51755175

5176+
op2 = NormalizeIndexToNativeSized(op2);
5177+
node->Op(2) = op2;
5178+
51765179
uint32_t elemSize = genTypeSize(simdBaseType);
51775180
uint32_t count = simdSize / elemSize;
51785181

@@ -5535,6 +5538,12 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node)
55355538
{
55365539
// We specially handle float and double for more efficient codegen
55375540
resIntrinsic = NI_Vector128_GetElement;
5541+
// GetElement takes a native sized index after lowering, so change
5542+
// the type of the constant we inserted above.
5543+
// (This is generally only for the non constant index case,
5544+
// which is not the case here, but keep the index operand's
5545+
// type consistent)
5546+
op2->gtType = TYP_I_IMPL;
55385547
break;
55395548
}
55405549

@@ -5625,6 +5634,8 @@ GenTree* Lowering::LowerHWIntrinsicWithElement(GenTreeHWIntrinsic* node)
56255634

56265635
if (!op2->OperIsConst())
56275636
{
5637+
op2 = NormalizeIndexToNativeSized(op2);
5638+
node->Op(2) = op2;
56285639
// We will specially handle WithElement in codegen when op2 isn't a constant
56295640
ContainCheckHWIntrinsic(node);
56305641
return node->gtNext;

0 commit comments

Comments
 (0)