Skip to content

Commit b3d4a4f

Browse files
authored
Don't fold CNS_VEC into a broadcast for EQ/NE(AND(X, CnsVec), ZeroVector) (#118504)
1 parent 5712202 commit b3d4a4f

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

src/coreclr/jit/lowerxarch.cpp

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9904,15 +9904,35 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
99049904
// because it will prevent other transforms that will be better for codegen.
99059905

99069906
LIR::Use use;
9907-
9908-
if ((oper == GT_XOR) && isEmbeddedBroadcastCompatible && BlockRange().TryGetUse(node, &use) &&
9909-
use.User()->OperIsVectorFusedMultiplyOp())
9907+
if (isEmbeddedBroadcastCompatible && BlockRange().TryGetUse(node, &use))
99109908
{
9911-
// xor is bitwise and the actual xor node might be a different base type
9912-
// from the FMA node, so we check if its negative zero using the FMA base
9913-
// type since that's what the end negation would end up using
9914-
var_types fmaSimdBaseType = use.User()->AsHWIntrinsic()->GetSimdBaseType();
9915-
isEmbeddedBroadcastCompatible = !containedOperand->IsVectorNegativeZero(fmaSimdBaseType);
9909+
if ((oper == GT_XOR) && use.User()->OperIsVectorFusedMultiplyOp())
9910+
{
9911+
// xor is bitwise and the actual xor node might be a different base type
9912+
// from the FMA node, so we check if its negative zero using the FMA base
9913+
// type since that's what the end negation would end up using
9914+
var_types fmaSimdBaseType = use.User()->AsHWIntrinsic()->GetSimdBaseType();
9915+
isEmbeddedBroadcastCompatible =
9916+
!containedOperand->IsVectorNegativeZero(fmaSimdBaseType);
9917+
}
9918+
else if (((oper == GT_AND) || (oper == GT_AND_NOT)) && use.User()->OperIsHWIntrinsic())
9919+
{
9920+
// For EQ/NE(AND(X, CnsVec), ZeroVector) we don't need to fold CnsVec into a contained
9921+
// broadcast operand - AND will be folded into TestZ anyway.
9922+
GenTreeHWIntrinsic* userHw = use.User()->AsHWIntrinsic();
9923+
NamedIntrinsic userId = userHw->GetHWIntrinsicId();
9924+
9925+
bool isEQ = (userId == NI_Vector128_op_Equality) ||
9926+
(userId == NI_Vector256_op_Equality) ||
9927+
(userId == NI_Vector512_op_Equality);
9928+
bool isNE = (userId == NI_Vector128_op_Inequality) ||
9929+
(userId == NI_Vector256_op_Inequality) ||
9930+
(userId == NI_Vector512_op_Inequality);
9931+
if ((isEQ || isNE) && (userHw->Op(1)->IsVectorZero() || userHw->Op(2)->IsVectorZero()))
9932+
{
9933+
isEmbeddedBroadcastCompatible = false;
9934+
}
9935+
}
99169936
}
99179937

99189938
if (isEmbeddedBroadcastCompatible)

0 commit comments

Comments
 (0)