Skip to content
Merged
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
4 changes: 2 additions & 2 deletions xls/dslx/bytecode/builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ absl::Status BuiltinRangeInternal(InterpreterStack& stack) {
XLS_RET_CHECK(end.IsBits());
XLS_ASSIGN_OR_RETURN(InterpValue start_ge_end, start.Ge(end));
if (start_ge_end.IsTrue()) {
return InterpValue::MakeArray({});
return InterpValue::MakeRange({});
}

std::vector<InterpValue> elements;
Expand All @@ -172,7 +172,7 @@ absl::Status BuiltinRangeInternal(InterpreterStack& stack) {
XLS_ASSIGN_OR_RETURN(cur, cur.Add(one));
XLS_ASSIGN_OR_RETURN(done, cur.Ge(end));
}
return InterpValue::MakeArray(elements);
return InterpValue::MakeRange(elements);
},
stack);
}
Expand Down
12 changes: 12 additions & 0 deletions xls/dslx/bytecode/bytecode_interpreter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2002,6 +2002,18 @@ fn main() -> u32[8] {
}
}

TEST_F(BytecodeInterpreterTest, RangeExprEmpty) {
constexpr std::string_view kProgram = R"(
fn main() -> u32[0] {
u32:100..u32:100
})";

XLS_ASSERT_OK_AND_ASSIGN(InterpValue value, Interpret(kProgram, "main"));
XLS_ASSERT_OK_AND_ASSIGN(const std::vector<InterpValue>* elements,
value.GetValues());
EXPECT_EQ(elements->size(), 0);
}

TEST_F(BytecodeInterpreterTest, TypeMaxExprU7) {
constexpr std::string_view kProgram = R"(
fn main() -> u7 {
Expand Down
12 changes: 11 additions & 1 deletion xls/dslx/interp_value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ std::string TagToString(InterpValueTag tag) {
return InterpValue{InterpValueTag::kArray, std::move(elements)};
}

/* static */ absl::StatusOr<InterpValue> InterpValue::MakeRange(
std::vector<InterpValue> elements) {
return InterpValue{InterpValueTag::kArray, std::move(elements),
/*is_range=*/true};
}

/* static */ InterpValue InterpValue::MakeUBits(int64_t bit_count,
int64_t value) {
return InterpValue{InterpValueTag::kUBits,
Expand Down Expand Up @@ -975,7 +981,11 @@ absl::StatusOr<InterpValue> InterpValue::Concat(
for (const InterpValue& o : other.GetValuesOrDie()) {
result.push_back(o);
}
return InterpValue(InterpValueTag::kArray, std::move(result));
// We don't propagate is_range_ from either operand, because the resulting
// concatenated array may or may not represent a contiguous range of
// values anymore.
return InterpValue(InterpValueTag::kArray, std::move(result),
/*is_range=*/false);
}
case InterpValueTag::kUBits:
return InterpValue(
Expand Down
9 changes: 7 additions & 2 deletions xls/dslx/interp_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ class InterpValue {
static InterpValue MakeBool(bool value) {
return MakeUBits(1, value ? 1 : 0);
}
static absl::StatusOr<InterpValue> MakeRange(
std::vector<InterpValue> elements);

static absl::StatusOr<InterpValue> MakeBits(InterpValueTag tag, Bits bits) {
if (tag != InterpValueTag::kUBits && tag != InterpValueTag::kSBits) {
Expand Down Expand Up @@ -541,6 +543,8 @@ class InterpValue {
bool operator<(const InterpValue& rhs) const;
bool operator>=(const InterpValue& rhs) const;

bool is_range() const { return is_range_; }

private:
friend struct InterpValuePickler;

Expand Down Expand Up @@ -576,8 +580,8 @@ class InterpValue {
std::shared_ptr<TokenData>, ChannelReference,
TypeReference, std::shared_ptr<ProcInitializer>>;

InterpValue(InterpValueTag tag, Payload payload)
: tag_(tag), payload_(std::move(payload)) {}
InterpValue(InterpValueTag tag, Payload payload, bool is_range = false)
: tag_(tag), payload_(std::move(payload)), is_range_(is_range) {}

using CompareF = bool (*)(const Bits& lhs, const Bits& rhs);

Expand All @@ -588,6 +592,7 @@ class InterpValue {

InterpValueTag tag_;
Payload payload_;
bool is_range_;
};

template <typename H>
Expand Down
16 changes: 16 additions & 0 deletions xls/dslx/interp_value_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,22 @@ TEST(InterpValueTest, FlattenArrayOfBits) {
EXPECT_THAT(o->GetBitValueUnsigned(), IsOkAndHolds(0xf00ba5));
}

TEST(InterpValueTest, ConcatRange) {
auto a = InterpValue::MakeUBits(/*bit_count=*/4, 1);
auto b = InterpValue::MakeUBits(/*bit_count=*/4, 2);
XLS_ASSERT_OK_AND_ASSIGN(InterpValue range_a, InterpValue::MakeRange({a}));
XLS_ASSERT_OK_AND_ASSIGN(InterpValue array_b, InterpValue::MakeArray({b}));

XLS_ASSERT_OK_AND_ASSIGN(InterpValue concat, range_a.Concat(array_b));
// Concatenating ranges don't produce a range, it produces an array.
EXPECT_FALSE(concat.is_range());
EXPECT_TRUE(concat.IsArray());

XLS_ASSERT_OK_AND_ASSIGN(InterpValue concat2, array_b.Concat(range_a));
EXPECT_FALSE(concat2.is_range());
EXPECT_TRUE(concat2.IsArray());
}

TEST(InterpValueTest, BitwiseNegateAllBitsSet) {
auto v = InterpValue::MakeUBits(/*bit_count=*/3, 0x7);
auto expected = InterpValue::MakeUBits(/*bit_count=*/3, 0);
Expand Down
Loading