p4-spec icon indicating copy to clipboard operation
p4-spec copied to clipboard

Comparisons of list expressions

Open MollyDream opened this issue 4 years ago • 5 comments

The specification states that structure-valued expressions can be used in comparisons (== or !=) in section 8.12 ("Structure-valued expressions can be used... in comparisons..."), but it does not say so for list expressions in section 8.11. Since those two kinds of expressions are very similar, this inconsistency here seems weird and probably needs some clarification.

Similarly, it probably should be clarified in section 8.10 whether tuples support comparisons (== or !=).

Lastly, the example of structure-valued expressions used in comparisons in 8.12 is perhaps a bad example ( bool b = s == (S) { a = 1, b = 2 } ) since that essentially compares two structures instead of two structure-valued expressions.

Example:

struct S {
    bit<4> a;
}
bool x = {a = 1} == {a = 1};
bool y = {1} == {1};

Based on the spec the first comparison is allowed, but the second is not.

MollyDream avatar Aug 27 '21 17:08 MollyDream

I have tested all types of comparisons in BMV2:

struct S {
    bit<32> a;
    bit<32> b;
}

control compute(inout hdr h) {
    apply {
        // bool b1_ = { a = 1, b = 2 } == { a = 1, b = 2 }; // BMV2: Compiler Bug: Could not find type for <Constant>(11032) 1
        bool b1 = { a = 8w1, b = 8w2 } == { a = 8w1, b = 8w2 };
        bool b2 = (S) { a = 1, b = 2 } == { a = 1, b = 2 };
        // bool b3 = { a = 1, b = 2 } == (S) { a = 1, b = 2 }; // BMV2: error: ==: Cannot unify struct S to unknown struct
        bool b4 = (S) { a = 1, b = 2 } == (S) { a = 1, b = 2 };
 
        bool b5 = { 1, 2 } == { 1, 2 };

        S s1 = { a = 1, b = 2 };
        S s2 = { a = 1, b = 2 };
        bool b6 = s1 == { a = 1, b = 2 };
        bool b7 = s1 == (S) { a = 1, b = 2 };
        bool b8 = s1 == s2;

        tuple<bit<8>, bit<8>> t1 = {1, 2};
        tuple<bit<8>, bit<8>> t2 = {1, 2};
        bool b9 = t1 == { 1, 2 };
        bool b10 = t1 == t2;

You can see that the comparisons between structure-valued expressions, list expressions, structs, and tuples are all allowed, except two cases. For b1_, it seems to be some other issue with the compiler since b1 works well. For b3, it seems weird that BMV2 cannot infer the type of the LHS. Given that b2 works well, and there is no rule in the spec enforcing the direction of type inference, I think it is more likely a problem with the compiler. Overall, this experiment seems to suggest that (in)equality comparisons should be allowed in structure-valued expressions, list expressions, structs, and tuples.

MollyDream avatar Dec 01 '21 16:12 MollyDream

If you find compiler bugs it would be very useful to file them as issues in the compiler repository.

mihaibudiu avatar Dec 01 '21 18:12 mihaibudiu

@mbudiu-vmw I would be happy to file them. Maybe after we finish changing the spec so that I can confirm that it is actually a compiler problem.

MollyDream avatar Dec 01 '21 19:12 MollyDream

Ok, so we'll count on you to keep track of the compiler bugs related to these fixes. There is a lot of information in your comments; ideally each different bug should eventually be filed as a separate issue.

mihaibudiu avatar Dec 01 '21 19:12 mihaibudiu

Without introducing "cast" and “types" (#953), one way to generalize this can be that

  • A list expression can be compared with a list expression, a tuple, a struct, or a header for equality (==) or inequality (!=)
  • A structure-valued expression can be compared with a structure-valued expression, a struct, or a header for equality (==) or inequality (!=)

But there is one corner case this description cannot handle: a list expression can also be compared with a structure-valued expression when typRef is explicit.

bool b11 = (S) { a = 1, b = 2 } == {1, 2}; // Good
// bool b12 = { a = 1, b = 2 } == {1, 2};  // Rejected by the BMV2 compiler

It seems reasonable for b11 to work since with (S), the LHS gain the type of S and then the RHS is cast to the same type. But this means that in order to explain this well, we probably need to introduce new types for the list and structure-valued expressions and new casts to the spec, which may be undesirable.

MollyDream avatar Dec 01 '21 19:12 MollyDream

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.

jnfoster avatar Nov 11 '23 13:11 jnfoster