Skip to content

Commit 1cd1504

Browse files
allightcopybara-github
authored andcommitted
Ensure Channel-legalization can handle procs with tokens in their state performing selects.
This can cause selects containing tokens to be seen by channel-legalization which previously confused the z3 translator. Fixes: #3738 PiperOrigin-RevId: 861807182
1 parent 2d6aa8b commit 1cd1504

File tree

3 files changed

+55
-20
lines changed

3 files changed

+55
-20
lines changed

xls/passes/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3888,9 +3888,11 @@ cc_test(
38883888
"//xls/ir:channel",
38893889
"//xls/ir:function_builder",
38903890
"//xls/ir:ir_parser",
3891+
"//xls/ir:ir_test_base",
38913892
"//xls/ir:proc_elaboration",
38923893
"//xls/ir:value",
38933894
"//xls/ir:verifier",
3895+
"//xls/solvers:z3_ir_equivalence_testutils",
38943896
"@com_google_absl//absl/container:flat_hash_map",
38953897
"@com_google_absl//absl/status",
38963898
"@com_google_absl//absl/status:status_matchers",

xls/passes/channel_legalization_pass_test.cc

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@
4444
#include "xls/ir/channel.h"
4545
#include "xls/ir/function_builder.h"
4646
#include "xls/ir/ir_parser.h"
47+
#include "xls/ir/ir_test_base.h"
4748
#include "xls/ir/package.h"
4849
#include "xls/ir/proc_elaboration.h"
4950
#include "xls/ir/value.h"
5051
#include "xls/ir/verifier.h"
5152
#include "xls/passes/optimization_pass.h"
5253
#include "xls/passes/pass_base.h"
54+
#include "xls/solvers/z3_ir_equivalence_testutils.h"
5355

5456
namespace xls {
5557
namespace {
@@ -98,8 +100,7 @@ struct TestParam {
98100
};
99101
};
100102

101-
class ChannelLegalizationPassTest
102-
: public TestWithParam<std::tuple<TestParam, ChannelStrictness>> {
103+
class ChannelLegalizationPassIrTest : public IrTestBase {
103104
protected:
104105
absl::StatusOr<bool> Run(Package* package) {
105106
PassResults results;
@@ -111,6 +112,11 @@ class ChannelLegalizationPassTest
111112
}
112113
};
113114

115+
class ChannelLegalizationPassTest
116+
: public testing::WithParamInterface<
117+
std::tuple<TestParam, ChannelStrictness>>,
118+
public ChannelLegalizationPassIrTest {};
119+
114120
TestParam kTestParameters[] = {
115121
TestParam{
116122
.test_name = "SingleProcBackToBackDataSwitchingOps",
@@ -995,6 +1001,29 @@ TEST_P(ChannelLegalizationPassTest, EvaluatesCorrectly) {
9951001
.evaluate(interpreter.get(), std::get<1>(GetParam())));
9961002
}
9971003

1004+
TEST_F(ChannelLegalizationPassIrTest, LegalizeWithTokenSel) {
1005+
auto p = CreatePackage();
1006+
ProcBuilder pb(NewStyleProc{}, TestName(), p.get());
1007+
XLS_ASSERT_OK_AND_ASSIGN(
1008+
auto chan_out,
1009+
pb.AddOutputChannel("out", p->GetBitsType(32), ChannelKind::kStreaming,
1010+
ChannelStrictness::kRuntimeMutuallyExclusive));
1011+
auto st = pb.StateElement("state", UBits(0, 1));
1012+
auto tok = pb.StateElement("tok", Value::Token());
1013+
auto not_st = pb.Not(st);
1014+
auto tok_new_a1 = pb.SendIf(chan_out, tok, st, pb.Literal(UBits(32, 32)));
1015+
auto tok_new_b1 = pb.SendIf(chan_out, tok, not_st, pb.Literal(UBits(12, 32)));
1016+
pb.Next(st, not_st);
1017+
// NB This can come about from fairly normal dslx see:
1018+
// https://github.com/google/xls/issues/3738
1019+
pb.Next(tok, pb.Select(st, tok_new_a1, tok_new_b1));
1020+
XLS_ASSERT_OK_AND_ASSIGN(auto f, pb.Build());
1021+
XLS_ASSERT_OK(p->SetTop(f));
1022+
solvers::z3::ScopedVerifyProcEquivalence svpe(f, /*activation_count=*/5);
1023+
ScopedRecordIr sri(p.get());
1024+
EXPECT_THAT(Run(p.get()), IsOkAndHolds(true));
1025+
}
1026+
9981027
INSTANTIATE_TEST_SUITE_P(
9991028
ChannelLegalizationPassTestInstantiation, ChannelLegalizationPassTest,
10001029
Combine(ValuesIn(kTestParameters),

xls/solvers/z3_ir_translator.cc

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,27 +1427,31 @@ absl::StatusOr<LeafTypeTree<Z3_ast>> IrTranslator::ToLeafTypeTree(Type* type,
14271427

14281428
absl::StatusOr<Z3_ast> IrTranslator::FromLeafTypeTree(
14291429
LeafTypeTreeView<Z3_ast> ast) {
1430-
if (ast.type()->IsBits()) {
1431-
return ast.Get({});
1432-
}
14331430
Type* ty = ast.type();
1434-
if (ty->IsArray()) {
1435-
std::vector<Z3_ast> elements;
1436-
elements.reserve(ty->AsArrayOrDie()->size());
1437-
for (int64_t i = 0; i < ty->AsArrayOrDie()->size(); ++i) {
1438-
XLS_ASSIGN_OR_RETURN(Z3_ast elem, FromLeafTypeTree(ast.AsView({i})));
1439-
elements.push_back(elem);
1431+
switch (ty->kind()) {
1432+
case TypeKind::kToken:
1433+
case TypeKind::kBits:
1434+
// Already a leaf value.
1435+
return ast.Get({});
1436+
case TypeKind::kTuple: {
1437+
std::vector<Z3_ast> elements;
1438+
elements.reserve(ty->AsTupleOrDie()->size());
1439+
for (int64_t i = 0; i < ty->AsTupleOrDie()->size(); ++i) {
1440+
XLS_ASSIGN_OR_RETURN(Z3_ast elem, FromLeafTypeTree(ast.AsView({i})));
1441+
elements.push_back(elem);
1442+
}
1443+
return CreateTuple(ty->AsTupleOrDie(), elements);
1444+
}
1445+
case TypeKind::kArray: {
1446+
std::vector<Z3_ast> elements;
1447+
elements.reserve(ty->AsArrayOrDie()->size());
1448+
for (int64_t i = 0; i < ty->AsArrayOrDie()->size(); ++i) {
1449+
XLS_ASSIGN_OR_RETURN(Z3_ast elem, FromLeafTypeTree(ast.AsView({i})));
1450+
elements.push_back(elem);
1451+
}
1452+
return CreateArray(ty->AsArrayOrDie(), elements);
14401453
}
1441-
return CreateArray(ty->AsArrayOrDie(), elements);
1442-
}
1443-
XLS_RET_CHECK(ty->IsTuple());
1444-
std::vector<Z3_ast> elements;
1445-
elements.reserve(ty->AsTupleOrDie()->size());
1446-
for (int64_t i = 0; i < ty->AsTupleOrDie()->size(); ++i) {
1447-
XLS_ASSIGN_OR_RETURN(Z3_ast elem, FromLeafTypeTree(ast.AsView({i})));
1448-
elements.push_back(elem);
14491454
}
1450-
return CreateTuple(ty->AsTupleOrDie(), elements);
14511455
}
14521456

14531457
absl::Status IrTranslator::HandleAndReduce(BitwiseReductionOp* and_reduce) {

0 commit comments

Comments
 (0)