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

Code before:
        regNumber divisorReg = REG_NA;
        if ((exSetFlags & ExceptionSetFlags::DivideByZeroException) != ExceptionSetFlags::None)
        {
            divisorReg = MakeOperandMultiUse(treeNode, divisor);
            GetEmitter()->emitIns(is64BitOp ? INS_i64_eqz : INS_i32_eqz);
            genJumpToThrowHlpBlk(SCK_DIV_BY_ZERO);
        }

        // (MinInt / -1) => ArithmeticException.
        GenTree*  dividend    = treeNode->gtGetOp1();
        regNumber dividendReg = REG_NA;
        if ((exSetFlags & ExceptionSetFlags::ArithmeticException) != ExceptionSetFlags::None)
        {
            // First, push "divisor == -1".
            if (divisorReg == REG_NA)
            {
                divisorReg = MakeOperandMultiUse(treeNode, divisor);
            }
            else
            {
                GetEmitter()->emitIns_I(INS_local_get, size, WasmRegToIndex(divisorReg));
            }
            GetEmitter()->emitIns_I(is64BitOp ? INS_i64_const : INS_i32_const, size, -1);
            GetEmitter()->emitIns(is64BitOp ? INS_i64_eq : INS_i32_eq);

            // Second, push "dividend == MinInt".
            dividendReg = MakeOperandMultiUse(treeNode, dividend);
            GetEmitter()->emitIns_I(is64BitOp ? INS_i64_const : INS_i32_const, size, is64BitOp ? INT64_MIN : INT32_MIN);
            GetEmitter()->emitIns(is64BitOp ? INS_i64_eq : INS_i32_eq);

            // Finally, do the and.
            GetEmitter()->emitIns(is64BitOp ? INS_i64_and : INS_i32_and);
            genJumpToThrowHlpBlk(SCK_ARITH_EXCPN);
        }

        if (dividendReg != REG_NA)
        {
            GetEmitter()->emitIns_I(INS_local_get, size, WasmRegToIndex(dividendReg));
        }
        if (divisorReg != REG_NA)
        {
            GetEmitter()->emitIns_I(INS_local_get, size, WasmRegToIndex(divisorReg));
        }
    }

    instruction ins;
    switch (PackOperAndType(treeNode->OperGet(), treeNode->TypeGet()))
    {
        case PackOperAndType(GT_DIV, TYP_INT):
            ins = INS_i32_div_s;
            break;

Review comment (suggestion):
At this point the wasm stack is
```
(divisor == -1)
divisor
dividend
```
So seems like the `MakeOperandMultiUse` will tee the `(divisor == -1)` value if the dividend is not something we can rematerialize.




Code after:
        regNumber divisorReg = REG_NA;
        if ((exSetFlags & ExceptionSetFlags::DivideByZeroException) != ExceptionSetFlags::None)
        {
            divisorReg = MakeOperandMultiUse(treeNode, divisor);
            GetEmitter()->emitIns(is64BitOp ? INS_i64_eqz : INS_i32_eqz);
            genJumpToThrowHlpBlk(SCK_DIV_BY_ZERO);
        }

        // (MinInt / -1) => ArithmeticException.
        if ((exSetFlags & ExceptionSetFlags::ArithmeticException) != ExceptionSetFlags::None)
        {
            // TODO-WASM: implement overflow checking.
        }

        if (divisorReg != REG_NA)
        {
            GetEmitter()->emitIns_I(INS_local_get, size, WasmRegToIndex(divisorReg));
        }
    }

    instruction ins;
    switch (PackOperAndType(treeNode->OperGet(), treeNode->TypeGet()))
    {
        case PackOperAndType(GT_DIV, TYP_INT):
            ins = INS_i32_div_s;
            break;
        case PackOperAndType(GT_DIV, TYP_LONG):
            ins = INS_i64_div_s;
            break;
        case PackOperAndType(GT_DIV, TYP_FLOAT):
            ins = INS_f32_div;
            break;
        case PackOperAndType(GT_DIV, TYP_DOUBLE):
            ins = INS_f64_div;
            break;

        case PackOperAndType(GT_UDIV, TYP_INT):
            ins = INS_i32_div_u;
            break;
        case PackOperAndType(GT_UDIV, TYP_LONG):
            ins = INS_i64_div_u;
            break;

        case PackOperAndType(GT_MOD, TYP_INT):
            ins = INS_i32_rem_s;
            break;
        case PackOperAndType(GT_MOD, TYP_LONG):
            ins = INS_i64_rem_s;
            break;

        case PackOperAndType(GT_UMOD, TYP_INT):