Division with bit<w> arguments
p4c permits division and modulo between bitint values. I think this is probably the spec being too restrictive rather than p4c being too permissive.
These operations do not have an unambiguous definition for negative values.
And what about the fact that it can be used with bit<_> too?
Some targets may reject some run-time divisions statically (but may accept, e.g., divisions by constants). But otherwise I think it's fine.
I just came across this today too. Maybe in the next spec meeting just get a vote up or down to allow them for bit<...>. We could even add saying some P4 target architectures may optionally support runtime division and mod (just like the section about saturating arithmetic). If I get time over the weekend, I will submit a pull request so we can just vote on it.
I agree that whether or not to allow runtime division depends on the target. And in the case of divided by zero, it should return an unspecified value rather than a runtime error. I think every non-zero division and mod has a well-defined result (dividing by the absolute value and rounding down). But it's okay if you have a different opinion.
In addition to division by zero, in 2's complement arithmetic, dividing the smallest value by -1 yields an unrepresentable value.
As of today, the spec does not define the division of the fixed-width types. It is only defined for arbitrary precision integers (type int), meaning that it can only be performed at runtime. Also, the operations on negative values are explicitly prohibited (which takes care of the problem raised by @blp )
If the compiler accepts expressions that involve division of fixed-width values (i.e. bit<N> or int<N>), it's either an unpublished extension of the spec or a bug (depending on the perspective).
Note, that this is different, compared to multiplication, where the result is clearly specified, but backends are allowed to impose their own restrictions.
In reality, this is should not limit any target in any way, because the specific architecture can always provide an extern function that will express the division operation available on that platform. That way one does not have to worry about all kinds of issues, related to exceptions, handling of signed values, etc -- they can be implemented exactly as one wants.
Once several platforms implement their version of division and a question "shouldn't we standardize these by finding the common ground and adopting the best practices" will appear, then a specific discussion can be had and we can decide to promote a specific behavior to a standard division or modulo operation. At that time it might also be prudent to make sure that the frontend uses relaxed checking, leaving more of the decisions (e.g. whether variable divisors are allowed) to the backends. But no earlier than that!
Note also, that even after standardization, the platforms can still have their own extern functions to express the extended functionality that might not be included into the spec.
C mandates that integer division rounds toward zero, so I'd be surprised to see other behavior if this gets standardized at all.
@blp -- if everyone ends up implementing things the same way, it will be very easy to reach an agreement :) But let's see these extern-based implementations first, so that we can have a concrete set of details to discuss.
In the interest of tidying up the set of active issues on the P4 specification repository, I'm marking this as "stalled" and closing it. Of course, we can always re-open it in the future if there is interest in resurrecting it.