Skip to content

Commit

Permalink
Fix an assert and clean up a codegen issue (#90067)
Browse files Browse the repository at this point in the history
  • Loading branch information
tannergooding authored Aug 6, 2023
1 parent 242fc7d commit 3f566cd
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions src/coreclr/jit/lowerxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1205,15 +1205,17 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
{
// We have `CompareEqual(x, Zero)` where a given element
// equaling zero returns 1. We can therefore use `vptestnm(x, x)`
// since it does `~(x & x)` and setting 1 if the result is zero.
// since it does `(x & x) == 0`, thus giving us `1` if zero and `0`
// if non-zero

testIntrinsicId = NI_AVX512F_PTESTNM;
}
else
{
// We have `CompareNotEqual(x, Zero)` where a given element
// equaling zero returns 0. We can therefore use `vptestm(x, x)`
// since it does `x & x` and setting 0 if the result is zero.
// since it does `(x & x) != 0`, thus giving us `1` if non-zero and `0`
// if zero

assert(intrinsicId == NI_AVX512F_CompareNotEqualMask);
testIntrinsicId = NI_AVX512F_PTESTM;
Expand Down Expand Up @@ -2113,14 +2115,23 @@ GenTree* Lowering::LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cm
case NI_AVX512F_And:
case NI_AVX512DQ_And:
{
// We can optimize since `vptestm` does `(x & y) != 0`
// and `vptestnm` does `(x & y) == 0`.
// We have `(x & y) == 0` with GenCondition::EQ (jz, setz, cmovz)
// or `(x & y) != 0`with GenCondition::NE (jnz, setnz, cmovnz)
//
// `vptestnm(x, y)` does the equivalent of `(x & y) == 0`,
// thus giving us `1` if zero and `0` if non-zero
//
// `vptestm(x, y)` does the equivalent of `(x & y) != 0`,
// thus giving us `1` if non-zero and `0` if zero
//
// Given the mask produced `m`, we then do `zf: (m == Zero)`, `cf: (m == AllBitsSet)`
//
// Thus, for either we can first emit `vptestm(x, y)`. This gives us a mask where
// `0` means the corresponding elements compared to zero. The subsequent `kortest`
// will then set `ZF: 1` if all elements were 0 and `ZF: 0` if any elements were
// non-zero. The default GenCondition then remain correct

if (cmpOp == GT_EQ)
{
testIntrinsicId = NI_AVX512F_PTESTNM;
cmpCnd = GenCondition::NE;
}
assert(testIntrinsicId == NI_AVX512F_PTESTM);

node->Op(1) = op1Intrinsic->Op(1);
node->Op(2) = op1Intrinsic->Op(2);
Expand Down Expand Up @@ -4589,9 +4600,8 @@ GenTree* Lowering::LowerHWIntrinsicWithElement(GenTreeHWIntrinsic* node)
{
// Now that we have finalized the shape of the tree, lower the insertion node as well.

assert((node->GetHWIntrinsicId() == NI_Vector512_GetLower128) ||
(node->GetHWIntrinsicId() == NI_AVX512F_ExtractVector128) ||
(node->GetHWIntrinsicId() == NI_AVX512DQ_ExtractVector128));
assert((node->GetHWIntrinsicId() == NI_AVX512F_InsertVector128) ||
(node->GetHWIntrinsicId() == NI_AVX512DQ_InsertVector128));
assert(node != result);

nextNode = LowerNode(node);
Expand Down

0 comments on commit 3f566cd

Please sign in to comment.