Skip to content

Commit

Permalink
Add containment analysis for AdvSimd_FusedMultiplyAddScalar in lower.…
Browse files Browse the repository at this point in the history
…h lowerarmarch.cpp
  • Loading branch information
echesakov committed Jul 30, 2020
1 parent b8f84d1 commit 90d7d8d
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/coreclr/src/jit/lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,12 @@ class Lowering final : public Phase
void LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cmpOp);
void LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node);
void LowerHWIntrinsicDot(GenTreeHWIntrinsic* node);
void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node);

#if defined(TARGET_XARCH)
void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node);
void LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node);
#elif defined(TARGET_ARM64)
bool IsValidConstForMovImm(GenTreeHWIntrinsic* node);
void LowerHWIntrinsicFusedMultiplyAddScalar(GenTreeHWIntrinsic* node);
#endif // !TARGET_XARCH && !TARGET_ARM64

union VectorConstant {
Expand Down
74 changes: 74 additions & 0 deletions src/coreclr/src/jit/lowerarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,76 @@ void Lowering::LowerSIMD(GenTreeSIMD* simdNode)
#endif // FEATURE_SIMD

#ifdef FEATURE_HW_INTRINSICS

//----------------------------------------------------------------------------------------------
// LowerHWIntrinsicFusedMultiplyAddScalar: Lowers AdvSimd_FusedMultiplyAddScalar intrinsics
// when some of the operands are negated by "containing" such negation.
//
// Arguments:
// node - The original hardware intrinsic node
//
// | op1 | op2 | op3 |
// | + | + | + | AdvSimd_FusedMultiplyAddScalar
// | + | + | - | AdvSimd_FusedMultiplySubtractScalar
// | + | - | + | AdvSimd_FusedMultiplySubtractScalar
// | + | - | - | AdvSimd_FusedMultiplyAddScalar
// | - | + | + | AdvSimd_FusedMultiplySubtractNegatedScalar
// | - | + | - | AdvSimd_FusedMultiplyAddNegatedScalar
// | - | - | + | AdvSimd_FusedMultiplyAddNegatedScalar
// | - | - | - | AdvSimd_FusedMultiplySubtractNegatedScalar
//
void Lowering::LowerHWIntrinsicFusedMultiplyAddScalar(GenTreeHWIntrinsic* node)
{
assert(node->gtHWIntrinsicId == NI_AdvSimd_FusedMultiplyAddScalar);

const HWIntrinsic intrin(node);

GenTree* op1 = intrin.op1;
GenTree* op2 = intrin.op2;
GenTree* op3 = intrin.op3;

auto lowerOperand = [this](GenTree* op) {
bool wasNegated = false;

if (op->OperIsHWIntrinsic() &&
((op->AsHWIntrinsic()->gtHWIntrinsicId == NI_AdvSimd_Arm64_DuplicateToVector64) ||
(op->AsHWIntrinsic()->gtHWIntrinsicId == NI_Vector64_CreateScalarUnsafe)))
{
GenTreeHWIntrinsic* createVector64 = op->AsHWIntrinsic();
GenTree* valueOp = createVector64->gtGetOp1();

if (valueOp->OperIs(GT_NEG))
{
createVector64->gtOp1 = valueOp->gtGetOp1();
BlockRange().Remove(valueOp);
wasNegated = true;
}
}

return wasNegated;
};

const bool op1WasNegated = lowerOperand(op1);
const bool op2WasNegated = lowerOperand(op2);
const bool op3WasNegated = lowerOperand(op3);

if (op1WasNegated)
{
if (op2WasNegated != op3WasNegated)
{
node->gtHWIntrinsicId = NI_AdvSimd_FusedMultiplyAddNegatedScalar;
}
else
{
node->gtHWIntrinsicId = NI_AdvSimd_FusedMultiplySubtractNegatedScalar;
}
}
else if (op2WasNegated != op3WasNegated)
{
node->gtHWIntrinsicId = NI_AdvSimd_FusedMultiplySubtractScalar;
}
}

//----------------------------------------------------------------------------------------------
// Lowering::LowerHWIntrinsic: Perform containment analysis for a hardware intrinsic node.
//
Expand Down Expand Up @@ -573,6 +643,10 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
return;
}

case NI_AdvSimd_FusedMultiplyAddScalar:
LowerHWIntrinsicFusedMultiplyAddScalar(node);
break;

default:
break;
}
Expand Down

0 comments on commit 90d7d8d

Please sign in to comment.