Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions xls/dslx/bytecode/builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -518,24 +518,6 @@ absl::Status RunBuiltinCtz(const Bytecode& bytecode, InterpreterStack& stack) {
return absl::OkStatus();
}

absl::Status RunBuiltinEnumerate(const Bytecode& bytecode,
InterpreterStack& stack) {
XLS_RET_CHECK(!stack.empty());
XLS_ASSIGN_OR_RETURN(InterpValue input, stack.Pop());
XLS_ASSIGN_OR_RETURN(const std::vector<InterpValue>* values,
input.GetValues());

std::vector<InterpValue> elements;
elements.reserve(values->size());
for (int32_t i = 0; i < values->size(); i++) {
elements.push_back(
InterpValue::MakeTuple({InterpValue::MakeU32(i), values->at(i)}));
}
XLS_ASSIGN_OR_RETURN(InterpValue result, InterpValue::MakeArray(elements));
stack.Push(result);
return absl::OkStatus();
}

absl::Status RunBuiltinOrReduce(const Bytecode& bytecode,
InterpreterStack& stack) {
VLOG(3) << "Executing builtin OrReduce.";
Expand Down
2 changes: 0 additions & 2 deletions xls/dslx/bytecode/builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ absl::Status RunBuiltinCeilLog2(const Bytecode& bytecode,
absl::Status RunBuiltinClz(const Bytecode& bytecode, InterpreterStack& stack);
absl::Status RunBuiltinCover(const Bytecode& bytecode, InterpreterStack& stack);
absl::Status RunBuiltinCtz(const Bytecode& bytecode, InterpreterStack& stack);
absl::Status RunBuiltinEnumerate(const Bytecode& bytecode,
InterpreterStack& stack);
absl::Status RunBuiltinOrReduce(const Bytecode& bytecode,
InterpreterStack& stack);
absl::Status RunBuiltinRange(const Bytecode& bytecode, InterpreterStack& stack);
Expand Down
2 changes: 0 additions & 2 deletions xls/dslx/bytecode/bytecode_interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1673,8 +1673,6 @@ absl::Status BytecodeInterpreter::RunBuiltinFn(const Bytecode& bytecode,
return RunBuiltinCover(bytecode, stack_);
case Builtin::kCtz:
return RunBuiltinCtz(bytecode, stack_);
case Builtin::kEnumerate:
return RunBuiltinEnumerate(bytecode, stack_);
case Builtin::kFail: {
XLS_ASSIGN_OR_RETURN(InterpValue value, Pop());
std::string message{value.ToString()};
Expand Down
23 changes: 0 additions & 23 deletions xls/dslx/bytecode/bytecode_interpreter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1940,29 +1940,6 @@ fn main(x: s10, y: s10) -> s10 {
EXPECT_THAT(bits.ToInt64(), IsOkAndHolds(-507));
}

TEST_F(BytecodeInterpreterTest, BuiltinEnumerate) {
constexpr std::string_view kProgram = R"(
fn main() -> (u32, u8)[4] {
let x = u8[4]:[5, 6, 7, 8];
enumerate(x)
})";

XLS_ASSERT_OK_AND_ASSIGN(InterpValue actual, Interpret(kProgram, "main"));
XLS_ASSERT_OK_AND_ASSIGN(
InterpValue expected,
InterpValue::MakeArray({
InterpValue::MakeTuple(
{InterpValue::MakeUBits(32, 0), InterpValue::MakeUBits(8, 5)}),
InterpValue::MakeTuple(
{InterpValue::MakeUBits(32, 1), InterpValue::MakeUBits(8, 6)}),
InterpValue::MakeTuple(
{InterpValue::MakeUBits(32, 2), InterpValue::MakeUBits(8, 7)}),
InterpValue::MakeTuple(
{InterpValue::MakeUBits(32, 3), InterpValue::MakeUBits(8, 8)}),
}));
EXPECT_TRUE(expected.Eq(actual));
}

TEST_F(BytecodeInterpreterTest, BuiltinUMulp) {
constexpr std::string_view kProgram = R"(
fn main(x: u10, y: u10) -> u10 {
Expand Down
1 change: 0 additions & 1 deletion xls/dslx/dslx_builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ namespace xls::dslx {
X("decode", kDecode) \
X("element_count", kElementCount) \
X("encode", kEncode) \
X("enumerate", kEnumerate) \
X("fail!", kFail) \
X("gate!", kGate) \
X("map", kMap) \
Expand Down
2 changes: 0 additions & 2 deletions xls/dslx/frontend/builtin_stubs.x
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ fn decode<T: type, N: u32>(x: uN[N]) -> T;

fn element_count<T: type>() -> u32;

fn enumerate<T: type, N: u32>(x: T[N]) -> (u32, T)[N];

fn fail!<N: u32, T: type> (label: u8[N], fallback_value: T) -> T;

fn gate!<T: type>(x: u1, y: T) -> T;
Expand Down
1 change: 0 additions & 1 deletion xls/dslx/frontend/builtins_metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ const absl::flat_hash_map<std::string, BuiltinsData>& GetParametricBuiltins() {
{"signex", {}},
{"array_slice", {}},
{"update", {}},
{"enumerate", {}},
{"widening_cast", {}},
{"checked_cast", {}},

Expand Down
23 changes: 10 additions & 13 deletions xls/dslx/ir_convert/testdata/ir_converter_test_ArrayEnumerate.ir
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,20 @@ package test_module
file_number 0 "xls/dslx/stdlib/std.x"
file_number 1 "test_module.x"

fn ____std__enumerate__4_u8_counted_for_0_body(i: bits[32] id=7, result: (bits[32], bits[8])[4] id=10, x: bits[8][4] id=11) -> (bits[32], bits[8])[4] {
literal.8: bits[32] = literal(value=0, id=8)
add.9: bits[32] = add(i, literal.8, id=9)
array_index.12: bits[8] = array_index(x, indices=[add.9], id=12)
tuple.13: (bits[32], bits[8]) = tuple(add.9, array_index.12, id=13)
ret array_update.14: (bits[32], bits[8])[4] = array_update(result, tuple.13, indices=[add.9], id=14)
fn ____std__enumerate__4_u8_counted_for_0_body(i: bits[32] id=4, result: (bits[32], bits[8])[4] id=7, x: bits[8][4] id=8) -> (bits[32], bits[8])[4] {
literal.5: bits[32] = literal(value=0, id=5)
add.6: bits[32] = add(i, literal.5, id=6)
array_index.9: bits[8] = array_index(x, indices=[add.6], id=9)
tuple.10: (bits[32], bits[8]) = tuple(add.6, array_index.9, id=10)
ret array_update.11: (bits[32], bits[8])[4] = array_update(result, tuple.10, indices=[add.6], id=11)
}

fn __std__enumerate__4_u8(x: bits[8][4] id=1) -> (bits[32], bits[8])[4] {
literal.3: bits[32] = literal(value=0, id=3)
literal.4: bits[8] = literal(value=0, id=4)
tuple.5: (bits[32], bits[8]) = tuple(literal.3, literal.4, id=5)
array.6: (bits[32], bits[8])[4] = array(tuple.5, tuple.5, tuple.5, tuple.5, id=6)
literal.3: (bits[32], bits[8])[4] = literal(value=[(0, 0), (0, 0), (0, 0), (0, 0)], id=3)
N: bits[32] = literal(value=4, id=2)
ret counted_for.15: (bits[32], bits[8])[4] = counted_for(array.6, trip_count=4, stride=1, body=____std__enumerate__4_u8_counted_for_0_body, invariant_args=[x], id=15)
ret counted_for.12: (bits[32], bits[8])[4] = counted_for(literal.3, trip_count=4, stride=1, body=____std__enumerate__4_u8_counted_for_0_body, invariant_args=[x], id=12)
}

top fn __test_module__main(array: bits[8][4] id=16) -> (bits[32], bits[8])[4] {
ret invoke.17: (bits[32], bits[8])[4] = invoke(array, to_apply=__std__enumerate__4_u8, id=17)
top fn __test_module__main(array: bits[8][4] id=13) -> (bits[32], bits[8])[4] {
ret invoke.14: (bits[32], bits[8])[4] = invoke(array, to_apply=__std__enumerate__4_u8, id=14)
}
44 changes: 43 additions & 1 deletion xls/dslx/stdlib/std.x
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
pub fn enumerate<T: type, N: u32>(x: T[N]) -> (u32, T)[N] {
for (i, result) in 0..N {
update(result, i, (i, x[i]))
}([(u32:0, zero!<T>()), ...])
}(zero!<(u32, T)[N]>())
}

#[test]
Expand All @@ -32,6 +32,13 @@ fn emumerate_test() {
assert_eq(enumerated[3], (3, 8));
}

#[test]
fn emumerate_empty_array_test() {
let empty_array: u32[0] = [];
let enumerated_empty = enumerate(empty_array);
assert_eq(enumerated_empty, []);
}

#[test]
fn enumerate_type_test() {
type RamData = uN[8];
Expand All @@ -51,6 +58,41 @@ fn enumerate_tuple_test() {
assert_eq(enumerated[1], (1, (false, 2)));
}

type TestIdx = uN[2];
type TestValue = uN[32];

struct TestData { idx: TestIdx, value: TestValue }

const TEST_DATA = TestData[20]:[
TestData { idx: TestIdx:0, value: TestValue:0xca32_9f4a },
TestData { idx: TestIdx:1, value: TestValue:0x0fb3_fa42 },
TestData { idx: TestIdx:2, value: TestValue:0xe7ee_da41 },
TestData { idx: TestIdx:3, value: TestValue:0xef51_f98c },
TestData { idx: TestIdx:0, value: TestValue:0x97a3_a2d2 },
TestData { idx: TestIdx:0, value: TestValue:0xea06_e94b },
TestData { idx: TestIdx:1, value: TestValue:0x5fac_17ce },
TestData { idx: TestIdx:3, value: TestValue:0xf9d8_9938 },
TestData { idx: TestIdx:2, value: TestValue:0xc262_2d2e },
TestData { idx: TestIdx:2, value: TestValue:0xb4dd_424e },
TestData { idx: TestIdx:1, value: TestValue:0x01f9_b9e4 },
TestData { idx: TestIdx:1, value: TestValue:0x3020_6eec },
TestData { idx: TestIdx:3, value: TestValue:0x3124_87b5 },
TestData { idx: TestIdx:0, value: TestValue:0x0a49_f5e3 },
TestData { idx: TestIdx:2, value: TestValue:0xde3b_5d0f },
TestData { idx: TestIdx:3, value: TestValue:0x5948_c1b3 },
TestData { idx: TestIdx:0, value: TestValue:0xa26d_851f },
TestData { idx: TestIdx:3, value: TestValue:0x3fa9_59c0 },
TestData { idx: TestIdx:1, value: TestValue:0x4efd_dd09 },
TestData { idx: TestIdx:1, value: TestValue:0x6d75_058a },
];

#[test]
fn enumerate_struct_test() {
let enumerated = enumerate(TEST_DATA);
assert_eq(enumerated[0], (0, TEST_DATA[0]));
assert_eq(enumerated[19], (19, TEST_DATA[19]));
}

pub fn sizeof<S: bool, N: u32>(x: xN[S][N]) -> u32 { N }

#[test]
Expand Down
6 changes: 0 additions & 6 deletions xls/dslx/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,6 @@ dslx_lang_test(

dslx_lang_test(name = "for_over_range")

dslx_lang_test(
name = "enumerate",
compare = "interpreter",
convert_to_ir = True,
)

dslx_lang_test(
name = "character_conversion",
# TODO: https://github.com/google/xls/issues/1526 - fails opportunistic_postcondition in autofmt
Expand Down
25 changes: 0 additions & 25 deletions xls/dslx/tests/enumerate.x

This file was deleted.

9 changes: 0 additions & 9 deletions xls/dslx/tests/errors/error_modules_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1097,15 +1097,6 @@ def test_user_defined_parametric_type(self):
stderr,
)

def test_match_empty_range(self):
stderr = self._run(
'xls/dslx/tests/errors/match_empty_range.x',
)
self.assertIn(
'`u32:0..u32:0` from `u32:0` to `u32:0` is an empty range',
stderr,
)

def test_parametric_test_fn(self):
stderr = self._run(
'xls/dslx/tests/errors/parametric_test_fn.x',
Expand Down
21 changes: 0 additions & 21 deletions xls/dslx/tests/errors/match_empty_range.x

This file was deleted.

22 changes: 10 additions & 12 deletions xls/dslx/type_system/deduce_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -239,18 +239,6 @@ absl::Status ValidateArrayIndex(const Index& node, const Type& array_type,
// producing a `Type`.
const auto& casted_array_type = dynamic_cast<const ArrayType&>(array_type);

// Reject indexing into zero-sized arrays regardless of whether the index is
// constexpr, since out-of-bounds semantics (return last element) are
// undefined for empty arrays.

XLS_ASSIGN_OR_RETURN(int64_t concrete_size,
casted_array_type.size().GetAsInt64());
if (concrete_size == 0) {
return TypeInferenceErrorStatus(node.span(), &array_type,
"Zero-sized arrays cannot be indexed",
file_table);
}

if (!ti.IsKnownConstExpr(rhs)) {
return absl::OkStatus();
}
Expand All @@ -270,6 +258,16 @@ absl::Status ValidateArrayIndex(const Index& node, const Type& array_type,
constexpr_index),
file_table);
}

// Reject indexing into zero-sized arrays, since out-of-bounds semantics
// (return last element) are undefined for empty arrays.
XLS_ASSIGN_OR_RETURN(int64_t concrete_size,
casted_array_type.size().GetAsInt64());
if (concrete_size == 0) {
return TypeInferenceErrorStatus(node.span(), &array_type,
"Zero-sized arrays cannot be indexed",
file_table);
}
return absl::OkStatus();
}

Expand Down
7 changes: 0 additions & 7 deletions xls/dslx/type_system/typecheck_module_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,6 @@ fn main() -> u2 { p<u32:1>(u2:0) }
XLS_EXPECT_OK(Typecheck(text));
}

TEST_F(TypecheckV2Test, IndexZeroSizedArray) {
std::string_view text = R"(fn f(a: u8[0], b: u3) -> u8 { a[b] })";
EXPECT_THAT(Typecheck(text),
StatusIs(absl::StatusCode::kInvalidArgument,
HasSubstr("Zero-sized arrays cannot be indexed")));
}

TEST_F(TypecheckV2Test, ZeroMacroFunctionRefIsNotValue) {
// Bare parametric macro reference should have function type `() -> E` and
// not be directly usable as a value of type `E`.
Expand Down
10 changes: 0 additions & 10 deletions xls/dslx/type_system_v2/typecheck_module_v2_array_tuple_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1726,16 +1726,6 @@ const X = foo()..(A * 2);
TypecheckSucceeds(HasNodeWithType("X", "sN[16][8]")));
}

TEST(TypecheckV2Test, RangeExprEmptyRange) {
XLS_ASSERT_OK_AND_ASSIGN(TypecheckResult result, TypecheckV2(R"(
const A = s8:4;
const X = A..s8:4;
)"));
ASSERT_THAT(result.tm.warnings.warnings().size(), 1);
EXPECT_EQ(result.tm.warnings.warnings()[0].message,
"`A..s8:4` from `s8:4` to `s8:4` is an empty range");
}

TEST(TypecheckV2Test, RangeExprSignednessMismatch) {
EXPECT_THAT(R"(const X = u32:1..s32:2;)",
TypecheckFails(HasSignednessMismatch("s32", "u32")));
Expand Down
15 changes: 0 additions & 15 deletions xls/dslx/type_system_v2/typecheck_module_v2_builtin_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -659,21 +659,6 @@ const_assert!(element_count<imported::T>() == 10);
XLS_EXPECT_OK(TypecheckV2(kProgram, "main", &import_data));
}

TEST(TypecheckV2BuiltinTest, Enumerate) {
EXPECT_THAT(R"(const Y = enumerate<u16, u32:3>([u16:1, u16:2, u16:3]);)",
TypecheckSucceeds(HasNodeWithType("Y", "(uN[32], uN[16])[3]")));
}

TEST(TypecheckV2BuiltinTest, EnumerateImplicitSize) {
EXPECT_THAT(R"(const Y = enumerate<u16>([u16:1, u16:2, u16:3]);)",
TypecheckSucceeds(HasNodeWithType("Y", "(uN[32], uN[16])[3]")));
}

TEST(TypecheckV2BuiltinTest, EnumerateImplicitType) {
EXPECT_THAT(R"(const Y = enumerate([u16:1, u16:2, u16:3]);)",
TypecheckSucceeds(HasNodeWithType("Y", "(uN[32], uN[16])[3]")));
}

TEST(TypecheckV2BuiltinTest, Fail) {
EXPECT_THAT(
R"(
Expand Down
5 changes: 3 additions & 2 deletions xls/dslx/type_system_v2/typecheck_module_v2_lambda_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,13 @@ const_assert!(ARR[1] == u16:2);
TEST(TypecheckV2Test, NestedLambdas) {
EXPECT_THAT(
R"(
import std;
fn main() -> u32[4][5] {
let z = zero!<u32[4][5]>();
map(enumerate(z), | tup | {
map(std::enumerate(z), | tup | {
let i = tup.0;
let arr = tup.1;
map(enumerate(arr), | tup2 | {
map(std::enumerate(arr), | tup2 | {
let j = tup2.0;
i + j
})
Expand Down
6 changes: 2 additions & 4 deletions xls/dslx/type_system_v2/validate_concrete_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -406,11 +406,9 @@ class TypeValidator : public AstNodeVisitorWithDefault {
const_cast<ImportData*>(&import_data_), const_cast<TypeInfo*>(&ti_),
&warning_collector_, env, range->end()));

// Allow empty range
if (!range->inclusive_end() && start.Eq(end)) {
warning_collector_.Add(
range->span(), WarningKind::kEmptyRangeLiteral,
absl::StrFormat("`%s` from `%s` to `%s` is an empty range",
range->ToString(), start.ToString(), end.ToString()));
return absl::OkStatus();
}
// In TIv1 we only warn for ranges in match arm that is empty.
if (range->has_pattern_semantics()) {
Expand Down