diff --git a/backends/bmv2/pna_nic/midend.cpp b/backends/bmv2/pna_nic/midend.cpp index 4c9073ca438..f37525da0e3 100644 --- a/backends/bmv2/pna_nic/midend.cpp +++ b/backends/bmv2/pna_nic/midend.cpp @@ -85,6 +85,8 @@ PnaNicMidEnd::PnaNicMidEnd(CompilerOptions &options, std::ostream *outStream) : PortableMidEnd(options) { auto convertEnums = new P4::ConvertEnums(&typeMap, new PnaEnumOn32Bits("pna.p4"_cs)); auto evaluator = new P4::EvaluatorPass(&refMap, &typeMap); + auto *strengthReductionPolicy = new P4::StrengthReductionPolicy(); + strengthReductionPolicy->enablePlusSliceToShiftTransform = true; P4::LocalCopyPropPolicyCallbackFn policy = [=](const Context *, const IR::Expression *e, const DeclarationLookup *refMap) -> bool { auto mce = e->to(); @@ -116,12 +118,12 @@ PnaNicMidEnd::PnaNicMidEnd(CompilerOptions &options, std::ostream *outStream) new P4::SimplifyKey(&typeMap, new P4::OrPolicy(new P4::IsValid(&typeMap), new P4::IsMask())), new P4::ConstantFolding(&typeMap), - new P4::StrengthReduction(&typeMap), + new P4::StrengthReduction(&typeMap, strengthReductionPolicy), new P4::SimplifySelectCases(&typeMap, true), // require constant keysets new P4::ExpandLookahead(&typeMap), new P4::ExpandEmit(&typeMap), new P4::SimplifyParsers(), - new P4::StrengthReduction(&typeMap), + new P4::StrengthReduction(&typeMap, strengthReductionPolicy), new P4::EliminateTuples(&typeMap), new P4::SimplifyComparisons(&typeMap), new P4::CopyStructures(&typeMap), @@ -135,8 +137,8 @@ PnaNicMidEnd::PnaNicMidEnd(CompilerOptions &options, std::ostream *outStream) new P4::MoveDeclarations(), // more may have been introduced new P4::ConstantFolding(&typeMap), new P4::LocalCopyPropagation(&typeMap, nullptr, policy), - new PassRepeated( - {new P4::ConstantFolding(&typeMap), new P4::StrengthReduction(&typeMap)}), + new PassRepeated({new P4::ConstantFolding(&typeMap), + new P4::StrengthReduction(&typeMap, strengthReductionPolicy)}), new P4::MoveDeclarations(), new P4::ValidateTableProperties({"pna_implementation"_cs, "pna_direct_counter"_cs, "pna_direct_meter"_cs, "pna_idle_timeout"_cs, diff --git a/backends/bmv2/psa_switch/midend.cpp b/backends/bmv2/psa_switch/midend.cpp index 859f03e38e5..920f670af4e 100644 --- a/backends/bmv2/psa_switch/midend.cpp +++ b/backends/bmv2/psa_switch/midend.cpp @@ -84,6 +84,8 @@ PsaSwitchMidEnd::PsaSwitchMidEnd(CompilerOptions &options, std::ostream *outStre : PortableMidEnd(options) { auto convertEnums = new P4::ConvertEnums(&typeMap, new PsaEnumOn32Bits("psa.p4"_cs)); auto evaluator = new P4::EvaluatorPass(&refMap, &typeMap); + auto *strengthReductionPolicy = new P4::StrengthReductionPolicy(); + strengthReductionPolicy->enablePlusSliceToShiftTransform = true; P4::LocalCopyPropPolicyCallbackFn policy = [=](const Context *, const IR::Expression *e, const DeclarationLookup *refMap) -> bool { auto mce = e->to(); @@ -116,12 +118,12 @@ PsaSwitchMidEnd::PsaSwitchMidEnd(CompilerOptions &options, std::ostream *outStre new P4::SimplifyKey(&typeMap, new P4::OrPolicy(new P4::IsValid(&typeMap), new P4::IsMask())), new P4::ConstantFolding(&typeMap), - new P4::StrengthReduction(&typeMap), + new P4::StrengthReduction(&typeMap, strengthReductionPolicy), new P4::SimplifySelectCases(&typeMap, true), // require constant keysets new P4::ExpandLookahead(&typeMap), new P4::ExpandEmit(&typeMap), new P4::SimplifyParsers(), - new P4::StrengthReduction(&typeMap), + new P4::StrengthReduction(&typeMap, strengthReductionPolicy), new P4::EliminateTuples(&typeMap), new P4::SimplifyComparisons(&typeMap), new P4::CopyStructures(&typeMap), @@ -138,7 +140,7 @@ PsaSwitchMidEnd::PsaSwitchMidEnd(CompilerOptions &options, std::ostream *outStre new P4::LocalCopyPropagation(&typeMap, nullptr, policy), new PassRepeated({ new P4::ConstantFolding(&typeMap), - new P4::StrengthReduction(&typeMap), + new P4::StrengthReduction(&typeMap, strengthReductionPolicy), }), new P4::MoveDeclarations(), new P4::ValidateTableProperties({ diff --git a/backends/bmv2/simple_switch/midend.cpp b/backends/bmv2/simple_switch/midend.cpp index 85d9f2b408c..cf90c6be554 100644 --- a/backends/bmv2/simple_switch/midend.cpp +++ b/backends/bmv2/simple_switch/midend.cpp @@ -62,6 +62,8 @@ using namespace P4::literals; SimpleSwitchMidEnd::SimpleSwitchMidEnd(CompilerOptions &options, std::ostream *outStream) : MidEnd(options) { auto *evaluator = new P4::EvaluatorPass(&refMap, &typeMap); + auto *strengthReductionPolicy = new P4::StrengthReductionPolicy(); + strengthReductionPolicy->enablePlusSliceToShiftTransform = true; if (!BMV2::SimpleSwitchContext::get().options().loadIRFromJson) { auto *convertEnums = new P4::ConvertEnums(&typeMap, new EnumOn32Bits("v1model.p4"_cs)); ParserConfig config; @@ -83,12 +85,12 @@ SimpleSwitchMidEnd::SimpleSwitchMidEnd(CompilerOptions &options, std::ostream *o new P4::SimplifyKey(&typeMap, new P4::OrPolicy(new P4::IsValid(&typeMap), new P4::IsMask())), new P4::ConstantFolding(&typeMap), - new P4::StrengthReduction(&typeMap), + new P4::StrengthReduction(&typeMap, strengthReductionPolicy), new P4::SimplifySelectCases(&typeMap, true), // require constant keysets new P4::ExpandLookahead(&typeMap), new P4::ExpandEmit(&typeMap), new P4::SimplifyParsers(), - new P4::StrengthReduction(&typeMap), + new P4::StrengthReduction(&typeMap, strengthReductionPolicy), new P4::EliminateTuples(&typeMap), new P4::SimplifyComparisons(&typeMap), new P4::CopyStructures(&typeMap), @@ -103,7 +105,7 @@ SimpleSwitchMidEnd::SimpleSwitchMidEnd(CompilerOptions &options, std::ostream *o new P4::LocalCopyPropagation(&typeMap), new PassRepeated({ new P4::ConstantFolding(&typeMap), - new P4::StrengthReduction(&typeMap), + new P4::StrengthReduction(&typeMap, strengthReductionPolicy), }), new P4::SimplifyKey(&typeMap, new P4::OrPolicy(new P4::IsValid(&typeMap), new P4::IsMask())), diff --git a/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2MetadataXfail.cmake b/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2MetadataXfail.cmake index 79c5700c625..a065e284305 100644 --- a/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2MetadataXfail.cmake +++ b/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2MetadataXfail.cmake @@ -32,6 +32,7 @@ p4tools_add_xfail_reason( "testgen-p4c-bmv2-metadata" "with type .* is not a Constant" # Most of these come from varbits + issue5558-bmv2.p4 # Variable-offset slices are not supported by P4Testgen. ) p4tools_add_xfail_reason( diff --git a/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2PTFXfail.cmake b/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2PTFXfail.cmake index ed38763ef31..3c5b4000b94 100644 --- a/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2PTFXfail.cmake +++ b/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2PTFXfail.cmake @@ -89,6 +89,12 @@ p4tools_add_xfail_reason( # These are failures in P4Testgen that need to be fixed. #################################################################################################### +p4tools_add_xfail_reason( + "testgen-p4c-bmv2-ptf" + "with type .* is not a Constant" + issue5558-bmv2.p4 # Variable-offset slices are not supported by P4Testgen. +) + p4tools_add_xfail_reason( "testgen-p4c-bmv2-ptf" "Computations are not supported in update_checksum" diff --git a/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2ProtobufIrXfail.cmake b/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2ProtobufIrXfail.cmake index 92bf5251fa8..e63ab1d4e6d 100644 --- a/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2ProtobufIrXfail.cmake +++ b/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2ProtobufIrXfail.cmake @@ -42,6 +42,7 @@ p4tools_add_xfail_reason( "testgen-p4c-bmv2-protobuf-ir" "with type .* is not a Constant" # Most of these come from varbits + issue5558-bmv2.p4 # Variable-offset slices are not supported by P4Testgen. ) p4tools_add_xfail_reason( diff --git a/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2STFXfail.cmake b/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2STFXfail.cmake index fdddc32b86a..6b9c52e6d91 100644 --- a/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2STFXfail.cmake +++ b/backends/p4tools/modules/testgen/targets/bmv2/test/BMV2STFXfail.cmake @@ -70,6 +70,12 @@ p4tools_add_xfail_reason( # These are failures in P4Testgen that need to be fixed. #################################################################################################### +p4tools_add_xfail_reason( + "testgen-p4c-bmv2-stf" + "with type .* is not a Constant" + issue5558-bmv2.p4 # Variable-offset slices are not supported by P4Testgen. +) + p4tools_add_xfail_reason( "testgen-p4c-bmv2-stf" "Cast failed" diff --git a/frontends/p4/strengthReduction.cpp b/frontends/p4/strengthReduction.cpp index 2a038ee3ab7..b9a0e241c58 100644 --- a/frontends/p4/strengthReduction.cpp +++ b/frontends/p4/strengthReduction.cpp @@ -503,6 +503,17 @@ const IR::Node *DoStrengthReduction::postorder(IR::PlusSlice *expr) { auto *rv = new IR::Slice(expr->srcInfo, expr->e0, expr->getH(), expr->getL()); return postorder(rv); } + if (policy->enablePlusSliceToShiftTransform) { + if (isWrite()) return expr; + + auto *width = expr->e2->checkedTo(); + if (width->value == 0) return expr; + + const IR::Expression *source = expr->e0; + if (!source->type->is()) return expr; + auto *shift = new IR::Shr(expr->srcInfo, source->type, source, expr->e1); + return new IR::Slice(expr->srcInfo, shift, width->asInt() - 1, 0); + } if (auto sh = expr->e0->to()) { if (!sh->left->type->is()) return expr; if (sh->left->type->to()->isSigned) return expr; diff --git a/frontends/p4/strengthReduction.h b/frontends/p4/strengthReduction.h index 04264b1d9a0..cfa23b68005 100644 --- a/frontends/p4/strengthReduction.h +++ b/frontends/p4/strengthReduction.h @@ -22,9 +22,11 @@ class StrengthReductionPolicy { public: StrengthReductionPolicy() {} StrengthReductionPolicy(bool enableSubConstToAddTransform, - bool enableNarrowingCastToSliceTransform) + bool enableNarrowingCastToSliceTransform, + bool enablePlusSliceToShiftTransform = false) : enableSubConstToAddTransform(enableSubConstToAddTransform), - enableNarrowingCastToSliceTransform(enableNarrowingCastToSliceTransform) {} + enableNarrowingCastToSliceTransform(enableNarrowingCastToSliceTransform), + enablePlusSliceToShiftTransform(enablePlusSliceToShiftTransform) {} /// Enable the subtract constant to add negative constant transform. /// Replaces `a - constant` with `a + (-constant)`. @@ -33,6 +35,10 @@ class StrengthReductionPolicy { /// Replace narrowing casts with slices. /// i.e. replaces (bit)(expr) with expr[n-1:0] when n is smaller than the width of expr. bool enableNarrowingCastToSliceTransform = false; + + /// Replace slices with a variable offset with a shift followed by a constant slice. + /// i.e. replaces expr[offset+:width] with (expr >> offset)[width-1:0]. + bool enablePlusSliceToShiftTransform = false; }; /** Implements a pass that replaces expensive arithmetic and boolean @@ -52,7 +58,7 @@ class StrengthReductionPolicy { * - division and modulus by `0` * */ -class DoStrengthReduction final : public Transform { +class DoStrengthReduction final : public Transform, P4WriteContext { protected: TypeMap *typeMap = nullptr; StrengthReductionPolicy *policy; diff --git a/test/gtest/strength_reduction.cpp b/test/gtest/strength_reduction.cpp index 9b97f47f540..278958b5659 100644 --- a/test/gtest/strength_reduction.cpp +++ b/test/gtest/strength_reduction.cpp @@ -76,9 +76,11 @@ struct GTestStrengthReductionPolicy : public P4::FrontEndPolicy { P4::StrengthReductionPolicy *getStrengthReductionPolicy() const override { return policy_; } GTestStrengthReductionPolicy(bool enableSubConstToAddTransform = true, - bool enableCastToSliceTransform = false) { + bool enableCastToSliceTransform = false, + bool enablePlusSliceToShiftTransform = false) { policy_ = new P4::StrengthReductionPolicy(enableSubConstToAddTransform, - enableCastToSliceTransform); + enableCastToSliceTransform, + enablePlusSliceToShiftTransform); } private: @@ -146,4 +148,63 @@ TEST_F(StrengthReductionTest, EnableNarrowingCastToSliceTransform) { EXPECT_FALSE(program_string.find(value2) == std::string::npos); } +TEST_F(StrengthReductionTest, DefaultDisablePlusSliceToShiftTransform) { + auto test = createStrengthReductionTestCase( + P4_SOURCE(R"(headers.h.f4 = headers.h.f1[headers.h.f2+:16];)")); + + Util::SourceCodeBuilder builder; + ToP4 top4(builder, false); + test->program->apply(top4); + + std::string program_string = builder.toString(); + EXPECT_NE(program_string.find("headers.h.f1[headers.h.f2+:16]"), std::string::npos); + EXPECT_EQ(program_string.find("(headers.h.f1 >> headers.h.f2)[15:0]"), std::string::npos); +} + +TEST_F(StrengthReductionTest, EnablePlusSliceToShiftTransform) { + GTestStrengthReductionPolicy policy(true, false, true); + auto test = createStrengthReductionTestCase( + P4_SOURCE(R"(headers.h.f4 = headers.h.f1[headers.h.f2+:16];)"), &policy); + + Util::SourceCodeBuilder builder; + ToP4 top4(builder, false); + test->program->apply(top4); + + std::string program_string = builder.toString(); + EXPECT_EQ(program_string.find("headers.h.f1[headers.h.f2+:16]"), std::string::npos); + EXPECT_NE(program_string.find("(headers.h.f1 >> headers.h.f2)[15:0]"), std::string::npos); +} + +TEST_F(StrengthReductionTest, PreservePlusSliceToShiftTransformOnWrite) { + GTestStrengthReductionPolicy policy(true, false, true); + auto test = createStrengthReductionTestCase( + P4_SOURCE(R"(headers.h.f1[headers.h.f2+:16] = headers.h.f4;)"), &policy); + + Util::SourceCodeBuilder builder; + ToP4 top4(builder, false); + test->program->apply(top4); + + std::string program_string = builder.toString(); + EXPECT_NE(program_string.find("headers.h.f1[headers.h.f2+:16] = headers.h.f4"), + std::string::npos); +} + +TEST_F(StrengthReductionTest, EnablePlusSliceToShiftTransformOnSignedSource) { + GTestStrengthReductionPolicy policy(true, false, true); + auto test = createStrengthReductionTestCase(P4_SOURCE(R"( + int<32> signedValue = -1; + headers.h.f4 = signedValue[headers.h.f2+:16]; + )"), + &policy); + + Util::SourceCodeBuilder builder; + ToP4 top4(builder, false); + test->program->apply(top4); + + std::string program_string = builder.toString(); + EXPECT_EQ(program_string.find("[headers.h.f2+:16]"), std::string::npos); + EXPECT_EQ(program_string.find("(bit<32>)signedValue"), std::string::npos); + EXPECT_NE(program_string.find(" >> headers.h.f2)[15:0]"), std::string::npos); +} + } // namespace P4::Test diff --git a/testdata/p4_16_samples/issue5558-bmv2.p4 b/testdata/p4_16_samples/issue5558-bmv2.p4 new file mode 100644 index 00000000000..6e3e954d3bc --- /dev/null +++ b/testdata/p4_16_samples/issue5558-bmv2.p4 @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2026 The P4 Language Consortium + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +header Hdr { + bit<8> a; +} + +struct Headers { + Hdr op; +} + +struct Meta {} + +parser p(packet_in b, out Headers h, inout Meta m, inout standard_metadata_t sm) { + state start { + transition accept; + } +} + +control vrfy(inout Headers h, inout Meta m) { apply {} } +control update(inout Headers h, inout Meta m) { apply {} } + +control ingress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { + apply { + bit<8> x = 0x00; + h.op.a[3:0] = x[h.op.a+:4]; + } +} + +control egress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { apply {} } + +control deparser(packet_out b, in Headers h) { + apply { + b.emit(h.op); + } +} + +V1Switch(p(), vrfy(), ingress(), egress(), update(), deparser()) main; diff --git a/testdata/p4_16_samples_outputs/issue5558-bmv2-first.p4 b/testdata/p4_16_samples_outputs/issue5558-bmv2-first.p4 new file mode 100644 index 00000000000..ad982320f7b --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue5558-bmv2-first.p4 @@ -0,0 +1,51 @@ +#include + +#define V1MODEL_VERSION 20180101 +#include + +header Hdr { + bit<8> a; +} + +struct Headers { + Hdr op; +} + +struct Meta { +} + +parser p(packet_in b, out Headers h, inout Meta m, inout standard_metadata_t sm) { + state start { + transition accept; + } +} + +control vrfy(inout Headers h, inout Meta m) { + apply { + } +} + +control update(inout Headers h, inout Meta m) { + apply { + } +} + +control ingress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { + apply { + bit<8> x = 8w0x0; + h.op.a[3:0] = x[h.op.a+:4]; + } +} + +control egress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { + apply { + } +} + +control deparser(packet_out b, in Headers h) { + apply { + b.emit(h.op); + } +} + +V1Switch(p(), vrfy(), ingress(), egress(), update(), deparser()) main; diff --git a/testdata/p4_16_samples_outputs/issue5558-bmv2-frontend.p4 b/testdata/p4_16_samples_outputs/issue5558-bmv2-frontend.p4 new file mode 100644 index 00000000000..dc868a63042 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue5558-bmv2-frontend.p4 @@ -0,0 +1,52 @@ +#include + +#define V1MODEL_VERSION 20180101 +#include + +header Hdr { + bit<8> a; +} + +struct Headers { + Hdr op; +} + +struct Meta { +} + +parser p(packet_in b, out Headers h, inout Meta m, inout standard_metadata_t sm) { + state start { + transition accept; + } +} + +control vrfy(inout Headers h, inout Meta m) { + apply { + } +} + +control update(inout Headers h, inout Meta m) { + apply { + } +} + +control ingress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { + @name("ingress.x") bit<8> x_0; + apply { + x_0 = 8w0x0; + h.op.a[3:0] = x_0[h.op.a+:4]; + } +} + +control egress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { + apply { + } +} + +control deparser(packet_out b, in Headers h) { + apply { + b.emit(h.op); + } +} + +V1Switch(p(), vrfy(), ingress(), egress(), update(), deparser()) main; diff --git a/testdata/p4_16_samples_outputs/issue5558-bmv2-midend.p4 b/testdata/p4_16_samples_outputs/issue5558-bmv2-midend.p4 new file mode 100644 index 00000000000..03dac4b4238 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue5558-bmv2-midend.p4 @@ -0,0 +1,59 @@ +#include + +#define V1MODEL_VERSION 20180101 +#include + +header Hdr { + bit<8> a; +} + +struct Headers { + Hdr op; +} + +struct Meta { +} + +parser p(packet_in b, out Headers h, inout Meta m, inout standard_metadata_t sm) { + state start { + transition accept; + } +} + +control vrfy(inout Headers h, inout Meta m) { + apply { + } +} + +control update(inout Headers h, inout Meta m) { + apply { + } +} + +control ingress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { + @hidden action issue5558bmv2l32() { + h.op.a[3:0] = 8w0x0[h.op.a+:4]; + } + @hidden table tbl_issue5558bmv2l32 { + actions = { + issue5558bmv2l32(); + } + const default_action = issue5558bmv2l32(); + } + apply { + tbl_issue5558bmv2l32.apply(); + } +} + +control egress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { + apply { + } +} + +control deparser(packet_out b, in Headers h) { + apply { + b.emit(h.op); + } +} + +V1Switch(p(), vrfy(), ingress(), egress(), update(), deparser()) main; diff --git a/testdata/p4_16_samples_outputs/issue5558-bmv2.p4 b/testdata/p4_16_samples_outputs/issue5558-bmv2.p4 new file mode 100644 index 00000000000..97c90edbd75 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue5558-bmv2.p4 @@ -0,0 +1,51 @@ +#include + +#define V1MODEL_VERSION 20180101 +#include + +header Hdr { + bit<8> a; +} + +struct Headers { + Hdr op; +} + +struct Meta { +} + +parser p(packet_in b, out Headers h, inout Meta m, inout standard_metadata_t sm) { + state start { + transition accept; + } +} + +control vrfy(inout Headers h, inout Meta m) { + apply { + } +} + +control update(inout Headers h, inout Meta m) { + apply { + } +} + +control ingress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { + apply { + bit<8> x = 0x0; + h.op.a[3:0] = x[h.op.a+:4]; + } +} + +control egress(inout Headers h, inout Meta m, inout standard_metadata_t sm) { + apply { + } +} + +control deparser(packet_out b, in Headers h) { + apply { + b.emit(h.op); + } +} + +V1Switch(p(), vrfy(), ingress(), egress(), update(), deparser()) main; diff --git a/testdata/p4_16_samples_outputs/issue5558-bmv2.p4-stderr b/testdata/p4_16_samples_outputs/issue5558-bmv2.p4-stderr new file mode 100644 index 00000000000..e69de29bb2d diff --git a/testdata/p4_16_samples_outputs/issue5558-bmv2.p4.entries.txtpb b/testdata/p4_16_samples_outputs/issue5558-bmv2.p4.entries.txtpb new file mode 100644 index 00000000000..5cb9652623a --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue5558-bmv2.p4.entries.txtpb @@ -0,0 +1,3 @@ +# proto-file: p4/v1/p4runtime.proto +# proto-message: p4.v1.WriteRequest + diff --git a/testdata/p4_16_samples_outputs/issue5558-bmv2.p4.p4info.txtpb b/testdata/p4_16_samples_outputs/issue5558-bmv2.p4.p4info.txtpb new file mode 100644 index 00000000000..fdf16790b91 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue5558-bmv2.p4.p4info.txtpb @@ -0,0 +1,6 @@ +# proto-file: p4/config/v1/p4info.proto +# proto-message: p4.config.v1.P4Info + +pkg_info { + arch: "v1model" +}