Skip to content

Incorrect order of casts on constant folding #5303

Open
@jaehyun1ee

Description

@jaehyun1ee
extern void sink<T>(in T t);

control C(in bool b, in int<6> i6);
package P(C c);

control CImpl(in bool b, in int<6> i6) {
   apply {
      sink((b ? i6 : 3) * 9);
   }
}
P(CImpl()) main;

Consider the expression (b ? i6 : 3) * 9 in the above program. To type this expression, we should first insert casts to the first subexpression (b ? i6 : 3) into (b ? i6 : (int<6>) 3). Then we insert cast to the right operand of multiplication, such that the entire expression becomes (b ? i6 : (int<6>) 3) * ((int<6>) 9). This is how P4C works, as after all frontend passes, p4test gives:

sink<int<6>>((b ? i6 : 6s3) * 6s9);

However, when the operands are constants, compile-time evaluation works differently.

header h_t {
   bit<(false ? 6s3 : 11) * 9> f;
}

control C(h_t h);
package P(C c);

control CImpl(h_t h) { apply {} }
P(CImpl()) main;

According to the order of casts explained above, it should be evaluated as (false ? 6s3 : 6s11) * 6s9. This yields -27, as 99 overflows int<6>. But, after -0010-ConstantFolding_0_DoConstantFolding, the IR gives:

header h_t {
    bit<99> f;
}

It seems like constant folding applied a different order of evaluation.

Metadata

Metadata

Assignees

Labels

p4-specTopics related to the P4 specification (https://github.com/p4lang/p4-spec/).

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions