The current implementations of Mod(I|L)Node::Value are very conservative:
- if either input is bottom, it returns bottom
- only if both inputs are >= 0, the returned range is Type(Int|Long)::POS, otherwise the full range is returned (besides constants)
I suggest the following improvements, closely related to what the JVMS already mentions about the irem/lrem instructions:
- The result is either zero or has the same sign as the dividend
- The result's magnitude is always less than the magnitude of the divisor
- The result is always either equal to or closer to zero than the dividend
- These improvements work even if one input has type bottom.
There is an additional improvement, but I think it belongs to Identity instead:
- If the magnitude of the divisor is known to be greater than the magnitude of the dividend, the dividend is the result
- if either input is bottom, it returns bottom
- only if both inputs are >= 0, the returned range is Type(Int|Long)::POS, otherwise the full range is returned (besides constants)
I suggest the following improvements, closely related to what the JVMS already mentions about the irem/lrem instructions:
- The result is either zero or has the same sign as the dividend
- The result's magnitude is always less than the magnitude of the divisor
- The result is always either equal to or closer to zero than the dividend
- These improvements work even if one input has type bottom.
There is an additional improvement, but I think it belongs to Identity instead:
- If the magnitude of the divisor is known to be greater than the magnitude of the dividend, the dividend is the result