p4c
p4c copied to clipboard
Compiler Bug: cannot find allocation of a field in header
Compile the following P4 code under p4c 1.2.5.10 (SHA: cceb17da1 BUILD: Release) (current main HEAD).
p4c --target tofino2 --arch t2na my_simple_switch_tna.p4
#include <core.p4>
#if __TARGET_TOFINO__ == 3
#include <t3na.p4>
#elif __TARGET_TOFINO__ == 2
#include <t2na.p4>
#else
#include <tna.p4>
#endif
#include "common/headers.p4"
#include "common/util.p4"
const ether_type_t ETHERTYPE_PROBE = 16w0x88b5;
header probe_h {
bit<8> stage;
@padding bit<7> _pad1;
bit<9> port;
bit<24> qdepth;
}
struct metadata_t {
bit<24> qlen;
}
struct ingress_header_t {
ethernet_h ethernet;
probe_h probe;
ipv4_h ipv4;
}
// ---------------------------------------------------------------------------
// Ingress parser
// ---------------------------------------------------------------------------
parser SwitchIngressParser(
packet_in pkt,
out ingress_header_t hdr,
out metadata_t ig_md,
out ingress_intrinsic_metadata_t ig_intr_md) {
TofinoIngressParser() tofino_parser;
state start {
tofino_parser.apply(pkt, ig_intr_md);
transition parse_ethernet;
}
state parse_ethernet {
pkt.extract(hdr.ethernet);
transition select (hdr.ethernet.ether_type) {
ETHERTYPE_IPV4 : parse_ipv4;
ETHERTYPE_PROBE : parse_recir;
default : reject;
}
}
state parse_recir {
pkt.extract(hdr.probe);
transition accept;
}
state parse_ipv4 {
pkt.extract(hdr.ipv4);
transition accept;
}
}
control SwitchIngress(
inout ingress_header_t hdr,
inout metadata_t ig_md,
in ingress_intrinsic_metadata_t ig_intr_md,
in ingress_intrinsic_metadata_from_parser_t ig_intr_prsr_md,
inout ingress_intrinsic_metadata_for_deparser_t ig_intr_dprsr_md,
inout ingress_intrinsic_metadata_for_tm_t ig_intr_tm_md) {
Counter<bit<32>, bit<2>>(3, CounterType_t.PACKETS_AND_BYTES) counter;
const bit<32> sfc_ingress_port_idx_cnt = 32w512;
Register<bit<32>, PortId_t>(sfc_ingress_port_idx_cnt) sfc_qdepth;
RegisterAction<bit<32>, PortId_t, void>(sfc_qdepth) qlen_write = {
void apply(inout bit<32> value) {
value = (bit<32>)hdr.probe.qdepth;
}
};
RegisterAction<bit<32>, PortId_t, bit<24>>(sfc_qdepth) qlen_read = {
void apply(inout bit<32> value, out bit<24> read_value) {
read_value = (bit<24>)value;
}
};
action recir_recv() {
counter.count(0);
qlen_write.execute(hdr.probe.port);
ig_intr_dprsr_md.drop_ctl = 0x1;
}
action recir_send(PortId_t port) {
counter.count(1);
ig_intr_tm_md.ucast_egress_port = port;
}
action nop() {
counter.count(2);
}
table recir_pkt {
key = {
hdr.ethernet.ether_type : exact;
hdr.probe.stage : exact;
}
actions = {
recir_send;
recir_recv;
nop;
}
size = 2;
const default_action = nop;
}
action hit(PortId_t port) {
ig_intr_tm_md.ucast_egress_port = port;
ig_md.qlen = qlen_read.execute(port);
}
action miss() {}
table forward {
key = {
hdr.ethernet.dst_addr : ternary;
}
actions = {
hit;
miss;
}
size = 1024;
const default_action = miss;
}
apply {
recir_pkt.apply();
forward.apply();
}
}
// ---------------------------------------------------------------------------
// Ingress Deparser
// ---------------------------------------------------------------------------
control SwitchIngressDeparser(
packet_out pkt,
inout ingress_header_t hdr,
in metadata_t ig_md,
in ingress_intrinsic_metadata_for_deparser_t ig_intr_dprsr_md) {
apply {
pkt.emit(hdr);
}
}
Pipeline(SwitchIngressParser(),
SwitchIngress(),
SwitchIngressDeparser(),
EmptyEgressParser(),
EmptyEgress(),
EmptyEgressDeparser()) pipe;
Switch(pipe) main;
The compiler output is:
In file: /home/yhr/p4c/backends/tofino/bf-p4c/mau/ixbar_realign.cpp:63
Compiler Bug: cannot find allocation of 19:ingress::hdr.probe.qdepth<24> ^0 ^bit[0..47] deparsed exact_containers mocha MW0(0..23), read in forward_0 (SwitchIngress.forward)
Internal compiler error. Please submit a bug report with your code.
However, p4c can compile this code successfully using tofino target and tna arch.
UPD: Added a minimal reproduction.