Skip to content

Commit

Permalink
#78303 Add transformation ~v1 & v2 to VectorXxx.AndNot(v1, v2) (#81993)
Browse files Browse the repository at this point in the history
Co-authored-by: EgorBo <[email protected]>
  • Loading branch information
SkiFoD and EgorBo authored Sep 4, 2023
1 parent 741ab87 commit 13a225f
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 1 deletion.
48 changes: 48 additions & 0 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25468,6 +25468,54 @@ void GenTreeHWIntrinsic::Initialize(NamedIntrinsic intrinsicId)
}
}
}

//------------------------------------------------------------------------------
// HWOperGet : Returns Oper based on the HWIntrinsicId
//
genTreeOps GenTreeHWIntrinsic::HWOperGet()
{
switch (GetHWIntrinsicId())
{
#if defined(TARGET_XARCH)
case NI_SSE_And:
case NI_SSE2_And:
case NI_AVX_And:
case NI_AVX2_And:
#elif defined(TARGET_ARM64)
case NI_AdvSimd_And:
#endif
{
return GT_AND;
}

#if defined(TARGET_ARM64)
case NI_AdvSimd_Not:
{
return GT_NOT;
}
#endif

#if defined(TARGET_XARCH)
case NI_SSE_Xor:
case NI_SSE2_Xor:
case NI_AVX_Xor:
case NI_AVX2_Xor:
#elif defined(TARGET_ARM64)
case NI_AdvSimd_Xor:
#endif
{
return GT_XOR;
}

// TODO: Handle other cases

default:
{
return GT_NONE;
}
}
}

#endif // FEATURE_HW_INTRINSICS

//---------------------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -6343,6 +6343,8 @@ struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic

static bool Equals(GenTreeHWIntrinsic* op1, GenTreeHWIntrinsic* op2);

genTreeOps HWOperGet();

private:
void SetHWIntrinsicId(NamedIntrinsic intrinsicId);

Expand Down
93 changes: 92 additions & 1 deletion src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10787,7 +10787,6 @@ GenTree* Compiler::fgOptimizeHWIntrinsic(GenTreeHWIntrinsic* node)
INDEBUG(node->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
return node;
}

#if defined(TARGET_XARCH)
case NI_AVX512F_Add:
case NI_AVX512BW_Add:
Expand Down Expand Up @@ -10951,6 +10950,98 @@ GenTree* Compiler::fgOptimizeHWIntrinsic(GenTreeHWIntrinsic* node)
}
}

// Transforms:
// 1.(~v1 & v2) to VectorXxx.AndNot(v1, v2)
// 2.(v1 & (~v2)) to VectorXxx.AndNot(v2, v1)
switch (node->HWOperGet())
{
case GT_AND:
{
GenTree* op1 = node->Op(1);
GenTree* op2 = node->Op(2);
GenTree* lhs = nullptr;
GenTree* rhs = nullptr;

if (op1->OperIsHWIntrinsic())
{
// Try handle: ~op1 & op2
GenTreeHWIntrinsic* hw = op1->AsHWIntrinsic();
genTreeOps hwOper = hw->HWOperGet();

if (hwOper == GT_NOT)
{
lhs = op2;
rhs = hw->Op(1);
}
else if (hwOper == GT_XOR)
{
GenTree* hwOp1 = hw->Op(1);
GenTree* hwOp2 = hw->Op(2);

if (hwOp1->IsVectorAllBitsSet())
{
lhs = op2;
rhs = hwOp2;
}
else if (hwOp2->IsVectorAllBitsSet())
{
lhs = op2;
rhs = hwOp1;
}
}
}

if ((lhs == nullptr) && op2->OperIsHWIntrinsic())
{
// Try handle: op1 & ~op2
GenTreeHWIntrinsic* hw = op2->AsHWIntrinsic();
genTreeOps hwOper = hw->HWOperGet();

if (hwOper == GT_NOT)
{
lhs = op1;
rhs = hw->Op(1);
}
else if (hwOper == GT_XOR)
{
GenTree* hwOp1 = hw->Op(1);
GenTree* hwOp2 = hw->Op(2);

if (hwOp1->IsVectorAllBitsSet())
{
lhs = op1;
rhs = hwOp2;
}
else if (hwOp2->IsVectorAllBitsSet())
{
lhs = op1;
rhs = hwOp1;
}
}
}

if (lhs == nullptr || rhs == nullptr)
{
break;
}

var_types simdType = node->TypeGet();
CorInfoType simdBaseJitType = node->GetSimdBaseJitType();
unsigned int simdSize = node->GetSimdSize();

GenTree* andnNode = gtNewSimdBinOpNode(GT_AND_NOT, simdType, lhs, rhs, simdBaseJitType, simdSize);

DEBUG_DESTROY_NODE(node);
INDEBUG(andnNode->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);

return andnNode;
}
default:
{
break;
}
}

return node;
}

Expand Down

0 comments on commit 13a225f

Please sign in to comment.