Repository: dotnet/runtime
File: src/coreclr/jit/hwintrinsicarm64.cpp (C++)

Code before:
        }

        case NI_Sve2_AddSaturate:
        {
            assert(sig->numArgs == 2);
            assert(retType != TYP_VOID);

            CORINFO_ARG_LIST_HANDLE arg1     = sig->args;
            CORINFO_ARG_LIST_HANDLE arg2     = info.compCompHnd->getArgNext(arg1);
            CORINFO_CLASS_HANDLE    argClass = NO_CLASS_HANDLE;

            var_types   argType1       = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass)));
            CorInfoType op1BaseJitType = getBaseJitTypeOfSIMDType(argClass);
            var_types   argType2       = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
            CorInfoType op2BaseJitType = getBaseJitTypeOfSIMDType(argClass);
            assert(JitType2PreciseVarType(op1BaseJitType) == simdBaseType);

            op2 = impPopStack().val;
            op1 = impPopStack().val;

            // NI_Sve2_AddSaturate has an OptionalEmbeddedMaskOperation flag so that it could fallback to the
            // unpredicated AddSaturate instruction, while NI_Sve2_AddSaturateWithSigned/UnsignedAddend are
            // always predicated. Therefore, separate HWIntrinsic IDs are used here instead of emitting the
            // corresponding instructions in the codegen with the same HWIntrinsic.

            if (op1BaseJitType != op2BaseJitType)
            {
                if (varTypeIsUnsigned(simdBaseType))
                {
                    intrinsic = NI_Sve2_AddSaturateWithSignedAddend;
                }
                else
                {
                    intrinsic = NI_Sve2_AddSaturateWithUnsignedAddend;
                }
            }

            retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseType, simdSize);
            break;
        }

        default:
        {
            return nullptr;
        }
    }

    if (isMinMaxIntrinsic)
    {
        assert(sig->numArgs == 2);
        assert(retNode == nullptr);

Review comment (suggestion):
It's unclear why this is needed instead of using the `auxiliaryJitType` field, which exists to allow such special differentiations.

We tend to prefer fewer IDs where we can as it simplifies the handling and matching of patterns elsewhere.

Code after:
            break;
        }

        case NI_Sve2_AddSaturate:
        {
            assert(sig->numArgs == 2);
            assert(retType != TYP_VOID);

            CORINFO_ARG_LIST_HANDLE arg1     = sig->args;
            CORINFO_ARG_LIST_HANDLE arg2     = info.compCompHnd->getArgNext(arg1);
            CORINFO_CLASS_HANDLE    argClass = NO_CLASS_HANDLE;

            var_types   argType1       = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass)));
            CorInfoType op1BaseJitType = getBaseJitTypeOfSIMDType(argClass);
            var_types   argType2       = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
            CorInfoType op2BaseJitType = getBaseJitTypeOfSIMDType(argClass);
            assert(JitType2PreciseVarType(op1BaseJitType) == simdBaseType);

            op2 = impPopStack().val;
            op1 = impPopStack().val;

            retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseType, simdSize);
            retNode->AsHWIntrinsic()->SetSimdBaseType(simdBaseType);
            retNode->AsHWIntrinsic()->SetAuxiliaryJitType(op2BaseJitType);
            break;
        }

        default:
        {
            return nullptr;
        }
    }

    if (isMinMaxIntrinsic)
    {
        assert(sig->numArgs == 2);
        assert(retNode == nullptr);

        if (isNative && BlockNonDeterministicIntrinsics(mustExpand))
        {
            return nullptr;
        }

        op2 = impSIMDPopStack();
        op1 = impSIMDPopStack();

        if (isNative)
        {
            assert(!isMagnitude && !isNumber);
            retNode = gtNewSimdMinMaxNativeNode(retType, op1, op2, simdBaseType, simdSize, isMax);
        }