Skip to content

Commit 7132299

Browse files
Ensure that bitwise operations of small masks can still be folded (#117887)
* Ensure that bitwise operations of small masks can still be folded * Ensure that the ability to negate a comparison isn't regressed
1 parent b131b6d commit 7132299

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

src/coreclr/jit/gentree.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32399,10 +32399,10 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree)
3239932399
GenTreeHWIntrinsic* cvtOp1 = op1->AsHWIntrinsic();
3240032400
GenTreeHWIntrinsic* cvtOp2 = (effectiveOper == GT_NOT) ? cvtOp1 : op2->AsHWIntrinsic();
3240132401

32402-
unsigned simdBaseTypeSize = genTypeSize(simdBaseType);
32402+
var_types op1SimdBaseType = cvtOp1->GetSimdBaseType();
32403+
var_types op2SimdBaseType = cvtOp2->GetSimdBaseType();
3240332404

32404-
if ((genTypeSize(cvtOp1->GetSimdBaseType()) == simdBaseTypeSize) &&
32405-
(genTypeSize(cvtOp2->GetSimdBaseType()) == simdBaseTypeSize))
32405+
if (genTypeSize(op1SimdBaseType) == genTypeSize(op2SimdBaseType))
3240632406
{
3240732407
// We need both operands to be the same kind of mask; otherwise
3240832408
// the bitwise operation can differ in how it performs
@@ -32455,6 +32455,12 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree)
3245532455
tree->gtFlags &= ~GTF_REVERSE_OPS;
3245632456
}
3245732457

32458+
// The bitwise operation is likely normalized to int or uint, while
32459+
// the underlying convert ops may be a small type. We need to preserve
32460+
// such a small type since that indicates how many elements are in the mask.
32461+
simdBaseJitType = cvtOp1->GetSimdBaseJitType();
32462+
tree->SetSimdBaseJitType(simdBaseJitType);
32463+
3245832464
tree->gtType = TYP_MASK;
3245932465
DEBUG_DESTROY_NODE(op1);
3246032466

src/coreclr/jit/morph.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11279,6 +11279,43 @@ GenTree* Compiler::fgMorphHWIntrinsic(GenTreeHWIntrinsic* tree)
1127911279
// Perform the required oper-specific postorder morphing
1128011280
//
1128111281

11282+
// If the folded tree is a vector to mask conversion, or vice versa,
11283+
// then we want to morph the inner operand as we may have folded something
11284+
// like xor(masktovector(op1), AllBitsSet) into masktovector(not(op1)), which
11285+
// can unlock further optimizations over op1, like the ability to invert
11286+
// not(cmple(op1, op2)) into cmpgt(op1, op2)
11287+
11288+
int opIndex = 0;
11289+
11290+
if (tree->OperIsConvertVectorToMask() || tree->OperIsConvertMaskToVector())
11291+
{
11292+
opIndex = 1;
11293+
}
11294+
11295+
#if defined(TARGET_ARM64)
11296+
if (tree->OperIsConvertVectorToMask())
11297+
{
11298+
opIndex = 2;
11299+
}
11300+
#endif // TARGET_ARM64
11301+
11302+
if (opIndex != 0)
11303+
{
11304+
GenTree* innerOp = tree->Op(opIndex);
11305+
11306+
if (innerOp->OperIsHWIntrinsic())
11307+
{
11308+
innerOp = fgMorphHWIntrinsicRequired(innerOp->AsHWIntrinsic());
11309+
11310+
if (innerOp->OperIsHWIntrinsic())
11311+
{
11312+
innerOp = fgMorphHWIntrinsicOptional(innerOp->AsHWIntrinsic());
11313+
}
11314+
11315+
tree->Op(opIndex) = innerOp;
11316+
}
11317+
}
11318+
1128211319
morphedTree = fgMorphHWIntrinsicRequired(tree);
1128311320

1128411321
if (morphedTree->OperIsHWIntrinsic())

0 commit comments

Comments
 (0)