diff --git a/xls/passes/select_simplification_pass.cc b/xls/passes/select_simplification_pass.cc
index fccc4f9971..d49c8b2a61 100644
--- a/xls/passes/select_simplification_pass.cc
+++ b/xls/passes/select_simplification_pass.cc
@@ -1114,6 +1114,15 @@ absl::StatusOr MaybeReorderSelect(Node* node,
return false;
}
+ // Side effecting operations don't have values which depend on their inputs so
+ // we can't replace the select with one on the selectors arguments.
+ // NB Only predicated state reads would get caught by this and not be caught
+ // by the 'unknown_operands.size() != 1' check below. Those could confuse this
+ // however and its better to be explicit.
+ if (OpIsSideEffecting(selector->op()) && selector->op() != Op::kGate) {
+ return false;
+ }
+
// Run through all of the selector's operands, recording the Values of any
// that are known constant; this simplification applies if all but one are
// known.
diff --git a/xls/passes/select_simplification_pass_test.cc b/xls/passes/select_simplification_pass_test.cc
index 6d4a35857c..e99ef515b1 100644
--- a/xls/passes/select_simplification_pass_test.cc
+++ b/xls/passes/select_simplification_pass_test.cc
@@ -70,7 +70,7 @@ class SelectSimplificationPassTest
: public IrTestBase,
public testing::WithParamInterface {
protected:
- absl::StatusOr Run(Function* f) {
+ absl::StatusOr Run(FunctionBase* f) {
PassResults results;
OptimizationContext context;
if (GetParam() == AnalysisType::kTernary) {
@@ -1830,6 +1830,29 @@ TEST_P(SelectSimplificationPassTest,
m::Param("ugt_result")));
}
+TEST_P(SelectSimplificationPassTest, PredicatedStateReadFeedSelector) {
+ auto p = CreatePackage();
+ TokenlessProcBuilder pb(NewStyleProc{}, TestName(), "tkn", p.get());
+ XLS_ASSERT_OK_AND_ASSIGN(StateElement * state_element1,
+ pb.UnreadStateElement("state1", Value(UBits(0, 1))));
+ XLS_ASSERT_OK_AND_ASSIGN(StateElement * state_element2,
+ pb.UnreadStateElement("state2", Value(UBits(0, 1))));
+ XLS_ASSERT_OK_AND_ASSIGN(auto in1,
+ pb.AddInputChannel("in1", p->GetBitsType(32)));
+ XLS_ASSERT_OK_AND_ASSIGN(auto in2,
+ pb.AddInputChannel("in2", p->GetBitsType(32)));
+ BValue sr1 = pb.StateRead(state_element1);
+ BValue sr2 = pb.StateRead(state_element2, sr1);
+ BValue update = pb.BitSlice(
+ pb.Select(sr2, {pb.ReceiveIf(in1, sr1), pb.ReceiveIf(in2, sr1)}), 0, 1);
+ pb.Next(state_element1, sr1);
+ pb.Next(state_element2, update, /*pred=*/sr1);
+ pb.Next(state_element2, sr1, /*pred=*/pb.Not(sr1));
+ XLS_ASSERT_OK_AND_ASSIGN(Proc * proc, pb.Build());
+
+ EXPECT_THAT(Run(proc), IsOkAndHolds(false));
+}
+
INSTANTIATE_TEST_SUITE_P(SelectSimplificationPassTest,
SelectSimplificationPassTest,
testing::Values(AnalysisType::kTernary,