Description
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.