Skip to content
Merged
2 changes: 2 additions & 0 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,8 @@ class CodeGen final : public CodeGenInterface
#endif // defined(TARGET_XARCH)

#ifdef TARGET_ARM64
void genEmbeddedMaskedHWIntrinsic(const HWIntrinsic intrinCndSel, regNumber targetReg);

class HWIntrinsicImmOpHelper final
{
public:
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/jit/emitarm64sve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19339,7 +19339,10 @@ void emitter::emitInsPairSanityCheck(instrDesc* firstId, instrDesc* secondId)
assert(firstId->idReg2() == secondId->idReg2());

// "predicated using the same governing predicate register and source element size as this instruction."
assert(firstId->idInsOpt() == secondId->idInsOpt());
emitAttr dstSize1 = optGetSveElemsize(firstId->idInsOpt());
emitAttr dstSize2 = insOptsScalableStandard(secondId->idInsOpt()) ? optGetSveElemsize(secondId->idInsOpt())
: optGetDstsize(secondId->idInsOpt());
assert(dstSize1 == dstSize2);
}

// The following instructions cannot use predicated movprfx, else the behaviour will be unpredictable.
Expand Down
1,110 changes: 476 additions & 634 deletions src/coreclr/jit/hwintrinsiccodegenarm64.cpp

Large diffs are not rendered by default.

21 changes: 12 additions & 9 deletions src/coreclr/jit/lowerarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4074,23 +4074,26 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
}

// Handle op3
if (op3->IsVectorZero() && op1->IsTrueMask(node->GetSimdBaseType()) && op2->IsEmbMaskOp())
if (op3->IsVectorZero() && op2->IsEmbMaskOp())
{
// When we are merging with zero, we can specialize
// and avoid instantiating the vector constant.
// Do this only if op1 was AllTrueMask
// When we are merging with zero, we can specialize and avoid instantiating the vector constant.
switch (op2->AsHWIntrinsic()->GetHWIntrinsicId())
{
case NI_Sve2_AddPairwise:
case NI_Sve2_MaxNumberPairwise:
case NI_Sve2_MaxPairwise:
case NI_Sve2_MinNumberPairwise:
case NI_Sve2_MinPairwise:
// This is an edge case where these instructions have unpredictable behaviour when
// using predicated movprfx, so the unpredicated variant must be used here. This
// prevents us from performing this optimization as we will need the constant vector
// for masking the result.
break;
case NI_Sve2_ConvertToDoubleOdd:
case NI_Sve2_ConvertToSingleOdd:
case NI_Sve2_ConvertToSingleOddRoundToOdd:
// This is an edge case where these instructions do not support predicated or any movprfx.
if (!op1->IsTrueMask(node->GetSimdBaseType()))
{
// When op1 is not all-true, we will need the constant vector for masking the result.
break;
}
FALLTHROUGH;

default:
MakeSrcContained(node, op3);
Expand Down
8 changes: 7 additions & 1 deletion src/coreclr/jit/lsraarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,6 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou
{
assert(addrOp != operand);
assert(consecutiveOp != operand);
assert(delayFreeOp != operand);
Comment thread
ylpoonlg marked this conversation as resolved.

srcCount += BuildEmbeddedOperandUses(embeddedOp, delayFreeOp);
}
Expand Down Expand Up @@ -2356,6 +2355,13 @@ GenTree* LinearScan::getDelayFreeOperand(GenTreeHWIntrinsic* intrinsicTree, bool
assert(delayFreeOp != nullptr);
}
}
else if (intrinsicTree->GetOperandCount() == 1 && embedded)
{
// 1-operand embedded masked operations are non-RMW, but they could also use movprfx.
// Set delayFreeOp to the embedded node itself so that op1 can be delay-freed.
delayFreeOp = intrinsicTree;
assert(delayFreeOp != nullptr);
Comment thread
ylpoonlg marked this conversation as resolved.
}
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2BaseType}* op2, {Op3VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, op3, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2BaseType}* op2, {Op3VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, op3, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2BaseType}* op2, {Op3VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, op3, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Comment thread
dhartglassMSFT marked this conversation as resolved.
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {RetVectorType}<{RetBaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);
var result = (falseOp == {RetVectorType}<{RetBaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), {RetVectorType}<{RetBaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue(Vector<{RetBaseType}> mask, Vector<{Op1BaseType}> op1, Vector<{Op2BaseType}> op2, Vector<{RetBaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);
var result = (falseOp == Vector<{RetBaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), Vector<{RetBaseType}>.Zero) :
Comment thread
dhartglassMSFT marked this conversation as resolved.
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);
ValidateConditionalSelectResult(mask, op1, op2, falseOp, result);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op3VectorType}<{Op3BaseType}> op3, {RetVectorType}<{RetBaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, {Imm1}, {Imm2}), falseOp);
var result = (falseOp == {RetVectorType}<{RetBaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, {Imm1}, {Imm2}), {RetVectorType}<{RetBaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, {Imm1}, {Imm2}), falseOp);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, op3, falseOp, _dataTable.outArrayPtr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {RetVectorType}<{RetBaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, Imm), falseOp);
var result = (falseOp == {RetVectorType}<{RetBaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, Imm), {RetVectorType}<{RetBaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, Imm), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {RetVectorType}<{RetBaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, {Imm}), falseOp);
var result = (falseOp == {RetVectorType}<{RetBaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, {Imm}), {RetVectorType}<{RetBaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, {Imm}), falseOp);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, Imm), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, Imm), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, Imm), falseOp);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, op3, falseOp, _dataTable.outArrayPtr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{RetBaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, Imm), falseOp);
var result = (falseOp == {Op1VectorType}<{RetBaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, Imm), {Op1VectorType}<{RetBaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, Imm), falseOp);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, op3, falseOp, _dataTable.outArrayPtr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op, {RetVectorType}<{RetBaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op, {Imm}), falseOp);
var result = (falseOp == {RetVectorType}<{RetBaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op, {Imm}), {RetVectorType}<{RetBaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op, {Imm}), falseOp);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op, falseOp, Imm, _dataTable.outArrayPtr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {RetVectorType}<{RetBaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1), falseOp);
var result = (falseOp == {RetVectorType}<{RetBaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1), {RetVectorType}<{RetBaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, falseOp, _dataTable.outArrayPtr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,9 @@ namespace {Namespace}
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp)
{
var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp);
var result = (falseOp == {Op1VectorType}<{Op1BaseType}>.Zero) ?
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), {Op1VectorType}<{Op1BaseType}>.Zero) :
Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateConditionalSelectResult_TrueValue(mask, op1, op2, op3, falseOp, _dataTable.outArrayPtr);
Expand Down
Loading
Loading