Closed
Description
Spotted while adding #114433 and #114431
In lowerarmarch.cpp
:
case NI_Sve_ConditionalSelect:
{
assert(intrin.numOperands == 3);
GenTree* op1 = intrin.op1;
GenTree* op2 = intrin.op2;
GenTree* op3 = intrin.op3;
// Handle op1
if (op1->IsVectorZero())
{
// When we are merging with zero, we can specialize
// and avoid instantiating the vector constant.
MakeSrcContained(node, op1);
}
// Handle op2
if (op2->OperIsHWIntrinsic() && !op2->IsEmbMaskOp())
{
The IsVectorZero()
check on Op1 will never trigger.
Consider:
var result2 = Sve.ConditionalSelect(Vector<int>.Zero, Sve.Add(op1, op2), op1);
[000005] ----------- arg0 \--* HWINTRINSIC simd16 int ConditionalSelect
[000007] ----------- +--* HWINTRINSIC mask int ConvertVectorToMask
[000006] ----------- | +--* HWINTRINSIC mask int CreateTrueMaskAll
[000000] ----------- | \--* CNS_VEC simd16<0x00000000, 0x00000000, 0x00000000, 0x00000000>
[000003] ----------- +--* HWINTRINSIC simd16 int Add
[000001] ----------- | +--* LCL_VAR simd16<System.Numerics.Vector`1> V00 arg0
[000002] ----------- | \--* LCL_VAR simd16<System.Numerics.Vector`1> V01 arg1
[000004] ----------- \--* LCL_VAR simd16<System.Numerics.Vector`1> V00 arg0
The VectorZero is converted to a mask when passed in as arg1 to conditionalselect.
I'm not sure if there are additional instances.
Ideally, I think we need a IsVectorOrMaskZero()
which takes into account mask/vector conversions.