Skip to content

Commit

Permalink
Remove chained update-index when the same element is indexed and both…
Browse files Browse the repository at this point in the history
… are known to be in bounds.

PiperOrigin-RevId: 692293570
  • Loading branch information
allight authored and copybara-github committed Nov 1, 2024
1 parent 9d97c34 commit ba53b52
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
22 changes: 22 additions & 0 deletions xls/passes/array_simplification_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,28 @@ absl::StatusOr<SimplifyResult> SimplifyArrayIndex(
return SimplifyResult::Changed({array_index->array()});
}

// An array-index of an array-update of the same index can be better
// thought of as a mux between the last element of the array (in the case the
// update & index are both out of bounds) and the updated value. In the case
// where the update/index location is in bounds we can just replace with the
// update value.
//
// Only checking single-dimensional array-indexes because its significantly
// simpler and is the common case.
//
if (array_index->array()->Is<ArrayUpdate>()) {
ArrayUpdate* update = array_index->array()->As<ArrayUpdate>();
if (IndicesAreDefinitelyEqual(array_index->indices(), update->indices(),
query_engine) &&
// Check both since if either has the known-in-bounds mark we can go
// ahead.
(IndicesAreDefinitelyInBounds(array_index, query_engine) ||
IndicesAreDefinitelyInBounds(update, query_engine))) {
XLS_RETURN_IF_ERROR(array_index->ReplaceUsesWith(update->update_value()));
return SimplifyResult::Changed({});
}
}

// An array index which indexes into a 1-element array can have its index
// replaced with a literal 0, since the clamping behavior makes all indexing
// equivalent:
Expand Down
19 changes: 19 additions & 0 deletions xls/passes/array_simplification_pass_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1602,5 +1602,24 @@ TEST_F(ArraySimplificationPassTest, MultidimensionalUnitArrayUpdate) {
/*default_value=*/m::Param("array")));
}

TEST_F(ArraySimplificationPassTest, ArrayUpdateIndexInBounds) {
auto p = CreatePackage();
FunctionBuilder fb(TestName(), p.get());
BValue arr = fb.Param("array", p->GetArrayType(10, p->GetBitsType(32)));
BValue idx = fb.Param("upd_idx", p->GetBitsType(32));
// NB This sort of selector requires context-sensitive range analysis to see.
BValue idx_bound = fb.Select(fb.ULt(idx, fb.Literal(UBits(10, 32))), {idx},
fb.Literal(UBits(0, 32)));
BValue val = fb.Param("val", p->GetBitsType(32));
BValue update_arr =
fb.ArrayUpdate(arr, val, {idx_bound}, /*known_in_bounds=*/true);
fb.ArrayIndex(update_arr, {idx_bound}, /*known_in_bounds=*/true);
XLS_ASSERT_OK_AND_ASSIGN(Function * f, fb.Build());
ScopedVerifyEquivalence sve(f);
ScopedRecordIr sri(p.get());
ASSERT_THAT(Run(f), IsOkAndHolds(true));
EXPECT_THAT(f->return_value(), m::Param("val"));
}

} // namespace
} // namespace xls

0 comments on commit ba53b52

Please sign in to comment.